<commit_before>#ifndef SCHEDULER_CORO_OSTHREAD
# include "Coro.c"
#endif
<commit_msg>Include sdk/config.h before testing configuration macros.<commit_after>#include <sdk/config.h>

#ifndef SCHEDULER_CORO_OSTHREAD
# include "Coro.c"
#endif
<|endoftext|>


<commit_before>#define _IRR_STATIC_LIB_
#include <irrlicht.h>

#include "../../ext/Draw/CDraw3DLine.h"
#include "../source/Irrlicht/COpenGLExtensionHandler.h"

using namespace irr;
using namespace core;

int main()
{
    irr::SIrrlichtCreationParameters params;
    params.Bits = 24;
    params.ZBufferBits = 24;
    params.DriverType = video::EDT_OPENGL;
    params.WindowSize = core::dimension2d<uint32_t>(1280, 720);
    params.Fullscreen = false;
    params.Vsync = true;
    params.Doublebuffer = true;
    params.Stencilbuffer = false;
    params.AuxGLContexts = 16;
    IrrlichtDevice* device = createDeviceEx(params);

    if (device == 0)
        return 1;

    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    auto draw3DLine = ext::draw::CDraw3DLine::create(driver);

    auto camera = smgr->addCameraSceneNodeFPS(0,100.0f,0.001f);

    camera->setPosition(core::vector3df(-4,0,0));
    camera->setTarget(core::vector3df(0,0,0));
    camera->setNearValue(0.01f);
    camera->setFarValue(10.0f);

    smgr->setActiveCamera(camera);

    uint64_t lastFPSTime = 0;

    while(device->run())
    if (device->isWindowActive())
    {
        driver->beginScene(true, false, video::SColor(255,255,255,255));

        draw3DLine->draw(
            0.f, 0.f, 0.f,   // start
            0.f, 100.f, 0.f, // end
            255, 0, 0, 255   // color
        );

        driver->endScene();

        // display frames per second in window title
        uint64_t time = device->getTimer()->getRealTime();
        if (time-lastFPSTime > 1000)
        {
            std::wostringstream str(L"Draw3DLine Ext - Irrlicht Engine [");
            str.seekp(0,std::ios_base::end);
            str << driver->getName() << "] FPS:" << driver->getFPS();

            device->setWindowCaption(str.str());
            lastFPSTime = time;
        }
    }

    //create a screenshot
    video::IImage* screenshot = driver->createImage(video::ECF_A8R8G8B8,params.WindowSize);
    glReadPixels(0,0, params.WindowSize.Width,params.WindowSize.Height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, screenshot->getData());
    {
        // images are horizontally flipped, so we have to fix that here.
        uint8_t* pixels = (uint8_t*)screenshot->getData();

        const int32_t pitch=screenshot->getPitch();
        uint8_t* p2 = pixels + (params.WindowSize.Height - 1) * pitch;
        uint8_t* tmpBuffer = new uint8_t[pitch];
        for (uint32_t i=0; i < params.WindowSize.Height; i += 2)
        {
            memcpy(tmpBuffer, pixels, pitch);
            memcpy(pixels, p2, pitch);
            memcpy(p2, tmpBuffer, pitch);
            pixels += pitch;
            p2 -= pitch;
        }
        delete [] tmpBuffer;
    }
    driver->writeImageToFile(screenshot,"./screenshot.png");
    screenshot->drop();

    device->drop();

    return 0;
}
<commit_msg>Add draw call, move camera backwards<commit_after>#define _IRR_STATIC_LIB_
#include <irrlicht.h>

#include "../../ext/Draw/CDraw3DLine.h"
#include "../source/Irrlicht/COpenGLExtensionHandler.h"

using namespace irr;
using namespace core;

int main()
{
    irr::SIrrlichtCreationParameters params;
    params.Bits = 24;
    params.ZBufferBits = 24;
    params.DriverType = video::EDT_OPENGL;
    params.WindowSize = core::dimension2d<uint32_t>(1280, 720);
    params.Fullscreen = false;
    params.Vsync = true;
    params.Doublebuffer = true;
    params.Stencilbuffer = false;
    params.AuxGLContexts = 16;
    IrrlichtDevice* device = createDeviceEx(params);

    if (device == 0)
        return 1;

    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    auto draw3DLine = ext::draw::CDraw3DLine::create(driver);

    auto camera = smgr->addCameraSceneNodeFPS(0,100.0f,0.001f);

    camera->setPosition(core::vector3df(0,0,-10));
    camera->setTarget(core::vector3df(0,0,0));
    camera->setNearValue(0.01f);
    camera->setFarValue(10.0f);

    smgr->setActiveCamera(camera);

    uint64_t lastFPSTime = 0;

    while(device->run())
    if (device->isWindowActive())
    {
        driver->beginScene(true, false, video::SColor(255,255,255,255));

        smgr->drawAll();

        draw3DLine->draw(
            0.f, 0.f, 0.f,   // start
            0.f, 100.f, 0.f, // end
            1.f, 0, 0, 1.f   // color
        );

        driver->endScene();

        // display frames per second in window title
        uint64_t time = device->getTimer()->getRealTime();
        if (time-lastFPSTime > 1000)
        {
            std::wostringstream str(L"Draw3DLine Ext - Irrlicht Engine [");
            str.seekp(0,std::ios_base::end);
            str << driver->getName() << "] FPS:" << driver->getFPS();

            device->setWindowCaption(str.str());
            lastFPSTime = time;
        }
    }

    //create a screenshot
    video::IImage* screenshot = driver->createImage(video::ECF_A8R8G8B8,params.WindowSize);
    glReadPixels(0,0, params.WindowSize.Width,params.WindowSize.Height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, screenshot->getData());
    {
        // images are horizontally flipped, so we have to fix that here.
        uint8_t* pixels = (uint8_t*)screenshot->getData();

        const int32_t pitch=screenshot->getPitch();
        uint8_t* p2 = pixels + (params.WindowSize.Height - 1) * pitch;
        uint8_t* tmpBuffer = new uint8_t[pitch];
        for (uint32_t i=0; i < params.WindowSize.Height; i += 2)
        {
            memcpy(tmpBuffer, pixels, pitch);
            memcpy(pixels, p2, pitch);
            memcpy(p2, tmpBuffer, pitch);
            pixels += pitch;
            p2 -= pitch;
        }
        delete [] tmpBuffer;
    }
    driver->writeImageToFile(screenshot,"./screenshot.png");
    screenshot->drop();

    device->drop();

    return 0;
}
<|endoftext|>


<commit_before>#define _IRR_STATIC_LIB_
#include <irrlicht.h>

#include "../../ext/Draw/CDraw3DLine.h"
#include "../source/Irrlicht/COpenGLExtensionHandler.h"

using namespace irr;
using namespace core;

int main()
{
    irr::SIrrlichtCreationParameters params;
    params.Bits = 24;
    params.ZBufferBits = 24;
    params.DriverType = video::EDT_OPENGL;
    params.WindowSize = core::dimension2d<uint32_t>(1280, 720);
    params.Fullscreen = false;
    params.Vsync = true;
    params.Doublebuffer = true;
    params.Stencilbuffer = false;
    params.AuxGLContexts = 16;
    IrrlichtDevice* device = createDeviceEx(params);

    if (device == 0)
        return 1;

    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    auto draw3DLine = ext::draw::CDraw3DLine::create(driver);

    auto camera = smgr->addCameraSceneNodeFPS(0,100.0f,0.001f);

    camera->setPosition(core::vector3df(0,0,-10));
    camera->setTarget(core::vector3df(0,0,0));
    camera->setNearValue(0.01f);
    camera->setFarValue(10.0f);

    smgr->setActiveCamera(camera);

    uint64_t lastFPSTime = 0;

    while(device->run())
    if (device->isWindowActive())
    {
        driver->beginScene(true, false, video::SColor(255,255,255,255));

        smgr->drawAll();

        draw3DLine->draw(
            0.f, 0.f, 0.f,   // start
            0.f, 100.f, 0.f, // end
            1.f, 0, 0, 1.f   // color
        );

        driver->endScene();

        // display frames per second in window title
        uint64_t time = device->getTimer()->getRealTime();
        if (time-lastFPSTime > 1000)
        {
            std::wostringstream str(L"Draw3DLine Ext - Irrlicht Engine [");
            str.seekp(0,std::ios_base::end);
            str << driver->getName() << "] FPS:" << driver->getFPS();

            device->setWindowCaption(str.str());
            lastFPSTime = time;
        }
    }

    //create a screenshot
    video::IImage* screenshot = driver->createImage(video::ECF_A8R8G8B8,params.WindowSize);
    glReadPixels(0,0, params.WindowSize.Width,params.WindowSize.Height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, screenshot->getData());
    {
        // images are horizontally flipped, so we have to fix that here.
        uint8_t* pixels = (uint8_t*)screenshot->getData();

        const int32_t pitch=screenshot->getPitch();
        uint8_t* p2 = pixels + (params.WindowSize.Height - 1) * pitch;
        uint8_t* tmpBuffer = new uint8_t[pitch];
        for (uint32_t i=0; i < params.WindowSize.Height; i += 2)
        {
            memcpy(tmpBuffer, pixels, pitch);
            memcpy(pixels, p2, pitch);
            memcpy(p2, tmpBuffer, pitch);
            pixels += pitch;
            p2 -= pitch;
        }
        delete [] tmpBuffer;
    }
    driver->writeImageToFile(screenshot,"./screenshot.png");
    screenshot->drop();

    device->drop();

    return 0;
}
<commit_msg>Fix drawing bug<commit_after>#define _IRR_STATIC_LIB_
#include <irrlicht.h>

#include "../../ext/Draw/CDraw3DLine.h"
#include "../source/Irrlicht/COpenGLExtensionHandler.h"

using namespace irr;
using namespace core;

int main()
{
    irr::SIrrlichtCreationParameters params;
    params.Bits = 24;
    params.ZBufferBits = 24;
    params.DriverType = video::EDT_OPENGL;
    params.WindowSize = core::dimension2d<uint32_t>(1280, 720);
    params.Fullscreen = false;
    params.Vsync = true;
    params.Doublebuffer = true;
    params.Stencilbuffer = false;
    params.AuxGLContexts = 16;
    IrrlichtDevice* device = createDeviceEx(params);

    if (device == 0)
        return 1;

    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
    auto draw3DLine = ext::draw::CDraw3DLine::create(driver);

    auto camera = smgr->addCameraSceneNodeFPS(0,100.0f,0.001f);

    camera->setPosition(core::vector3df(0,0,-10));
    camera->setTarget(core::vector3df(0,0,0));
    camera->setNearValue(0.01f);
    camera->setFarValue(100.0f);

    smgr->setActiveCamera(camera);

    uint64_t lastFPSTime = 0;

    while(device->run())
    if (device->isWindowActive())
    {
        driver->beginScene(true, true, video::SColor(255,255,255,255));

        smgr->drawAll();

        draw3DLine->draw(
            0.f, 0.f, 0.f,   // start
            0.f, 100.f, 0.f, // end
            1.f, 0, 0, 1.f   // color
        );

        driver->endScene();

        // display frames per second in window title
        uint64_t time = device->getTimer()->getRealTime();
        if (time-lastFPSTime > 1000)
        {
            std::wostringstream str(L"Draw3DLine Ext - Irrlicht Engine [");
            str.seekp(0,std::ios_base::end);
            str << driver->getName() << "] FPS:" << driver->getFPS();

            device->setWindowCaption(str.str());
            lastFPSTime = time;
        }
    }

    draw3DLine->drop();

    //create a screenshot
    video::IImage* screenshot = driver->createImage(video::ECF_A8R8G8B8,params.WindowSize);
    glReadPixels(0,0, params.WindowSize.Width,params.WindowSize.Height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, screenshot->getData());
    {
        // images are horizontally flipped, so we have to fix that here.
        uint8_t* pixels = (uint8_t*)screenshot->getData();

        const int32_t pitch=screenshot->getPitch();
        uint8_t* p2 = pixels + (params.WindowSize.Height - 1) * pitch;
        uint8_t* tmpBuffer = new uint8_t[pitch];
        for (uint32_t i=0; i < params.WindowSize.Height; i += 2)
        {
            memcpy(tmpBuffer, pixels, pitch);
            memcpy(pixels, p2, pitch);
            memcpy(p2, tmpBuffer, pitch);
            pixels += pitch;
            p2 -= pitch;
        }
        delete [] tmpBuffer;
    }
    driver->writeImageToFile(screenshot,"./screenshot.png");
    screenshot->drop();

    device->drop();

    return 0;
}
<|endoftext|>


<commit_before>/*
 * squares inside other squares
 * at the start left buttom must be pushed
 */

//#include <stdlib>
#include <GL/glut.h>

// every program must call glutDisplayFunc even if it is empty
void display() {}

void drawsquare(int x, int y)
{
  int n, i;
  float m, ax, bx, by, cx, cy, dx, dy, x1, y1, x2, y2, x3, x4, y4, a, b;

  a = x;
  b = 500 - y; // co-ordinate of mouse is upper left corner

  n = 25; // number of squares
  m = 0.9; // parameter of line

  ax = a; ay = b;
  bx = 150.0 + a; by = b;
  cx = 150.0 + a; cy = 150.0 + b;
  dx = a; dy = 150.0 + b;

  glClear(GL_COLOR_BUFFER_BIT);

}
<commit_msg>handout completely coppied down<commit_after>/*
 * squares inside other squares
 * at the start left buttom must be pushed
 */

//#include <stdlib>
#include <GL/glut.h>

// every program must call glutDisplayFunc even if it is empty
void display() {}

void drawsquare(int x, int y)
{
  int n, i;
  float m, ax, ay, bx, by, cx, cy, dx, dy, x1, y1, x2, y2, x3, y3, x4, y4, a, b;

  a = x;
  b = 500 - y; // co-ordinate of mouse is upper left corner

  n = 25; // number of squares
  m = 0.9; // parameter of line

  ax = a; ay = b;
  bx = 150.0 + a; by = b;
  cx = 150.0 + a; cy = 150.0 + b;
  dx = a; dy = 150.0 + b;
  //
  glClear(GL_COLOR_BUFFER_BIT);
  //
  for (i = 1; i <=n; ++i)
  {
    glBegin(GL_LINE_LOOP);
      glVertex2f(ax, ay);
      glVertex2f(bx, by);
      glVertex2f(cx, cy);
      glVertex2f(dx, dy);
    glEnd();
    //
    x1 = ax + m*(bx - ax);
    y1 = ay + m*(by - ay);
    x2 = bx + m*(cx - bx);
    y2 = by + m*(cy - by);
    x3 = cx + m*(dx - cx);
    y3 = cy + m*(dy - cy);
    x4 = dx + m*(ax - dx);
    y4 = dy + m*(ay - dy);
    //
    ax = x1; ay = y1;
    bx = x2; by = y2;
    cx = x3; cy = y3;
    dx = x4; dy = y4;
  }
  glFlush();
}

void myMoveMouse (int x, int y)
{
  drawsquare(x, y);
}

void mouse (int button, int state, int x, int y)
{
  if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
    drawsquare (x, y);
  if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_UP))
    exit (-1);
}

void init ()
{
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glColor3f(0.0, 1.0, 0.0);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  //gluOrtho2D(0, 500, 0, 500);
}

int main (int argc, char** argv)
{
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
  glutInitWindowSize(500, 500);
  glutInitWindowPosition(0, 0);
  glutCreateWindow("Square inside Square");

  /* according to wich button is pushed and is up or down
   * the value of x,y at that point is returned */
   //glutMouseFunc(mouse);

   // no button has to be pushed, returns only x,y
   //glutPassiveMotionFunc(myMoveMouse);

   // any one of the buttons has to be pushed, returns only x,y
   glutMotionFunc(myMoveMouse);

   glutDisplayFunc(display);
   init();
   glutMainLoop();
}
<|endoftext|>


<commit_before>#include <gecode/driver.hh>
#include <gecode/int.hh>
#include <gecode/minimodel.hh>
#include <gecode/gist.hh>
#include <gecode/search.hh>

#include "dep_selector_to_gecode.h"

#include <iostream>
#include <vector>
//
// T
//

using namespace Gecode;

//
// Version Problem
//
const int VersionProblem::UNRESOLVED_VARIABLE = -1;

VersionProblem::VersionProblem()
{
}

// Clone constructor; check gecode rules for this...
VersionProblem::VersionProblem(bool share, VersionProblem & s)
  : Script(share, s)
{
  package_versions.update(*this, share, s.package_versions);
}

// Support for gecode
Space* VersionProblem::copy(bool share)
{
  return new VersionProblem(share,*this);
}

VersionProblem::~VersionProblem() {
}

int
VersionProblem::AddPackage(int minVersion, int maxVersion, int currentVersion)
{
  int index = package_version_accumulator.size();
  IntVar version(*this, minVersion, maxVersion);
  package_version_accumulator << version;
  return index;
}

bool
VersionProblem::AddVersionConstraint(int packageId, int version,
				     int dependentPackageId, int minDependentVersion, int maxDependentVersion)

{
  BoolVar pred(*this, 0, 1);
  version_flags << pred;
  // Constrain pred to reify package @ version
  rel(*this, package_version_accumulator[packageId], IRT_EQ, version, pred);
  // Add the predicated version constraints imposed on dependent package
  dom(*this, package_version_accumulator[dependentPackageId], minDependentVersion, maxDependentVersion, pred);
}

void VersionProblem::Finalize()
{
  package_versions = IntVarArray(*this, package_version_accumulator);
  branch(*this, package_versions, INT_VAR_SIZE_MIN, INT_VAL_MAX);
}

IntVar & VersionProblem::SafeGetVar(int packageId)
{
  IntVar & var = package_versions[packageId];
}

int VersionProblem::GetPackageVersion(int packageId)
{
  IntVar & var = SafeGetVar(packageId);
  if (1 == var.size()) return var.val();
  return UNRESOLVED_VARIABLE;
}
int VersionProblem::GetAFC(int packageId)
{
  return SafeGetVar(packageId).afc();
}

int VersionProblem::GetMax(int packageId)
{
  return SafeGetVar(packageId).max();
}
int VersionProblem::GetMin(int packageId)
{
  return SafeGetVar(packageId).min();
}

// Utility
void VersionProblem::Print(std::ostream & out)
{
  out << "Version problem dump: " << package_versions.size() << " elements" << std::endl;
  for (int i = 0; i < package_versions.size(); i++) {
    out << "\t";
    PrintPackageVar(out, i);
    out << std::endl;
  }
}

// TODO: Validate package ids !

void VersionProblem::PrintPackageVar(std::ostream & out, int packageId)
{
  // Hack Alert: we could have the package variable in one of two places, but we don't clearly distinguish where.
  IntVar & var = package_version_accumulator[packageId];
  if (package_versions.size() > 0) {
    var = package_versions[packageId];
  }
  out << "PackageId: " << packageId <<  " Sltn: " << var.min() << " - " << var.max() << " afc: " << var.afc();
}

bool VersionProblem::CheckPackageId(int id)
{
  return (id < package_version_accumulator.size()) || (id < package_versions.size());
}

VersionProblem * VersionProblem::Solve(VersionProblem * problem)
{
  problem->Finalize();
  problem->status();
  problem->Print(std::cout);
  DFS<VersionProblem> solver(problem);

  // std::cout << solver.statistics();

  if (VersionProblem * solution = solver.next())
    {
      return solution;
    }
  return 0;
}
<commit_msg>Fix bad constraint system for dependencies.<commit_after>#include <gecode/driver.hh>
#include <gecode/int.hh>
#include <gecode/minimodel.hh>
#include <gecode/gist.hh>
#include <gecode/search.hh>

#include "dep_selector_to_gecode.h"

#include <iostream>
#include <vector>
//
// T
//

using namespace Gecode;

//
// Version Problem
//
const int VersionProblem::UNRESOLVED_VARIABLE = -1;

VersionProblem::VersionProblem()
{
}

// Clone constructor; check gecode rules for this...
VersionProblem::VersionProblem(bool share, VersionProblem & s)
  : Script(share, s)
{
  package_versions.update(*this, share, s.package_versions);
}

// Support for gecode
Space* VersionProblem::copy(bool share)
{
  return new VersionProblem(share,*this);
}

VersionProblem::~VersionProblem() {
}

int
VersionProblem::AddPackage(int minVersion, int maxVersion, int currentVersion)
{
  int index = package_version_accumulator.size();
  IntVar version(*this, minVersion, maxVersion);
  package_version_accumulator << version;
  return index;
}

bool
VersionProblem::AddVersionConstraint(int packageId, int version,
				     int dependentPackageId, int minDependentVersion, int maxDependentVersion)

{
  BoolVar version_match(*this, 0, 1);
  BoolVar depend_match(*this, 0, 1);
  //version_flags << version_match;
  // Constrain pred to reify package @ version
  rel(*this, package_version_accumulator[packageId], IRT_EQ, version, version_match);
  // Add the predicated version constraints imposed on dependent package
  dom(*this, package_version_accumulator[dependentPackageId], minDependentVersion, maxDependentVersion, depend_match);
  rel(*this, version_match, BOT_IMP, depend_match, 1);
}

void VersionProblem::Finalize()
{
  package_versions = IntVarArray(*this, package_version_accumulator);
  branch(*this, package_versions, INT_VAR_SIZE_MIN, INT_VAL_MAX);
}

IntVar & VersionProblem::SafeGetVar(int packageId)
{
  IntVar & var = package_versions[packageId];
}

int VersionProblem::GetPackageVersion(int packageId)
{
  IntVar & var = SafeGetVar(packageId);
  if (1 == var.size()) return var.val();
  return UNRESOLVED_VARIABLE;
}
int VersionProblem::GetAFC(int packageId)
{
  return SafeGetVar(packageId).afc();
}

int VersionProblem::GetMax(int packageId)
{
  return SafeGetVar(packageId).max();
}
int VersionProblem::GetMin(int packageId)
{
  return SafeGetVar(packageId).min();
}

// Utility
void VersionProblem::Print(std::ostream & out)
{
  out << "Version problem dump: " << package_versions.size() << " elements" << std::endl;
  for (int i = 0; i < package_versions.size(); i++) {
    out << "\t";
    PrintPackageVar(out, i);
    out << std::endl;
  }
}

// TODO: Validate package ids !

void VersionProblem::PrintPackageVar(std::ostream & out, int packageId)
{
  // Hack Alert: we could have the package variable in one of two places, but we don't clearly distinguish where.
  IntVar & var = package_version_accumulator[packageId];
  if (package_versions.size() > 0) {
    var = package_versions[packageId];
  }
  out << "PackageId: " << packageId <<  " Sltn: " << var.min() << " - " << var.max() << " afc: " << var.afc();
}

bool VersionProblem::CheckPackageId(int id)
{
  return (id < package_version_accumulator.size()) || (id < package_versions.size());
}

VersionProblem * VersionProblem::Solve(VersionProblem * problem)
{
  problem->Finalize();
  problem->status();
  problem->Print(std::cout);
  DFS<VersionProblem> solver(problem);

  // std::cout << solver.statistics();

  if (VersionProblem * solution = solver.next())
    {
      return solution;
    }
  return 0;
}
<|endoftext|>


<commit_before>// Author: Sergey Linev <S.Linev@gsi.de>
// Date: 2017-06-29
// Warning: This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!

/*************************************************************************
 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "rooturlschemehandler.h"

#include "rootwebpage.h" // only because of logger channel

#include <QBuffer>
#include <QByteArray>
#include <QFile>
#include <QWebEngineUrlRequestJob>

#include <ROOT/RLogger.hxx>

#include "THttpServer.h"
#include "THttpCallArg.h"
#include "TBase64.h"

/** \class UrlRequestJobHolder
\ingroup qt5webdisplay

Class UrlRequestJobHolder
Required to monitor state of QWebEngineUrlRequestJob
Qt can delete object at any time, therefore one connects destroy signal
from the request to clear pointer

*/

/////////////////////////////////////////////////////////////////
/// Constructor

UrlRequestJobHolder::UrlRequestJobHolder(QWebEngineUrlRequestJob *req) : QObject(), fRequest(req)
{
   if (fRequest)
      connect(fRequest, &QObject::destroyed, this, &UrlRequestJobHolder::onRequestDeleted);
}

/////////////////////////////////////////////////////////////////
/// destroyed signal handler

void UrlRequestJobHolder::onRequestDeleted(QObject *obj)
{
   if (fRequest == obj)
      fRequest = nullptr;
}

/////////////////////////////////////////////////////////////////
/// Reset holder

void UrlRequestJobHolder::reset()
{
   if (fRequest)
      disconnect(fRequest, &QObject::destroyed, this, &UrlRequestJobHolder::onRequestDeleted);
   fRequest = nullptr;
}

// ===================================================================

/////////////////////////////////////////////////////////////////////////////////////
/// Class TWebGuiCallArg
/// Specialized handler of requests in THttpServer with QWebEngine
////////////////////////////////////////////////////////////////////////////////////

class TWebGuiCallArg : public THttpCallArg {

protected:
   UrlRequestJobHolder fRequest;

public:
   explicit TWebGuiCallArg(QWebEngineUrlRequestJob *req = nullptr) : THttpCallArg(), fRequest(req) {}

   virtual ~TWebGuiCallArg() {}

   /** provide WS kind  */
   const char *GetWSKind() const override { return "rawlongpoll"; }

   /** provide WS platform, intentially keep qt5 here while it only used on client side */
   const char *GetWSPlatform() const override { return "qt5"; }

   void SendFile(const char *fname)
   {
      const char *mime = THttpServer::GetMimeType(fname);

      QBuffer *buffer = new QBuffer;

      QFile file(fname);
      buffer->open(QIODevice::WriteOnly);
      if (file.open(QIODevice::ReadOnly)) {
         QByteArray arr = file.readAll();
         buffer->write(arr);
      }
      file.close();
      buffer->close();

      QWebEngineUrlRequestJob *req = fRequest.req();

      if (req) {
         buffer->connect(req, &QObject::destroyed, buffer, &QObject::deleteLater);
         req->reply(mime, buffer);
         fRequest.reset();
      }
   }

   void HttpReplied() override
   {
      QWebEngineUrlRequestJob *req = fRequest.req();

      if (!req) {
         R__LOG_ERROR(QtWebDisplayLog()) << "Qt5 request already processed path " << GetPathName() << " file " << GetFileName();
         return;
      }

      if (Is404()) {
         R__LOG_ERROR(QtWebDisplayLog()) << "Qt5 request FAIL path " << GetPathName() << " file " << GetFileName();

         req->fail(QWebEngineUrlRequestJob::UrlNotFound);
         // abort request
      } else if (IsFile()) {
         // send file
         SendFile((const char *)GetContent());
      } else {

         QBuffer *buffer = new QBuffer;

         buffer->open(QIODevice::WriteOnly);

         buffer->write((const char *)GetContent(), GetContentLength());

         buffer->close();

         buffer->connect(req, &QObject::destroyed, buffer, &QObject::deleteLater);

         req->reply(GetContentType(), buffer);
      }

      fRequest.reset();
   }
};

/////////////////////////////////////////////////////////////////
/// Returns fully qualified URL, required to open in QWindow

QString RootUrlSchemeHandler::MakeFullUrl(THttpServer *serv, const QString &url)
{
   // TODO: provide support for many servers
   fServer = serv;

   QString res = "rootscheme://root.server1";
   res.append(url);
   return res;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
/// Start processing of emulated HTTP request in WebEngine scheme handler
/// Either one reads file or redirect request to THttpServer

void RootUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request)
{
   QUrl url = request->requestUrl();

   if (!fServer) {
      R__LOG_ERROR(QtWebDisplayLog()) << "Server not specified when request is started";
      request->fail(QWebEngineUrlRequestJob::UrlNotFound);
      return;
   }

   QString inp_path = url.path();
   QString inp_query = url.query();
   QString inp_method = request->requestMethod();

   // printf("REQUEST PATH:%s QUERY:%s\n", inp_path.toLatin1().data(), inp_query.toLatin1().data());

   auto arg = std::make_shared<TWebGuiCallArg>(request);

   TString fname;

   // process file
   if (fServer->IsFileRequested(inp_path.toLatin1().data(), fname)) {
      arg->SendFile(fname.Data());
      return;
   }

   // Analyze and cut post data as soon as possible
   TString query = inp_query.toLatin1().data();
   Int_t pos = query.Index("&post=");
   if (pos != kNPOS) {
      TString buf = TBase64::Decode(query.Data() + pos + 6);
      arg->SetPostData(std::string(buf.Data()));
      query.Resize(pos);
   }

   arg->SetPathAndFileName(inp_path.toLatin1().data());
   arg->SetQuery(query.Data());
   arg->SetMethod(inp_method.toLatin1().data());
   arg->SetTopName("webgui");

   // can process immediately - function called in main thread
   fServer->SubmitHttp(arg, kTRUE);
}
<commit_msg>[webgui] update comment in qt scheme handler<commit_after>// Author: Sergey Linev <S.Linev@gsi.de>
// Date: 2017-06-29
// Warning: This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!

/*************************************************************************
 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "rooturlschemehandler.h"

#include "rootwebpage.h" // only because of logger channel

#include <QBuffer>
#include <QByteArray>
#include <QFile>
#include <QWebEngineUrlRequestJob>

#include <ROOT/RLogger.hxx>

#include "THttpServer.h"
#include "THttpCallArg.h"
#include "TBase64.h"

/** \class UrlRequestJobHolder
\ingroup qt5webdisplay

Class UrlRequestJobHolder
Required to monitor state of QWebEngineUrlRequestJob
Qt can delete object at any time, therefore one connects destroy signal
from the request to clear pointer

*/

/////////////////////////////////////////////////////////////////
/// Constructor

UrlRequestJobHolder::UrlRequestJobHolder(QWebEngineUrlRequestJob *req) : QObject(), fRequest(req)
{
   if (fRequest)
      connect(fRequest, &QObject::destroyed, this, &UrlRequestJobHolder::onRequestDeleted);
}

/////////////////////////////////////////////////////////////////
/// destroyed signal handler

void UrlRequestJobHolder::onRequestDeleted(QObject *obj)
{
   if (fRequest == obj)
      fRequest = nullptr;
}

/////////////////////////////////////////////////////////////////
/// Reset holder

void UrlRequestJobHolder::reset()
{
   if (fRequest)
      disconnect(fRequest, &QObject::destroyed, this, &UrlRequestJobHolder::onRequestDeleted);
   fRequest = nullptr;
}

// ===================================================================

/////////////////////////////////////////////////////////////////////////////////////
/// Class TWebGuiCallArg
/// Specialized handler of requests in THttpServer with QWebEngine
////////////////////////////////////////////////////////////////////////////////////

class TWebGuiCallArg : public THttpCallArg {

protected:
   UrlRequestJobHolder fRequest;

public:
   explicit TWebGuiCallArg(QWebEngineUrlRequestJob *req = nullptr) : THttpCallArg(), fRequest(req) {}

   virtual ~TWebGuiCallArg() {}

   /** provide WS kind  */
   const char *GetWSKind() const override { return "rawlongpoll"; }

   /** provide WS platform, intentionally keep qt5 here while it only used on client side */
   const char *GetWSPlatform() const override { return "qt5"; }

   void SendFile(const char *fname)
   {
      const char *mime = THttpServer::GetMimeType(fname);

      QBuffer *buffer = new QBuffer;

      QFile file(fname);
      buffer->open(QIODevice::WriteOnly);
      if (file.open(QIODevice::ReadOnly)) {
         QByteArray arr = file.readAll();
         buffer->write(arr);
      }
      file.close();
      buffer->close();

      QWebEngineUrlRequestJob *req = fRequest.req();

      if (req) {
         buffer->connect(req, &QObject::destroyed, buffer, &QObject::deleteLater);
         req->reply(mime, buffer);
         fRequest.reset();
      }
   }

   void HttpReplied() override
   {
      QWebEngineUrlRequestJob *req = fRequest.req();

      if (!req) {
         R__LOG_ERROR(QtWebDisplayLog()) << "Qt5 request already processed path " << GetPathName() << " file " << GetFileName();
         return;
      }

      if (Is404()) {
         R__LOG_ERROR(QtWebDisplayLog()) << "Qt5 request FAIL path " << GetPathName() << " file " << GetFileName();

         req->fail(QWebEngineUrlRequestJob::UrlNotFound);
         // abort request
      } else if (IsFile()) {
         // send file
         SendFile((const char *)GetContent());
      } else {

         QBuffer *buffer = new QBuffer;

         buffer->open(QIODevice::WriteOnly);

         buffer->write((const char *)GetContent(), GetContentLength());

         buffer->close();

         buffer->connect(req, &QObject::destroyed, buffer, &QObject::deleteLater);

         req->reply(GetContentType(), buffer);
      }

      fRequest.reset();
   }
};

/////////////////////////////////////////////////////////////////
/// Returns fully qualified URL, required to open in QWindow

QString RootUrlSchemeHandler::MakeFullUrl(THttpServer *serv, const QString &url)
{
   // TODO: provide support for many servers
   fServer = serv;

   QString res = "rootscheme://root.server1";
   res.append(url);
   return res;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
/// Start processing of emulated HTTP request in WebEngine scheme handler
/// Either one reads file or redirect request to THttpServer

void RootUrlSchemeHandler::requestStarted(QWebEngineUrlRequestJob *request)
{
   QUrl url = request->requestUrl();

   if (!fServer) {
      R__LOG_ERROR(QtWebDisplayLog()) << "Server not specified when request is started";
      request->fail(QWebEngineUrlRequestJob::UrlNotFound);
      return;
   }

   QString inp_path = url.path();
   QString inp_query = url.query();
   QString inp_method = request->requestMethod();

   // printf("REQUEST PATH:%s QUERY:%s\n", inp_path.toLatin1().data(), inp_query.toLatin1().data());

   auto arg = std::make_shared<TWebGuiCallArg>(request);

   TString fname;

   // process file
   if (fServer->IsFileRequested(inp_path.toLatin1().data(), fname)) {
      arg->SendFile(fname.Data());
      return;
   }

   // Analyze and cut post data as soon as possible
   TString query = inp_query.toLatin1().data();
   Int_t pos = query.Index("&post=");
   if (pos != kNPOS) {
      TString buf = TBase64::Decode(query.Data() + pos + 6);
      arg->SetPostData(std::string(buf.Data()));
      query.Resize(pos);
   }

   arg->SetPathAndFileName(inp_path.toLatin1().data());
   arg->SetQuery(query.Data());
   arg->SetMethod(inp_method.toLatin1().data());
   arg->SetTopName("webgui");

   // can process immediately - function called in main thread
   fServer->SubmitHttp(arg, kTRUE);
}
<|endoftext|>


<commit_before>//
//  main.cpp
//  prel
//
//  Created by George Oblapenko on 11/11/14.
//  Copyright (c) 2014 George Oblapenko. All rights reserved.
//

#include <iostream>
#include <kineticlib.h>

int main(int argc, const char * argv[]) {
	double start_T = 2000.; // the start temperature
	double end_T = 10000.0; // the end temperature
	double p = 100000.0; // atmospheric pressure
	double xN = 0.5; // the relative numeric density of atomic nitrogen
	double xN2 = 1. - xN;

	std::string cs_model = "VSS";  // the dissociation cross-section model
	bool vl_dependent = false;  // whether the dissociation cross-section is dependent on the vibrational level of the dissociating molecule

	int points_amt = 50; // the amount of points
	arma::vec T_array = arma::linspace<arma::vec>(start_T, end_T, points_amt); // start value of T, end value of T, amount of steps
	arma::vec prel = arma::zeros(50); // array of relaxation pressure values

	klib::MoleculeOneT N2 = klib::MoleculeOneT("N2");
	klib::Atom N = klib::Atom("N");
	arma::vec idata_N2N2 = klib::load_elastic_parameters(N2, N2); // N2 + N2 elastic interaction data
	arma::vec idata_N2N = klib::load_elastic_parameters(N2, N); // N2 + N elastic interaction data
	arma::vec ddata_N2N2 = klib::load_dissociation_parameters(N2, N2); // N2 + N2 dissociation data
	arma::vec ddata_N2N = klib::load_dissociation_parameters(N2, N); // N2 + N dissociation data
	arma::mat33 beta_matrix; // the matrix of beta integral brackets
	arma::vec3 right_parts; // the right-hand side of the system
	arma::vec3 results; // the values of the expansion coefficients g_{c,pq} - the order is g_{N2,10}, g_{N2,01}, g_{N,10}

	double R_react_N2, R_react_N; // relaxation terms
	double T, n, rho, omega11_N2N, tau_rot_N2N, tau_rot_N2N2, eta_zeta_N2N2, eta_zeta_N2N, cV, SJsl, PJsl, SJslN2, PJslN2; // the numeric density of the mixture, the density of the mixture, Omega^{(1,1)}_{N2,N}, rotational relaxation times for N2+N and N2+N2, the quantity 4T \pi / (\eta_{cd} * \xi_{cd}), the quantity dE/dT
	double tmp_int00 = 0.0;
	beta_matrix.at(0, 0) = 1.5 * (1. - xN);
	beta_matrix.at(0, 2) = 1.5 * xN; // these appear due to the constraint conditions and are independent of temperature
	beta_matrix.zeros();
	right_parts[0] = 0.;
	for (int i = 0; i < points_amt; i++) {
		T = T_array[i];
		n = p / (KLIB_CONST_K * T);
		N2.renorm(T, xN2 * n);
		rho = xN2 * n * N2.mass + xN * n * N.mass;
		omega11_N2N = klib::omega(T, 1, 1, idata_N2N, "ESA", true, true); // we set nokt to true so that the result is of order 10e-07 instead of 10e-16
		tau_rot_N2N = klib::rot_rel_time_vss(T, idata_N2N, N2, n);
		tau_rot_N2N2 = klib::rot_rel_time_vss(T, idata_N2N2, N2, n);
		eta_zeta_N2N2 = 1. / (n * KLIB_CONST_K * tau_rot_N2N2);
		eta_zeta_N2N = 1. / (n * KLIB_CONST_K * tau_rot_N2N);
		cV = 1.5 * KLIB_CONST_K * n / rho + xN2 * (N2.mass * n / rho) * (N2.crot + N2.E_vibr_dT(T));
		beta_matrix.at(0, 1) = xN2 * klib::wt_poly_norm(T, N2);

		beta_matrix.at(1, 0) = -xN2 * N2.mass * N2.crot * (xN * (0.33333) * eta_zeta_N2N + xN2 * eta_zeta_N2N2); // does vibrational relaxation time play any significant role?
		beta_matrix.at(1, 1) = xN2 * N2.mass * N2.crot * (xN * eta_zeta_N2N + xN2 * eta_zeta_N2N2);
		beta_matrix.at(2, 0) = (2. / 9.) * xN2 * xN * (-16 * omega11_N2N + sqrt(1. / (KLIB_CONST_K * T)) * N2.mass * N2.crot * eta_zeta_N2N);
		beta_matrix.at(2, 2) = (2. / 9.) * xN2 * xN * (16 * omega11_N2N + sqrt(1. / (KLIB_CONST_K * T)) * N2.mass * N2.crot * eta_zeta_N2N);

		beta_matrix.at(1, 0) /= sqrt(KLIB_CONST_K * T);
		beta_matrix.at(1, 1) /= sqrt(KLIB_CONST_K * T);
		R_react_N2 = -klib::diss_rate_treanor_marrone(T, ddata_N2N, N2) * (xN * n) * (xN2 * n);

		R_react_N2 /= sqrt(KLIB_CONST_K * T);
		R_react_N = -2 * R_react_N2; // this is a binary mixture and the relaxation terms are related in a simple way

		SJsl = 0.0;
		PJsl = 0.0;
		SJslN2 = 0.0;
		PJslN2 = 0.0;

		for (int vl = 0; vl <= N2.num_vibr; vl++) {
			tmp_int00 = klib::diss_integral(T, 0, idata_N2N, N2, vl, true, vl_dependent, cs_model, true);
			SJsl += (1. / 3.) * (12 * tmp_int00  - klib::diss_integral(T, 1, idata_N2N, N2, vl, true, true, cs_model, true)) * N2.vibr_exp(T, vl) / N2.Z_vibr(T);
			PJsl += (N2.avg_vibr_energy(T, false) - N2.vibr[vl] / (KLIB_CONST_K * T)) * 8 * tmp_int00 * N2.vibr_exp(T, vl) / N2.Z_vibr(T);

			tmp_int00 = klib::diss_integral(T, 0, idata_N2N2, N2, vl, true, vl_dependent, cs_model, true);
			SJslN2 += (1. / 2.) * (12 * tmp_int00 - 8 * klib::diss_integral(T, 1, idata_N2N2, N2, vl, true, vl_dependent, cs_model, true)) * N2.vibr_exp(T, vl) / N2.Z_vibr(T);
			PJslN2 += (N2.avg_vibr_energy(T, false) - N2.vibr[vl] / (KLIB_CONST_K * T)) * 8 * tmp_int00 * N2.vibr_exp(T, vl) / N2.Z_vibr(T);
		}

		right_parts[1] = xN2 * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * klib::wt_poly_norm(T, N2) / (rho * T * cV) + PJsl * (xN * xN2) * n;
		right_parts[2] = xN * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * 1.5 / (rho * T * cV) - 2 * 1.5 * SJsl * (xN * xN2) * n;
		results = arma::solve(beta_matrix, right_parts);
		std::cout << "\nprel_{N2+N}=" << -KLIB_CONST_K * T * (xN2 * results[0] + xN * results[2]) * klib::Gamma_diss(T, N2, N, N, xN2 * n, xN * n, xN * n);

		R_react_N2 = klib::diss_rate_treanor_marrone(T, ddata_N2N2, N2) * (xN2 * n) * (xN2 * n);
		R_react_N2 /= sqrt(KLIB_CONST_K * T);
		R_react_N = -2 * R_react_N2;
		right_parts[1] = xN2 * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * klib::wt_poly_norm(T, N2) / (rho * T * cV) + PJslN2 * (xN2 * xN2) * n;
		right_parts[2] = xN * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * 1.5 / (rho * T * cV);
		results = arma::solve(beta_matrix, right_parts);
		std::cout << "; prel_{N2+N2}=" << -KLIB_CONST_K * T * (xN2 * results[0] + xN * results[2]) * klib::Gamma_diss(T, N2, N, N, xN2 * n, xN * n, xN * n);
	}
}
<commit_msg>output to csv file added<commit_after>//
//  main.cpp
//  prel
//
//  Created by George Oblapenko on 11/11/14.
//  Copyright (c) 2014 George Oblapenko. All rights reserved.
//

#include <iostream>
#include <kineticlib.h>
#include <fstream>

int main(int argc, const char * argv[]) {
	double start_T = 500.; // the start temperature
	double end_T = 10000.0; // the end temperature
	double p = 100000.0; // atmospheric pressure
	double xN = 0.9; // the relative numeric density of atomic nitrogen
	double xN2 = 1. - xN;

	std::string cs_model = "VSS";  // the dissociation cross-section model
	bool vl_dependent = false;  // whether the dissociation cross-section is dependent on the vibrational level of the dissociating molecule

	int points_amt = 20; // the amount of points
	arma::vec T_array = arma::linspace<arma::vec>(start_T, end_T, points_amt); // start value of T, end value of T, amount of steps
	arma::vec prel = arma::zeros(points_amt); // array of relaxation pressure values

	klib::MoleculeOneT N2 = klib::MoleculeOneT("N2");
	klib::Atom N = klib::Atom("N");
	arma::vec idata_N2N2 = klib::load_elastic_parameters(N2, N2); // N2 + N2 elastic interaction data
	arma::vec idata_N2N = klib::load_elastic_parameters(N2, N); // N2 + N elastic interaction data
	arma::vec ddata_N2N2 = klib::load_dissociation_parameters(N2, N2); // N2 + N2 dissociation data
	arma::vec ddata_N2N = klib::load_dissociation_parameters(N2, N); // N2 + N dissociation data
	arma::mat33 beta_matrix; // the matrix of beta integral brackets
	arma::vec3 right_parts; // the right-hand side of the system
	arma::vec3 results; // the values of the expansion coefficients g_{c,pq} - the order is g_{N2,10}, g_{N2,01}, g_{N,10}

	double R_react_N2, R_react_N; // relaxation terms
	double T, n, rho, omega11_N2N, tau_rot_N2N, tau_rot_N2N2, eta_zeta_N2N2, eta_zeta_N2N, cV, SJsl, PJsl, SJslN2, PJslN2; // the numeric density of the mixture, the density of the mixture, Omega^{(1,1)}_{N2,N}, rotational relaxation times for N2+N and N2+N2, the quantity 4T \pi / (\eta_{cd} * \xi_{cd}), the quantity dE/dT
	double tmp_int00 = 0.0;
	beta_matrix.at(0, 0) = 1.5 * (1. - xN);
	beta_matrix.at(0, 2) = 1.5 * xN; // these appear due to the constraint conditions and are independent of temperature
	beta_matrix.zeros();
	right_parts[0] = 0.;

	std::ofstream fout;
	fout.open("results.csv");

	for (int i = 0; i < points_amt; i++) {
		T = T_array[i];
		n = p / (KLIB_CONST_K * T);
		N2.renorm(T, xN2 * n);
		rho = xN2 * n * N2.mass + xN * n * N.mass;
		omega11_N2N = klib::omega(T, 1, 1, idata_N2N, "ESA", true, true); // we set nokt to true so that the result is of order 10e-07 instead of 10e-16
		tau_rot_N2N = klib::rot_rel_time_vss(T, idata_N2N, N2, n);
		tau_rot_N2N2 = klib::rot_rel_time_vss(T, idata_N2N2, N2, n);
		eta_zeta_N2N2 = 1. / (n * KLIB_CONST_K * tau_rot_N2N2);
		eta_zeta_N2N = 1. / (n * KLIB_CONST_K * tau_rot_N2N);
		cV = 1.5 * KLIB_CONST_K * n / rho + xN2 * (N2.mass * n / rho) * (N2.crot + N2.E_vibr_dT(T));
		beta_matrix.at(0, 1) = xN2 * klib::wt_poly_norm(T, N2);

		beta_matrix.at(1, 0) = -xN2 * N2.mass * N2.crot * (xN * (0.33333) * eta_zeta_N2N + xN2 * eta_zeta_N2N2); // does vibrational relaxation time play any significant role?
		beta_matrix.at(1, 1) = xN2 * N2.mass * N2.crot * (xN * eta_zeta_N2N + xN2 * eta_zeta_N2N2);
		beta_matrix.at(2, 0) = (2. / 9.) * xN2 * xN * (-16 * omega11_N2N + sqrt(1. / (KLIB_CONST_K * T)) * N2.mass * N2.crot * eta_zeta_N2N);
		beta_matrix.at(2, 2) = (2. / 9.) * xN2 * xN * (16 * omega11_N2N + sqrt(1. / (KLIB_CONST_K * T)) * N2.mass * N2.crot * eta_zeta_N2N);

		beta_matrix.at(1, 0) /= sqrt(KLIB_CONST_K * T);
		beta_matrix.at(1, 1) /= sqrt(KLIB_CONST_K * T);
		R_react_N2 = -klib::diss_rate_treanor_marrone(T, ddata_N2N, N2) * (xN * n) * (xN2 * n);

		R_react_N2 /= sqrt(KLIB_CONST_K * T);
		R_react_N = -2 * R_react_N2; // this is a binary mixture and the relaxation terms are related in a simple way

		SJsl = 0.0;
		PJsl = 0.0;
		SJslN2 = 0.0;
		PJslN2 = 0.0;

		for (int vl = 0; vl <= N2.num_vibr; vl++) {
			tmp_int00 = klib::diss_integral(T, 0, idata_N2N, N2, vl, true, vl_dependent, cs_model, true);
			SJsl += (1. / 3.) * (12 * tmp_int00  - klib::diss_integral(T, 1, idata_N2N, N2, vl, true, true, cs_model, true)) * N2.vibr_exp(T, vl) / N2.Z_vibr(T);
			PJsl += (N2.avg_vibr_energy(T, false) - N2.vibr[vl] / (KLIB_CONST_K * T)) * 8 * tmp_int00 * N2.vibr_exp(T, vl) / N2.Z_vibr(T);

			tmp_int00 = klib::diss_integral(T, 0, idata_N2N2, N2, vl, true, vl_dependent, cs_model, true);
			SJslN2 += (1. / 2.) * (12 * tmp_int00 - 8 * klib::diss_integral(T, 1, idata_N2N2, N2, vl, true, vl_dependent, cs_model, true)) * N2.vibr_exp(T, vl) / N2.Z_vibr(T);
			PJslN2 += (N2.avg_vibr_energy(T, false) - N2.vibr[vl] / (KLIB_CONST_K * T)) * 8 * tmp_int00 * N2.vibr_exp(T, vl) / N2.Z_vibr(T);
		}

		right_parts[1] = xN2 * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * klib::wt_poly_norm(T, N2) / (rho * T * cV) + PJsl * (xN * xN2) * n;
		right_parts[2] = xN * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * 1.5 / (rho * T * cV) - 2 * 1.5 * SJsl * (xN * xN2) * n;
		results = arma::solve(beta_matrix, right_parts);
		std::cout << "\nprel_{N2+N}=" << -KLIB_CONST_K * T * (xN2 * results[0] + xN * results[2]) * klib::Gamma_diss(T, N2, N, N, xN2 * n, xN * n, xN * n);
		prel[i] = -KLIB_CONST_K * T * (xN2 * results[0] + xN * results[2]) * klib::Gamma_diss(T, N2, N, N, xN2 * n, xN * n, xN * n);

		/*R_react_N2 = klib::diss_rate_treanor_marrone(T, ddata_N2N2, N2) * (xN2 * n) * (xN2 * n);
		R_react_N2 /= sqrt(KLIB_CONST_K * T);
		R_react_N = -2 * R_react_N2;
		right_parts[1] = xN2 * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * klib::wt_poly_norm(T, N2) / (rho * T * cV) + PJslN2 * (xN2 * xN2) * n;
		right_parts[2] = xN * (R_react_N2 * (1.5 * KLIB_CONST_K * T + N2.avg_full_energy(T) + N2.form)
			+ R_react_N * (1.5 * KLIB_CONST_K * T + N.form)) * 1.5 / (rho * T * cV);
		results = arma::solve(beta_matrix, right_parts);
		std::cout << "; prel_{N2+N2}=" << -KLIB_CONST_K * T * (xN2 * results[0] + xN * results[2]) * klib::Gamma_diss(T, N2, N, N, xN2 * n, xN * n, xN * n);*/
	}

	fout << "prel (xN=" << xN << ")";

	for (int i = 0; i < points_amt; i++) {
		fout << "\n" << prel[i];
	}

	fout.close();
	return 1;
}
<|endoftext|>


<commit_before><commit_msg>Exit fullscreen when creating new tab by search key.<commit_after><|endoftext|>


<commit_before><commit_msg>Disable "Duplicate" and "Copy URL" window actions on TYPE_APP browsers.<commit_after><|endoftext|>


<commit_before><commit_msg>[Mac] Enable fullscreen<commit_after><|endoftext|>


<commit_before><commit_msg>Don't enumerate unmapped top-level windows.  This occurs most often in the Compiz window manager when the browser window is moved partially off-screen.<commit_after><|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file reference_line_smooother.cpp
 **/
#include "modules/planning/reference_line/reference_line_smoother.h"

#include <algorithm>
#include <limits>
#include <string>
#include <utility>

#include "modules/common/log.h"
#include "modules/common/math/vec2d.h"
#include "modules/common/proto/pnc_point.pb.h"
#include "modules/common/util/file.h"
#include "modules/planning/math/curve_math.h"
#include "modules/planning/math/double.h"

namespace apollo {
namespace planning {

bool ReferenceLineSmoother::Init(const std::string& config_file) {
  if (!common::util::GetProtoFromFile(config_file, &smoother_config_)) {
    AERROR << "failed to load config file " << config_file;
    return false;
  }
  return true;
}

void ReferenceLineSmoother::Init(const ReferenceLineSmootherConfig& config) {
  smoother_config_ = config;
}

void ReferenceLineSmoother::Reset() {
  t_knots_.clear();
  ref_points_.clear();
  spline_solver_.reset(nullptr);
}

bool ReferenceLineSmoother::smooth(
    const ReferenceLine& raw_reference_line,
    ReferenceLine* const smoothed_reference_line) {
  Reset();
  std::vector<ReferencePoint> ref_points;
  if (!sampling(raw_reference_line)) {
    AERROR << "Fail to sample reference line smoother points!";
    return false;
  }

  spline_solver_.reset(
      new Spline2dSolver(t_knots_, smoother_config_.spline_order()));

  if (!apply_constraint(raw_reference_line)) {
    AERROR << "Add constraint for spline smoother failed";
    return false;
  }

  if (!ApplyKernel()) {
    AERROR << "Add kernel for spline smoother failed.";
    return false;
  }

  if (!Solve()) {
    AERROR << "Solve spline smoother problem failed";
  }

  // mapping spline to reference line point
  const double start_t = t_knots_.front();
  const double end_t = t_knots_.back();

  const double resolution =
      (end_t - start_t) / (smoother_config_.num_of_total_points() - 1);
  double t = start_t;
  for (std::uint32_t i = 0;
       i < smoother_config_.num_of_total_points() && t < end_t;
       ++i, t += resolution) {
    std::pair<double, double> xy = spline_solver_->spline()(t);
    const double heading = std::atan2(spline_solver_->spline().derivative_y(t),
                                      spline_solver_->spline().DerivativeX(t));
    const double kappa = CurveMath::ComputeCurvature(
        spline_solver_->spline().DerivativeX(t),
        spline_solver_->spline().SecondDerivativeX(t),
        spline_solver_->spline().derivative_y(t),
        spline_solver_->spline().second_derivative_y(t));
    const double dkappa = CurveMath::ComputeCurvatureDerivative(
        spline_solver_->spline().DerivativeX(t),
        spline_solver_->spline().SecondDerivativeX(t),
        spline_solver_->spline().ThirdDerivativeX(t),
        spline_solver_->spline().derivative_y(t),
        spline_solver_->spline().second_derivative_y(t),
        spline_solver_->spline().third_derivative_y(t));

    common::SLPoint ref_sl_point;
    if (!raw_reference_line.xy_to_sl({xy.first, xy.second}, &ref_sl_point)) {
      return false;
    }
    if (ref_sl_point.s() < 0 ||
        ref_sl_point.s() > raw_reference_line.length()) {
      continue;
    }

    ReferencePoint rlp =
        raw_reference_line.get_reference_point(ref_sl_point.s());
    ref_points.emplace_back(ReferencePoint(
        hdmap::MapPathPoint(common::math::Vec2d(xy.first, xy.second), heading,
                            rlp.lane_waypoints()),
        kappa, dkappa, 0.0, 0.0));
  }
  ReferencePoint::remove_duplicates(&ref_points);
  *smoothed_reference_line = ReferenceLine(ref_points);
  return true;
}

bool ReferenceLineSmoother::sampling(const ReferenceLine& raw_reference_line) {
  const double length = raw_reference_line.length();
  const double resolution = length / smoother_config_.num_spline();
  for (std::uint32_t i = 0;
       i <= smoother_config_.num_spline() && i * resolution <= length; ++i) {
    ReferencePoint rlp = raw_reference_line.get_reference_point(resolution * i);
    common::PathPoint path_point;
    path_point.set_x(rlp.x());
    path_point.set_y(rlp.y());
    path_point.set_theta(rlp.heading());
    path_point.set_s(i * resolution);
    ref_points_.push_back(std::move(path_point));
    t_knots_.push_back(i);
  }
  return true;
}

bool ReferenceLineSmoother::apply_constraint(
    const ReferenceLine& raw_reference_line) {
  const double t_length = t_knots_.back() - t_knots_.front();
  double dt = t_length / (smoother_config_.num_evaluated_points() - 1);
  std::vector<double> evaluated_t;
  for (std::uint32_t i = 0; i < smoother_config_.num_evaluated_points(); ++i) {
    evaluated_t.push_back(i * dt);
  }
  std::vector<common::PathPoint> path_points;
  if (!extract_evaluated_points(raw_reference_line, evaluated_t,
                                &path_points)) {
    AERROR << "Extract evaluated points failed";
    return false;
  }

  // Add x, y boundary constraint
  std::vector<double> angles;
  std::vector<double> longitidinal_bound;
  std::vector<double> lateral_bound;
  std::vector<common::math::Vec2d> xy_points;
  for (std::uint32_t i = 0; i < path_points.size(); ++i) {
    angles.push_back(path_points[i].theta());
    longitidinal_bound.push_back(smoother_config_.boundary_bound());
    lateral_bound.push_back(smoother_config_.boundary_bound());
    xy_points.emplace_back(path_points[i].x(), path_points[i].y());
  }

  if (!spline_solver_->mutable_constraint()->Add2dBoundary(
          evaluated_t, angles, xy_points, longitidinal_bound, lateral_bound)) {
    AERROR << "Add 2d boundary constraint failed";
    return false;
  }

  if (!spline_solver_->mutable_constraint()
           ->AddThirdDerivativeSmoothConstraint()) {
    AERROR << "Add jointness constraint failed";
    return false;
  }

  return true;
}

bool ReferenceLineSmoother::ApplyKernel() {
  Spline2dKernel* kernel = spline_solver_->mutable_kernel();

  // add spline kernel
  if (smoother_config_.derivative_weight() > 0) {
    kernel->add_derivative_kernel_matrix(smoother_config_.derivative_weight());
  }

  if (smoother_config_.second_derivative_weight() > 0) {
    kernel->add_second_order_derivative_matrix(
        smoother_config_.second_derivative_weight());
  }

  if (smoother_config_.third_derivative_weight() > 0) {
    kernel->add_third_order_derivative_matrix(
        smoother_config_.third_derivative_weight());
  }

  // TODO(fanhaoyang): change to a configurable param
  kernel->AddRegularization(0.01);
  return true;
}

bool ReferenceLineSmoother::Solve() { return spline_solver_->Solve(); }

bool ReferenceLineSmoother::extract_evaluated_points(
    const ReferenceLine& raw_reference_line, const std::vector<double>& vec_t,
    std::vector<common::PathPoint>* const path_points) const {
  for (std::uint32_t i = 0; i < vec_t.size(); ++i) {
    double s = 0.0;
    if (!get_s_from_param_t(vec_t[i], &s)) {
      AERROR << "Extract point " << i << " failed";
      return false;
    }
    ReferencePoint rlp = raw_reference_line.get_reference_point(s);
    common::PathPoint path_point;
    path_point.set_x(rlp.x());
    path_point.set_y(rlp.y());
    path_point.set_theta(rlp.heading());
    path_point.set_s(s);
    path_points->push_back(std::move(path_point));
  }
  return true;
}

bool ReferenceLineSmoother::get_s_from_param_t(const double t,
                                               double* const s) const {
  if (t_knots_.size() < 2 || Double::Compare(t, t_knots_.back(), 1e-8) > 0) {
    return false;
  }
  std::uint32_t lower = find_index(t);
  std::uint32_t upper = lower + 1;
  double weight = 0.0;
  if (Double::Compare(t_knots_[upper], t_knots_[lower], 1e-8) > 0) {
    weight = (t - t_knots_[lower]) / (t_knots_[upper] - t_knots_[lower]);
  }
  *s =
      ref_points_[lower].s() * (1.0 - weight) + ref_points_[upper].s() * weight;
  return true;
}

std::uint32_t ReferenceLineSmoother::find_index(const double t) const {
  auto upper_bound = std::upper_bound(t_knots_.begin() + 1, t_knots_.end(), t);
  return std::min(t_knots_.size() - 1,
                  static_cast<std::size_t>(upper_bound - t_knots_.begin())) -
         1;
}

}  // namespace planning
}  // namespace apollo
<commit_msg>planning: optimize reference line smoother implementation.<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

/**
 * @file reference_line_smooother.cpp
 **/
#include "modules/planning/reference_line/reference_line_smoother.h"

#include <algorithm>
#include <limits>
#include <string>
#include <utility>

#include "modules/common/log.h"
#include "modules/common/math/vec2d.h"
#include "modules/common/proto/pnc_point.pb.h"
#include "modules/common/util/file.h"
#include "modules/planning/math/curve_math.h"
#include "modules/planning/math/double.h"

namespace apollo {
namespace planning {

bool ReferenceLineSmoother::Init(const std::string& config_file) {
  if (!common::util::GetProtoFromFile(config_file, &smoother_config_)) {
    AERROR << "failed to load config file " << config_file;
    return false;
  }
  return true;
}

void ReferenceLineSmoother::Init(const ReferenceLineSmootherConfig& config) {
  smoother_config_ = config;
}

void ReferenceLineSmoother::Reset() {
  t_knots_.clear();
  ref_points_.clear();
  spline_solver_.reset(nullptr);
}

bool ReferenceLineSmoother::smooth(
    const ReferenceLine& raw_reference_line,
    ReferenceLine* const smoothed_reference_line) {
  Reset();
  std::vector<ReferencePoint> ref_points;
  if (!sampling(raw_reference_line)) {
    AERROR << "Fail to sample reference line smoother points!";
    return false;
  }

  spline_solver_.reset(
      new Spline2dSolver(t_knots_, smoother_config_.spline_order()));

  if (!apply_constraint(raw_reference_line)) {
    AERROR << "Add constraint for spline smoother failed";
    return false;
  }

  if (!ApplyKernel()) {
    AERROR << "Add kernel for spline smoother failed.";
    return false;
  }

  if (!Solve()) {
    AERROR << "Solve spline smoother problem failed";
  }

  // mapping spline to reference line point
  const double start_t = t_knots_.front();
  const double end_t = t_knots_.back();

  const double resolution =
      (end_t - start_t) / (smoother_config_.num_of_total_points() - 1);
  double t = start_t;
  for (std::uint32_t i = 0;
       i < smoother_config_.num_of_total_points() && t < end_t;
       ++i, t += resolution) {
    std::pair<double, double> xy = spline_solver_->spline()(t);
    const double heading = std::atan2(spline_solver_->spline().derivative_y(t),
                                      spline_solver_->spline().DerivativeX(t));
    const double kappa = CurveMath::ComputeCurvature(
        spline_solver_->spline().DerivativeX(t),
        spline_solver_->spline().SecondDerivativeX(t),
        spline_solver_->spline().derivative_y(t),
        spline_solver_->spline().second_derivative_y(t));
    const double dkappa = CurveMath::ComputeCurvatureDerivative(
        spline_solver_->spline().DerivativeX(t),
        spline_solver_->spline().SecondDerivativeX(t),
        spline_solver_->spline().ThirdDerivativeX(t),
        spline_solver_->spline().derivative_y(t),
        spline_solver_->spline().second_derivative_y(t),
        spline_solver_->spline().third_derivative_y(t));

    common::SLPoint ref_sl_point;
    if (!raw_reference_line.xy_to_sl({xy.first, xy.second}, &ref_sl_point)) {
      return false;
    }
    if (ref_sl_point.s() < 0 ||
        ref_sl_point.s() > raw_reference_line.length()) {
      continue;
    }

    ReferencePoint rlp =
        raw_reference_line.get_reference_point(ref_sl_point.s());
    ref_points.emplace_back(ReferencePoint(
        hdmap::MapPathPoint(common::math::Vec2d(xy.first, xy.second), heading,
                            rlp.lane_waypoints()),
        kappa, dkappa, 0.0, 0.0));
  }
  ReferencePoint::remove_duplicates(&ref_points);
  *smoothed_reference_line = ReferenceLine(ref_points);
  return true;
}

bool ReferenceLineSmoother::sampling(const ReferenceLine& raw_reference_line) {
  const double length = raw_reference_line.length();
  const double resolution = length / smoother_config_.num_spline();
  double accumulated_s = 0.0;
  for (std::uint32_t i = 0;
       i <= smoother_config_.num_spline() && accumulated_s <= length;
       ++i, accumulated_s += resolution) {
    ReferencePoint rlp = raw_reference_line.get_reference_point(accumulated_s);
    common::PathPoint path_point;
    path_point.set_x(rlp.x());
    path_point.set_y(rlp.y());
    path_point.set_theta(rlp.heading());
    path_point.set_s(accumulated_s);
    ref_points_.push_back(std::move(path_point));
    t_knots_.push_back(i);
  }
  return true;
}

bool ReferenceLineSmoother::apply_constraint(
    const ReferenceLine& raw_reference_line) {
  const double t_length = t_knots_.back() - t_knots_.front();
  const double dt = t_length / (smoother_config_.num_evaluated_points() - 1);
  std::vector<double> evaluated_t;
  double accumulated_eval_t = 0.0;
  for (std::uint32_t i = 0; i < smoother_config_.num_evaluated_points();
       ++i, accumulated_eval_t += dt) {
    evaluated_t.push_back(accumulated_eval_t);
  }
  std::vector<common::PathPoint> path_points;
  if (!extract_evaluated_points(raw_reference_line, evaluated_t,
                                &path_points)) {
    AERROR << "Extract evaluated points failed";
    return false;
  }

  // Add x, y boundary constraint
  std::vector<double> angles;
  std::vector<double> longitidinal_bound;
  std::vector<double> lateral_bound;
  std::vector<common::math::Vec2d> xy_points;
  for (std::uint32_t i = 0; i < path_points.size(); ++i) {
    angles.push_back(path_points[i].theta());
    longitidinal_bound.push_back(smoother_config_.boundary_bound());
    lateral_bound.push_back(smoother_config_.boundary_bound());
    xy_points.emplace_back(path_points[i].x(), path_points[i].y());
  }

  if (!spline_solver_->mutable_constraint()->Add2dBoundary(
          evaluated_t, angles, xy_points, longitidinal_bound, lateral_bound)) {
    AERROR << "Add 2d boundary constraint failed";
    return false;
  }

  if (!spline_solver_->mutable_constraint()
           ->AddThirdDerivativeSmoothConstraint()) {
    AERROR << "Add jointness constraint failed";
    return false;
  }

  return true;
}

bool ReferenceLineSmoother::ApplyKernel() {
  Spline2dKernel* kernel = spline_solver_->mutable_kernel();

  // add spline kernel
  if (smoother_config_.derivative_weight() > 0) {
    kernel->add_derivative_kernel_matrix(smoother_config_.derivative_weight());
  }

  if (smoother_config_.second_derivative_weight() > 0) {
    kernel->add_second_order_derivative_matrix(
        smoother_config_.second_derivative_weight());
  }

  if (smoother_config_.third_derivative_weight() > 0) {
    kernel->add_third_order_derivative_matrix(
        smoother_config_.third_derivative_weight());
  }

  // TODO(fanhaoyang): change to a configurable param
  kernel->AddRegularization(0.01);
  return true;
}

bool ReferenceLineSmoother::Solve() { return spline_solver_->Solve(); }

bool ReferenceLineSmoother::extract_evaluated_points(
    const ReferenceLine& raw_reference_line, const std::vector<double>& vec_t,
    std::vector<common::PathPoint>* const path_points) const {
  for (const auto t : vec_t) {
    double s = 0.0;
    if (!get_s_from_param_t(t, &s)) {
      AERROR << "get s from " << t << " failed";
      return false;
    }
    ReferencePoint rlp = raw_reference_line.get_reference_point(s);
    common::PathPoint path_point;
    path_point.set_x(rlp.x());
    path_point.set_y(rlp.y());
    path_point.set_theta(rlp.heading());
    path_point.set_s(s);
    path_points->push_back(std::move(path_point));
  }
  return true;
}

bool ReferenceLineSmoother::get_s_from_param_t(const double t,
                                               double* const s) const {
  if (t_knots_.size() < 2 || Double::Compare(t, t_knots_.back(), 1e-8) > 0) {
    return false;
  }
  std::uint32_t lower = find_index(t);
  std::uint32_t upper = lower + 1;
  double weight = 0.0;
  if (Double::Compare(t_knots_[upper], t_knots_[lower], 1e-8) > 0) {
    weight = (t - t_knots_[lower]) / (t_knots_[upper] - t_knots_[lower]);
  }
  *s =
      ref_points_[lower].s() * (1.0 - weight) + ref_points_[upper].s() * weight;
  return true;
}

std::uint32_t ReferenceLineSmoother::find_index(const double t) const {
  auto upper_bound = std::upper_bound(t_knots_.begin() + 1, t_knots_.end(), t);
  return std::min(t_knots_.size() - 1,
                  static_cast<std::size_t>(upper_bound - t_knots_.begin())) -
         1;
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before><commit_msg>Track blending bug fix.<commit_after><|endoftext|>


<commit_before><commit_msg>Clean up language specs file<commit_after><|endoftext|>


<commit_before>#include "find_datarefs_in_files.h"

#include <algorithm>
#include <cctype>
#include <fstream>
#include <sstream>
#include <string>

#include <boost/filesystem.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/algorithm/string.hpp>

#include "XPLMUtilities.h"

inline char isValidDatarefChar(char c) {
	return std::isalnum(c) || '_' == c || '/' == c || '-' == c || '.' == c;
}

const size_t min_dataref_length = 8;

std::vector<std::string> getDatarefsFromFile(const std::string & filename) {
    boost::iostreams::mapped_file_source file;

    try {
        file.open(filename);
    } catch(std::exception & e) {
		return {};
    }

	std::vector<std::string> all_refs;
	size_t start_pos = 0;
	const char * file_data = file.data();
	bool last_char_valid = false;
    for(size_t i = 0; i < file.size(); i++) {
    	if(isValidDatarefChar(file_data[i])) {
    		if(false == last_char_valid) {
    			start_pos = i;
    		}
    		last_char_valid = true;
    		continue;
    	} else {
    		 if(last_char_valid && (i - start_pos) > min_dataref_length) {
    			std::string new_dataref(file_data + start_pos, file_data + i);

    			//get rid of some obvious false positives
    			if('/' != new_dataref.front() && std::string::npos != new_dataref.find('/')) {
    				all_refs.push_back(new_dataref);
    			}
	    	}

    		last_char_valid = false;
    	}
    }

	removeVectorUniques(all_refs);

	const std::string message = std::string("DRT: Found ") + std::to_string(all_refs.size()) + std::string(" unique possible datarefs in file ") + filename + std::string("\n");
	XPLMDebugString(message.c_str());

	return all_refs;
}

std::vector<std::string> getDatarefsFromAircraft(const std::string & acf_path) {
	boost::filesystem::path aircraft_dir = boost::filesystem::path(acf_path).parent_path();

	std::vector<std::string> all_refs;

	// list file
	boost::filesystem::path list_file_path = aircraft_dir / "dataref.txt";
	if(boost::filesystem::exists(list_file_path)) {
		std::vector<std::string> refs = getDatarefsFromFile(list_file_path.string());
		all_refs.insert(all_refs.begin(), refs.begin(), refs.end());
	}

	//cdataref.txt
	boost::filesystem::path cdataref_path = aircraft_dir / "cdataref.txt";
	if(boost::filesystem::exists(cdataref_path) && boost::filesystem::is_regular_file(cdataref_path)) {
		std::ifstream inFile(cdataref_path.native());
        std::stringstream sstr;
        sstr << inFile.rdbuf();

		std::vector<std::string> cdataref_entries;
		std::string s = sstr.str();
		boost::split(cdataref_entries, s, boost::is_any_of("\n\r\t, "));
		for(std::string & s : cdataref_entries) {
			boost::algorithm::trim(s);
		}

		//remove empty lines
		cdataref_entries.erase(std::remove_if(cdataref_entries.begin(), cdataref_entries.end(), [](const std::string & a)-> bool { return a.size() < min_dataref_length; }), cdataref_entries.end());

		all_refs.insert(all_refs.begin(), cdataref_entries.begin(), cdataref_entries.end());

		const std::string message = std::string("DRT: Found ") + std::to_string(cdataref_entries.size()) + std::string(" unique possible datarefs in ") + cdataref_path.string() + std::string("\n");
		XPLMDebugString(message.c_str());
	}

	//plugins
	boost::filesystem::path plugin_dir_path = aircraft_dir / "plugins";

	//for each directory inside plugin path
	if(boost::filesystem::exists(plugin_dir_path)) {
		boost::filesystem::directory_iterator dir_end_it;
		for(boost::filesystem::directory_iterator dir_it(plugin_dir_path); dir_it != dir_end_it; dir_it++) {
			std::vector<std::string> refs = getDatarefsFromPluginFolder(dir_it->path().string());
			all_refs.insert(all_refs.begin(), refs.begin(), refs.end());
		}
	}

	//object files. Recurse over directory structure
	std::vector<boost::filesystem::path> paths;
	paths.push_back(aircraft_dir / "objects");

	while(false == paths.empty()) {
		boost::filesystem::path path = paths.back();
		paths.pop_back();

		if(boost::filesystem::is_directory(path)) {
			//iterate over directory, pushing back
			boost::filesystem::directory_iterator dir_end_it;
			for(boost::filesystem::directory_iterator dir_it(path); dir_it != dir_end_it; dir_it++) {
				paths.push_back(dir_it->path());
			}
		}

		if(boost::filesystem::is_regular_file(path)) {
			if(".obj" == path.extension() || ".acf" == path.extension()) {
				std::vector<std::string> refs = getDatarefsFromFile(path.string());
				all_refs.insert(all_refs.begin(), refs.begin(), refs.end());
			}
		}
	}
	removeVectorUniques(all_refs);
	const std::string message = std::string("DRT: Found ") + std::to_string(all_refs.size()) + std::string(" unique possible datarefs for aircraft ") + acf_path + std::string("\n");
	XPLMDebugString(message.c_str());

	return all_refs;
}

std::vector<std::string> getDatarefsFromListFile(const std::string & filename) {
	return getDatarefsFromFile(filename);
}

std::vector<std::string> getDatarefsFromPluginFolder(const std::string & plugin_dir_path) {
#ifdef __APPLE__
	static const std::string plugin_name = "mac.xpl";
#elif defined _WIN32 || defined _WIN64
	static const std::string plugin_name = "win.xpl";
#else
	static const std::string plugin_name = "lin.xpl";
#endif

	std::vector<std::string> all_refs;
	boost::filesystem::path plugin_dir(plugin_dir_path);
	boost::filesystem::path plugin_old_path = plugin_dir / plugin_name;
	boost::filesystem::path plugin_new_path = plugin_dir / "64" / plugin_name;

	if(boost::filesystem::exists(plugin_old_path)) {
		std::vector<std::string> refs = getDatarefsFromFile(plugin_old_path.string());
		all_refs.insert(all_refs.begin(), refs.begin(), refs.end());
	}
	if(boost::filesystem::exists(plugin_new_path)) {
		std::vector<std::string> refs = getDatarefsFromFile(plugin_new_path.string());
		all_refs.insert(all_refs.begin(), refs.begin(), refs.end());
	}

	removeVectorUniques(all_refs);

	return all_refs;
}<commit_msg>Attempt to load additional datarefs from .acf and .obj in the aircraft directory.<commit_after>#include "find_datarefs_in_files.h"

#include <algorithm>
#include <cctype>
#include <fstream>
#include <sstream>
#include <string>

#include <boost/filesystem.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include <boost/algorithm/string.hpp>

#include "XPLMUtilities.h"

inline char isValidDatarefChar(char c) {
	return std::isalnum(c) || '_' == c || '/' == c || '-' == c || '.' == c;
}

const size_t min_dataref_length = 8;

std::vector<std::string> getDatarefsFromFile(const std::string & filename) {
    boost::iostreams::mapped_file_source file;

    try {
        file.open(filename);
    } catch(std::exception & e) {
		return {};
    }

	std::vector<std::string> all_refs;
	size_t start_pos = 0;
	const char * file_data = file.data();
	bool last_char_valid = false;
    for(size_t i = 0; i < file.size(); i++) {
    	if(isValidDatarefChar(file_data[i])) {
    		if(false == last_char_valid) {
    			start_pos = i;
    		}
    		last_char_valid = true;
    		continue;
    	} else {
    		 if(last_char_valid && (i - start_pos) > min_dataref_length) {
    			std::string new_dataref(file_data + start_pos, file_data + i);

    			//get rid of some obvious false positives
    			if('/' != new_dataref.front() && std::string::npos != new_dataref.find('/')) {
    				all_refs.push_back(new_dataref);
    			}
	    	}

    		last_char_valid = false;
    	}
    }

	removeVectorUniques(all_refs);

	const std::string message = std::string("DRT: Found ") + std::to_string(all_refs.size()) + std::string(" unique possible datarefs in file ") + filename + std::string("\n");
	XPLMDebugString(message.c_str());

	return all_refs;
}

std::vector<std::string> getDatarefsFromAircraft(const std::string & acf_path) {
	boost::filesystem::path aircraft_dir = boost::filesystem::path(acf_path).parent_path();

	std::vector<std::string> all_refs;

	// list file
	boost::filesystem::path list_file_path = aircraft_dir / "dataref.txt";
	if(boost::filesystem::exists(list_file_path)) {
		std::vector<std::string> refs = getDatarefsFromFile(list_file_path.string());
		all_refs.insert(all_refs.begin(), refs.begin(), refs.end());
	}

	//cdataref.txt
	boost::filesystem::path cdataref_path = aircraft_dir / "cdataref.txt";
	if(boost::filesystem::exists(cdataref_path) && boost::filesystem::is_regular_file(cdataref_path)) {
		std::ifstream inFile(cdataref_path.native());
        std::stringstream sstr;
        sstr << inFile.rdbuf();

		std::vector<std::string> cdataref_entries;
		std::string s = sstr.str();
		boost::split(cdataref_entries, s, boost::is_any_of("\n\r\t, "));
		for(std::string & s : cdataref_entries) {
			boost::algorithm::trim(s);
		}

		//remove empty lines
		cdataref_entries.erase(std::remove_if(cdataref_entries.begin(), cdataref_entries.end(), [](const std::string & a)-> bool { return a.size() < min_dataref_length; }), cdataref_entries.end());

		all_refs.insert(all_refs.begin(), cdataref_entries.begin(), cdataref_entries.end());

		const std::string message = std::string("DRT: Found ") + std::to_string(cdataref_entries.size()) + std::string(" unique possible datarefs in ") + cdataref_path.string() + std::string("\n");
		XPLMDebugString(message.c_str());
	}

	//plugins
	boost::filesystem::path plugin_dir_path = aircraft_dir / "plugins";

	//for each directory inside plugin path
	if(boost::filesystem::exists(plugin_dir_path)) {
		boost::filesystem::directory_iterator dir_end_it;
		for(boost::filesystem::directory_iterator dir_it(plugin_dir_path); dir_it != dir_end_it; dir_it++) {
			std::vector<std::string> refs = getDatarefsFromPluginFolder(dir_it->path().string());
			all_refs.insert(all_refs.begin(), refs.begin(), refs.end());
		}
	}

	//object files in aircraft directory
	std::vector<boost::filesystem::path> paths;
	boost::filesystem::directory_iterator dir_end_it;
	for(boost::filesystem::directory_iterator dir_it(aircraft_dir); dir_it != dir_end_it; dir_it++) {
		boost::filesystem::path file_path = dir_it->path();

		if(boost::filesystem::is_regular_file(file_path)) {
			if(".obj" == file_path.extension() || ".acf" == file_path.extension()) {
				paths.push_back(file_path);
			}
		}
	}

	//object files. Recurse over directory structure
	paths.push_back(aircraft_dir / "objects");

	while(false == paths.empty()) {
		boost::filesystem::path path = paths.back();
		paths.pop_back();

		if(boost::filesystem::is_directory(path)) {
			//iterate over directory, pushing back
			boost::filesystem::directory_iterator dir_end_it;
			for(boost::filesystem::directory_iterator dir_it(path); dir_it != dir_end_it; dir_it++) {
				paths.push_back(dir_it->path());
			}
		}

		if(boost::filesystem::is_regular_file(path)) {
			if(".obj" == path.extension() || ".acf" == path.extension()) {
				std::vector<std::string> refs = getDatarefsFromFile(path.string());
				all_refs.insert(all_refs.begin(), refs.begin(), refs.end());
			}
		}
	}
	removeVectorUniques(all_refs);
	const std::string message = std::string("DRT: Found ") + std::to_string(all_refs.size()) + std::string(" unique possible datarefs for aircraft ") + acf_path + std::string("\n");
	XPLMDebugString(message.c_str());

	return all_refs;
}

std::vector<std::string> getDatarefsFromListFile(const std::string & filename) {
	return getDatarefsFromFile(filename);
}

std::vector<std::string> getDatarefsFromPluginFolder(const std::string & plugin_dir_path) {
#ifdef __APPLE__
	static const std::string plugin_name = "mac.xpl";
#elif defined _WIN32 || defined _WIN64
	static const std::string plugin_name = "win.xpl";
#else
	static const std::string plugin_name = "lin.xpl";
#endif

	std::vector<std::string> all_refs;
	boost::filesystem::path plugin_dir(plugin_dir_path);
	boost::filesystem::path plugin_old_path = plugin_dir / plugin_name;
	boost::filesystem::path plugin_new_path = plugin_dir / "64" / plugin_name;

	if(boost::filesystem::exists(plugin_old_path)) {
		std::vector<std::string> refs = getDatarefsFromFile(plugin_old_path.string());
		all_refs.insert(all_refs.begin(), refs.begin(), refs.end());
	}
	if(boost::filesystem::exists(plugin_new_path)) {
		std::vector<std::string> refs = getDatarefsFromFile(plugin_new_path.string());
		all_refs.insert(all_refs.begin(), refs.begin(), refs.end());
	}

	removeVectorUniques(all_refs);

	return all_refs;
}<|endoftext|>


<commit_before>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011,2012 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "jubatus_serv.hpp"
#include "../common/util.hpp"
#include "../common/cht.hpp"
#include "../common/exception.hpp"
#include "../common/mprpc/rpc_client.hpp"
#include "server_util.hpp"
#include "aggregators.hpp"

#include <fstream>
#include <sstream>
#include <pficommon/system/time_util.h>

using std::vector;
using std::string;
using pfi::network::mprpc::rpc_client;
using pfi::lang::function;

using pfi::system::time::clock_time;
using pfi::system::time::get_clock_time;

namespace jubatus { namespace framework {

jubatus_serv::jubatus_serv(const server_argv& a, const std::string& base_path):
  a_(a),
  update_count_(0),
#ifdef HAVE_ZOOKEEPER_H
  mixer_(new mixer(a_.name, a_.interval_count, a_.interval_sec,
		   pfi::lang::bind(&jubatus_serv::do_mix, this, pfi::lang::_1))),
  use_cht_(false),
#endif
  base_path_(a_.tmpdir)
{
};

int jubatus_serv::start(pfi::network::mprpc::rpc_server& serv){

#ifdef HAVE_ZOOKEEPER_H
  if(! a_.is_standalone()){
    zk_ = common::cshared_ptr<jubatus::common::lock_service>
      (common::create_lock_service("zk", a_.z, a_.timeout, "logfile_jubatus_serv"));
    ls = zk_;
    jubatus::common::prepare_jubatus(*zk_);

    if( a_.join ){ // join to the existing cluster with -j option
      join_to_cluster(zk_);
    }

    if( use_cht_ ){
      jubatus::common::cht::setup_cht_dir(*zk_, a_.name);
      jubatus::common::cht ht(zk_, a_.name);
      ht.register_node(a_.eth, a_.port);
    }

    mixer_->set_zk(zk_);
    register_actor(*zk_, a_.name, a_.eth, a_.port);
    mixer_->start();
  }
#endif

  if( serv.serv(a_.port, a_.threadnum) ){
    LOG(INFO) << "running in port=" << a_.port;
    return 0;
  }else{
    LOG(ERROR) << "failed starting server: any process using port " << a_.port << "?";
    return -1;
  }
}

void jubatus_serv::register_mixable(mixable0* m){
#ifdef HAVE_ZOOKEEPER_H
  try{
    m->get_diff(); // #22 ensure m is good pointer at process startup
  }catch(const jubatus::config_not_set& e){
  }

#endif
  mixables_.push_back(m);
};

void jubatus_serv::use_cht(){
#ifdef HAVE_ZOOKEEPER_H
  use_cht_ = true;
#endif
};

std::map<std::string, std::map<std::string,std::string> > jubatus_serv::get_status() const {
  std::map<std::string, std::string> data;
  util::get_machine_status(data);

  data["timeout"] = pfi::lang::lexical_cast<std::string>(a_.timeout);
  data["threadnum"] = pfi::lang::lexical_cast<std::string>(a_.threadnum);
  data["tmpdir"] = a_.tmpdir;
  data["interval_sec"] = pfi::lang::lexical_cast<std::string>(a_.interval_sec);
  data["interval_count"] = pfi::lang::lexical_cast<std::string>(a_.interval_count);
  data["is_standalone"] = pfi::lang::lexical_cast<std::string>(a_.is_standalone());
  data["VERSION"] = JUBATUS_VERSION;
  data["PROGNAME"] = JUBATUS_APPNAME;

  data["update_count"] = pfi::lang::lexical_cast<std::string>(update_count_);

#ifdef HAVE_ZOOKEEPER_H
  mixer_->get_status(data);
  data["zk"] = a_.z;
  data["use_cht"] = pfi::lang::lexical_cast<std::string>(use_cht_);
#endif

  std::map<std::string, std::map<std::string,std::string> > ret;
  ret[get_server_identifier()] = data;
  return ret;
};

std::string jubatus_serv::get_server_identifier()const{
  std::stringstream ss;
  ss << a_.eth;
  ss << "_";
  ss << a_.port;
  return ss.str();
};

//here
#ifdef HAVE_ZOOKEEPER_H
void jubatus_serv::join_to_cluster(common::cshared_ptr<jubatus::common::lock_service> z){
  std::vector<std::string> list;
  std::string path = common::ACTOR_BASE_PATH + "/" + a_.name + "/nodes";
  z->list(path, list);
  if(not list.empty()){
    common::lock_service_mutex zlk(*z, common::ACTOR_BASE_PATH + "/" + a_.name + "/master_lock");
    while(not zlk.try_lock()){ ; }
    size_t i = rand() % list.size();
    std::string ip;
    int port;
    common::revert(list[i], ip, port);
    pfi::network::mprpc::rpc_client c(ip, port, a_.timeout);

    pfi::lang::function<std::string()> f = c.call<std::string()>("get_storage");
    std::stringstream ss( f() );
    for(size_t i = 0;i<mixables_.size(); ++i){
      mixables_[i]->clear();
      mixables_[i]->load(ss);
    }
  }
};

std::string jubatus_serv::get_storage(int i){
  std::stringstream ss;
  for(size_t i=0; i<mixables_.size(); ++i){
    mixables_[i]->save(ss);
  }
  return ss.str();
}

std::vector<std::string> jubatus_serv::get_diff_impl(int){
  // if(mixables_.empty()){
  //   //throw config_not_set(); nothing to mix
  // }
  std::vector<std::string> o;
  {
    scoped_lock lk(rlock(m_));
    for(size_t i=0; i<mixables_.size(); ++i){
      o.push_back(mixables_[i]->get_diff());
    }
  }
  return o;
};

int jubatus_serv::put_diff_impl(std::vector<std::string> unpacked){
  scoped_lock lk(wlock(m_));
  if(unpacked.size() != mixables_.size()){
    //deserialization error
    return -1;
  }
  for(size_t i=0; i<mixables_.size(); ++i){
    mixables_[i]->put_diff(unpacked[i]);
  }
  mixer_->clear();
  return 0;
};

std::vector<std::string> jubatus_serv::mix_agg(const std::vector<std::string>& lhs,
 					       const std::vector<std::string>& rhs){
  if(lhs.size() != rhs.size()){
    // TODO: error. log and assertion exit is good.
  }
  std::vector<std::string> ret;
  for(size_t i = 0; i < lhs.size(); ++i){
    std::string tmp = rhs[i];
    mixables_[i]->reduce(lhs[i], tmp);
    ret.push_back(tmp);
  }
  return ret;
};

void jubatus_serv::do_mix(const std::vector<std::pair<std::string,int> >& v){
  vector<string> accs;
  //vector<string> serialized_diffs;
  clock_time start = get_clock_time();

  {
    pfi::lang::function<std::vector<std::string>(const std::vector<std::string>, const std::vector<std::string>)>
      f = pfi::lang::bind(&jubatus_serv::mix_agg, this, pfi::lang::_1, pfi::lang::_2);

    common::mprpc::rpc_mclient c(v, a_.timeout);
    c.call_async("get_diff", 0);
    accs = c.join_all<std::vector<std::string> >(f);
    c.call_async("put_diff", accs);
    c.join_all<int>(pfi::lang::function<int(int,int)>(&framework::add<int>));
  }
  /*
    for(size_t s = 0; s < v.size(); ++s ){
    try{
          rpc_client c(v[s].first, v[s].second, a_.timeout);
          function<vector<string>(int)> get_diff_fun = c.call<vector<string>(int)>("get_diff");
          serialized_diffs = get_diff_fun(0);
        }catch(std::exception& e){
          LOG(ERROR) << e.what();
          continue;
        }
        scoped_lock lk(rlock(m_)); // model_ should not be in mix (reduce)?
        if(accs.empty()){
          accs = serialized_diffs;
        }else{
          for(size_t i=0; i<mixables_.size(); ++i){
            // FIXME: very inefficient but what sucks is type system of C++
            mixables_[i]->reduce(serialized_diffs[i], accs[i]);
          }
        }
	}*/

      /*
      for(size_t s = 0; s < v.size(); ++s ){
        try{
          rpc_client c(v[s].first, v[s].second, a_.timeout);
          function<int(vector<string>)> put_diff_fun = c.call<int(vector<string>)>("put_diff");
          put_diff_fun(accs);
        }catch(std::exception& e){
          LOG(ERROR) << e.what();
          continue;
        }
      }
      */
  clock_time end = get_clock_time();
  DLOG(INFO) << "mixed with " << v.size() << " servers in " << (double)(end - start) << " secs.";
  size_t s = 0;
  for(size_t i=0; i<accs.size(); ++i){
    s+=accs[i].size();
  }
  DLOG(INFO) << s << " bytes (serialized data) has been put.";
}
#endif

void jubatus_serv::updated(){
#ifdef HAVE_ZOOKEEPER_H
  update_count_ = mixer_->updated();
#else
  update_count_++;
#endif
}

bool jubatus_serv::save(std::string id)  {
  std::string ofile;
  build_local_path_(ofile, "jubatus", id);

  std::ofstream ofs(ofile.c_str(), std::ios::trunc|std::ios::binary);
  if(!ofs){
    throw std::runtime_error(ofile + ": cannot open (" + pfi::lang::lexical_cast<std::string>(errno) + ")" );
  }
  try{
    for(size_t i=0; i<mixables_.size(); ++i){
      mixables_[i]->save(ofs);
    }
    ofs.close();
    LOG(INFO) << "saved to " << ofile;
    return true;
  }catch(const std::runtime_error& e){
    LOG(ERROR) << e.what();
    throw e;
  }
}

bool jubatus_serv::load(std::string id) {
  std::string ifile;
  build_local_path_(ifile, "jubatus", id);

  std::ifstream ifs(ifile.c_str(), std::ios::binary);
  if(!ifs)throw std::runtime_error(ifile + ": cannot open (" + pfi::lang::lexical_cast<std::string>(errno) + ")" );
  try{
    for(size_t i = 0;i<mixables_.size(); ++i){
      mixables_[i]->clear();
      mixables_[i]->load(ifs);
    }
    ifs.close();
    this->after_load();
    return true;
  }catch(const std::runtime_error& e){
    ifs.close();
    LOG(ERROR) << e.what();
    throw e;
  }
}
}}
<commit_msg>fix error handling in mix<commit_after>// Jubatus: Online machine learning framework for distributed environment
// Copyright (C) 2011,2012 Preferred Infrastructure and Nippon Telegraph and Telephone Corporation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#include "jubatus_serv.hpp"
#include "../common/util.hpp"
#include "../common/cht.hpp"
#include "../common/exception.hpp"
#include "../common/mprpc/rpc_client.hpp"
#include "server_util.hpp"
#include "aggregators.hpp"

#include <fstream>
#include <sstream>
#include <pficommon/system/time_util.h>

using std::vector;
using std::string;
using pfi::network::mprpc::rpc_client;
using pfi::lang::function;

using pfi::system::time::clock_time;
using pfi::system::time::get_clock_time;

namespace jubatus { namespace framework {

jubatus_serv::jubatus_serv(const server_argv& a, const std::string& base_path):
  a_(a),
  update_count_(0),
#ifdef HAVE_ZOOKEEPER_H
  mixer_(new mixer(a_.name, a_.interval_count, a_.interval_sec,
		   pfi::lang::bind(&jubatus_serv::do_mix, this, pfi::lang::_1))),
  use_cht_(false),
#endif
  base_path_(a_.tmpdir)
{
};

int jubatus_serv::start(pfi::network::mprpc::rpc_server& serv){

#ifdef HAVE_ZOOKEEPER_H
  if(! a_.is_standalone()){
    // FIXME: need to decide the log file
    // without log output file, zkclient outputs to stderr
    zk_ = common::cshared_ptr<jubatus::common::lock_service>
      (common::create_lock_service("zk", a_.z, a_.timeout, "logfile_jubatus_serv"));
    ls = zk_;
    jubatus::common::prepare_jubatus(*zk_);

    if( a_.join ){ // join to the existing cluster with -j option
      join_to_cluster(zk_);
    }

    if( use_cht_ ){
      jubatus::common::cht::setup_cht_dir(*zk_, a_.name);
      jubatus::common::cht ht(zk_, a_.name);
      ht.register_node(a_.eth, a_.port);
    }

    // FIXME(rethink): is this sequence correct?
    mixer_->set_zk(zk_);
    register_actor(*zk_, a_.name, a_.eth, a_.port);
    mixer_->start();
  }
#endif

  if( serv.serv(a_.port, a_.threadnum) ){
    LOG(INFO) << "running in port=" << a_.port;
    return 0;
  }else{
    LOG(ERROR) << "failed starting server: any process using port " << a_.port << "?";
    return -1;
  }
}

void jubatus_serv::register_mixable(mixable0* m){
#ifdef HAVE_ZOOKEEPER_H
  try{
    m->get_diff(); // #22 ensure m is good pointer at process startup
  }catch(const jubatus::config_not_set& e){
  }

#endif
  mixables_.push_back(m);
};

void jubatus_serv::use_cht(){
#ifdef HAVE_ZOOKEEPER_H
  use_cht_ = true;
#endif
};

std::map<std::string, std::map<std::string,std::string> > jubatus_serv::get_status() const {
  std::map<std::string, std::string> data;
  util::get_machine_status(data);

  data["timeout"] = pfi::lang::lexical_cast<std::string>(a_.timeout);
  data["threadnum"] = pfi::lang::lexical_cast<std::string>(a_.threadnum);
  data["tmpdir"] = a_.tmpdir;
  data["interval_sec"] = pfi::lang::lexical_cast<std::string>(a_.interval_sec);
  data["interval_count"] = pfi::lang::lexical_cast<std::string>(a_.interval_count);
  data["is_standalone"] = pfi::lang::lexical_cast<std::string>(a_.is_standalone());
  data["VERSION"] = JUBATUS_VERSION;
  data["PROGNAME"] = JUBATUS_APPNAME;

  data["update_count"] = pfi::lang::lexical_cast<std::string>(update_count_);

#ifdef HAVE_ZOOKEEPER_H
  mixer_->get_status(data);
  data["zk"] = a_.z;
  data["use_cht"] = pfi::lang::lexical_cast<std::string>(use_cht_);
#endif

  std::map<std::string, std::map<std::string,std::string> > ret;
  ret[get_server_identifier()] = data;
  return ret;
};

std::string jubatus_serv::get_server_identifier()const{
  std::stringstream ss;
  ss << a_.eth;
  ss << "_";
  ss << a_.port;
  return ss.str();
};

//here
#ifdef HAVE_ZOOKEEPER_H
void jubatus_serv::join_to_cluster(common::cshared_ptr<jubatus::common::lock_service> z){
  std::vector<std::string> list;
  std::string path = common::ACTOR_BASE_PATH + "/" + a_.name + "/nodes";
  z->list(path, list);
  if(not list.empty()){
    common::lock_service_mutex zlk(*z, common::ACTOR_BASE_PATH + "/" + a_.name + "/master_lock");
    while(not zlk.try_lock()){ ; }

    // if you're using even any cht, you should choose from cht. otherwise random.
    size_t i = rand() % list.size();

    std::string ip;
    int port;
    common::revert(list[i], ip, port);
    pfi::network::mprpc::rpc_client c(ip, port, a_.timeout);

    pfi::lang::function<std::string(int)> f = c.call<std::string(int)>("get_storage");
    std::string data = f(0);
    LOG(INFO) << "join to cluster: " << data.size() << " bytes got from " << ip << " " << port;
    std::stringstream ss( data );

    for(size_t i = 0;i<mixables_.size(); ++i){
      mixables_[i]->clear();
      mixables_[i]->load(ss);
    }
    DLOG(INFO) << "all data successfully loaded to " << mixables_.size() << " mixables.";
  }
};

std::string jubatus_serv::get_storage(int i){
  std::stringstream ss;
  for(size_t i=0; i<mixables_.size(); ++i){
    mixables_[i]->save(ss);
  }
  return ss.str();
}

std::vector<std::string> jubatus_serv::get_diff_impl(int){
  // if(mixables_.empty()){
  //   //throw config_not_set(); nothing to mix
  // }
  std::vector<std::string> o;
  {
    scoped_lock lk(rlock(m_));
    for(size_t i=0; i<mixables_.size(); ++i){
      o.push_back(mixables_[i]->get_diff());
    }
  }
  return o;
};

int jubatus_serv::put_diff_impl(std::vector<std::string> unpacked){
  scoped_lock lk(wlock(m_));
  if(unpacked.size() != mixables_.size()){
    //deserialization error
    return -1;
  }
  for(size_t i=0; i<mixables_.size(); ++i){
    mixables_[i]->put_diff(unpacked[i]);
  }
  mixer_->clear();
  return 0;
};

std::vector<std::string> jubatus_serv::mix_agg(const std::vector<std::string>& lhs,
 					       const std::vector<std::string>& rhs){
  if(lhs.size() != rhs.size()){
    // TODO: error. log and assertion exit is good.
  }
  std::vector<std::string> ret;
  for(size_t i = 0; i < lhs.size(); ++i){
    std::string tmp = rhs[i];
    mixables_[i]->reduce(lhs[i], tmp);
    ret.push_back(tmp);
  }
  return ret;
};

void jubatus_serv::do_mix(const std::vector<std::pair<std::string,int> >& v){
  vector<string> accs;
  //vector<string> serialized_diffs;
  clock_time start = get_clock_time();

  if(v.empty()){
    LOG(WARNING) << "no other server. ";
    return;
  }else{
    pfi::lang::function<std::vector<std::string>
                        (const std::vector<std::string>, const std::vector<std::string>)>
      f = pfi::lang::bind(&jubatus_serv::mix_agg, this, pfi::lang::_1, pfi::lang::_2);
    common::mprpc::rpc_mclient c(v, a_.timeout);
    try{
      c.call_async("get_diff", 0);
      accs = c.join_all<std::vector<std::string> >(f);
      c.call_async("put_diff", accs);
      c.join_all<int>(pfi::lang::function<int(int,int)>(&framework::add<int>));
    }catch(const std::runtime_error & e){
      LOG(WARNING) << e.what() << " : mix failed";
      return;
    }
  }

  clock_time end = get_clock_time();
  DLOG(INFO) << "mixed with " << v.size() << " servers in " << (double)(end - start) << " secs.";
  size_t s = 0;
  for(size_t i=0; i<accs.size(); ++i){
    s+=accs[i].size();
  }
  DLOG(INFO) << s << " bytes (serialized data) has been put.";
}
#endif

void jubatus_serv::updated(){
#ifdef HAVE_ZOOKEEPER_H
  update_count_ = mixer_->updated();
#else
  update_count_++;
#endif
}

bool jubatus_serv::save(std::string id)  {
  std::string ofile;
  build_local_path_(ofile, "jubatus", id);

  std::ofstream ofs(ofile.c_str(), std::ios::trunc|std::ios::binary);
  if(!ofs){
    throw std::runtime_error(ofile + ": cannot open (" + pfi::lang::lexical_cast<std::string>(errno) + ")" );
  }
  try{
    for(size_t i=0; i<mixables_.size(); ++i){
      mixables_[i]->save(ofs);
    }
    ofs.close();
    LOG(INFO) << "saved to " << ofile;
    return true;
  }catch(const std::runtime_error& e){
    LOG(ERROR) << e.what();
    throw e;
  }
}

bool jubatus_serv::load(std::string id) {
  std::string ifile;
  build_local_path_(ifile, "jubatus", id);

  std::ifstream ifs(ifile.c_str(), std::ios::binary);
  if(!ifs)throw std::runtime_error(ifile + ": cannot open (" + pfi::lang::lexical_cast<std::string>(errno) + ")" );
  try{
    for(size_t i = 0;i<mixables_.size(); ++i){
      mixables_[i]->clear();
      mixables_[i]->load(ifs);
    }
    ifs.close();
    this->after_load();
    return true;
  }catch(const std::runtime_error& e){
    ifs.close();
    LOG(ERROR) << e.what();
    throw e;
  }
}
}}
<|endoftext|>