<commit_before>#ifndef LF_POOL_ALLOC_POOL
#define LF_POOL_ALLOC_POOL

#include <cstdint>
#include <atomic>
#include <memory>
#include <iostream>
#include <cassert>

namespace lfpAlloc {

    template<typename T, uint16_t CellsPerAllocation, std::size_t NumCells>
    class Pool {
    public:
        static_assert(NumCells % CellsPerAllocation == 0,
                      "NumCells must be a multiple of CellsPerAllocation.");

        Pool() : handle_(new Node_),
                 head_(&handle_.load()->memBlock_[0]){}

        ~Pool() {
            Node_* node = handle_.load();
            while(node) {
                auto temp = node;
                node = node->next_;
                delete temp;
            }
        }

        T* allocate(){
        start:
            Cell_* currentHead;
            Cell_* currentNext;

            Node_* currentHandle;
            Node_* newNode;

            // Ran out of cells to allocate
            if (!head_.load()) {

                // Make a new node
                newNode = new Node_;

                // Point the current Head's next to the head of the new node
                do {
                    currentHead = head_.load();
                    newNode->memBlock_[NumCells-CellsPerAllocation].next_ = currentHead;
                } while(!head_.compare_exchange_strong(currentHead, &newNode->memBlock_[0]));

                // Add the node to the chain
                do {
                    currentHandle = handle_.load();
                    newNode->next_ = currentHandle;
                } while(!handle_.compare_exchange_strong(currentHandle, newNode));
                assert(head_.load());
            }

            // Allocate by making head = head.next
            do {
                currentHead = head_.load();
                currentNext = currentHead->next_.load();
            } while (!head_.compare_exchange_strong(currentHead, currentNext));
            return reinterpret_cast<T*>(currentHead);
        }

        void deallocate(void* p) {
            auto newHead = reinterpret_cast<Cell_*>(p);
            Cell_* currentHead;
            do {
                currentHead = head_.load();
                newHead->next_ = currentHead;
            } while (!head_.compare_exchange_strong(currentHead, newHead));
        }

    private:
        union Cell_{
            std::atomic<Cell_*> next_;
            uint8_t val[sizeof(T)];
        };

        struct Node_ {
            Node_() {
                for (uint16_t s=0; s < NumCells/CellsPerAllocation; ++s) {
                    memBlock_[s*CellsPerAllocation].next_
                        .store(&memBlock_[(s+1)*CellsPerAllocation],
                               std::memory_order_relaxed);
                }
                auto& last = memBlock_[NumCells-CellsPerAllocation];
                last.next_.store(nullptr, std::memory_order_relaxed);
            }
            Cell_ memBlock_[NumCells];
            Node_* next_ = nullptr;
        };

        std::atomic<Node_*> handle_;
        std::atomic<Cell_*> head_;
    };
}

#endif
<commit_msg>Reserve first cell in new node for current request<commit_after>#ifndef LF_POOL_ALLOC_POOL
#define LF_POOL_ALLOC_POOL

#include <cstdint>
#include <atomic>
#include <memory>
#include <iostream>
#include <cassert>

namespace lfpAlloc {

    template<typename T, uint16_t CellsPerAllocation, std::size_t NumCells>
    class Pool {
    public:
        static_assert(NumCells % CellsPerAllocation == 0,
                      "NumCells must be a multiple of CellsPerAllocation.");

        Pool() : handle_(new Node_),
                 head_(&handle_.load()->memBlock_[0]){}

        ~Pool() {
            Node_* node = handle_.load();
            while(node) {
                auto temp = node;
                node = node->next_;
                delete temp;
            }
        }

        T* allocate(){
            Cell_* currentHead;
            Cell_* currentNext;

            Node_* currentHandle;
            Node_* newNode;

            // Out of cells to allocate
            if (!head_.load()) {

                // Make a new node
                newNode = new Node_;

                // Point the current Head's next to the head of the new node
                do {
                    currentHead = head_.load();
                    newNode->memBlock_[NumCells-CellsPerAllocation].next_ = currentHead;

                    // The first block is reserved for the current request
                } while(!head_.compare_exchange_strong(currentHead, &newNode->memBlock_[1]));

                // Add the node to the chain
                do {
                    currentHandle = handle_.load();
                    newNode->next_ = currentHandle;
                } while(!handle_.compare_exchange_strong(currentHandle, newNode));

                return reinterpret_cast<T*>(&newNode->memBlock_[0]);
            }

            // Allocate by making head = head.next
            do {
                currentHead = head_.load();
                currentNext = currentHead->next_.load();
            } while (!head_.compare_exchange_strong(currentHead, currentNext));
            return reinterpret_cast<T*>(currentHead);
        }

        void deallocate(void* p) {
            auto newHead = reinterpret_cast<Cell_*>(p);
            Cell_* currentHead;
            do {
                currentHead = head_.load();
                newHead->next_ = currentHead;
            } while (!head_.compare_exchange_strong(currentHead, newHead));
        }

    private:
        union Cell_{
            std::atomic<Cell_*> next_;
            uint8_t val[sizeof(T)];
        };

        struct Node_ {
            Node_() {
                for (uint16_t s=0; s < NumCells/CellsPerAllocation; ++s) {
                    memBlock_[s*CellsPerAllocation].next_
                        .store(&memBlock_[(s+1)*CellsPerAllocation],
                               std::memory_order_relaxed);
                }
                auto& last = memBlock_[NumCells-CellsPerAllocation];
                last.next_.store(nullptr, std::memory_order_relaxed);
            }
            Cell_ memBlock_[NumCells];
            Node_* next_ = nullptr;
        };

        std::atomic<Node_*> handle_;
        std::atomic<Cell_*> head_;
    };
}

#endif
<|endoftext|>


<commit_before>// Copyright (C) 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// the window containing the plot and buttons for supported operations

#include <QtSvg/QtSvg>

#include <QtGui/QToolBar>
#include <QtGui/QPrinter>
#include <QtGui/QPixmap>
#include <QtGui/QPicture>
#include <QtSvg/QSvgGenerator>

#include "CQOptPopulation.h"

#include "UI/copasiui3window.h"
#include "UI/CQMessageBox.h"
#include "UI/qtUtilities.h"
#include "qlayout/CQZoomableView.h"
#include "UI/CColorScale.h"
#include "resourcesUI/CQIconResource.h"
#include "optimization/COptPopulationMethod.h"
#include "optimization/COptTask.h"
#include "optimization/COptProblem.h"
#include "optimization/COptItem.h"

#ifdef DEBUG_UI
#include <QtCore/QtDebug>
#endif

#include <qwt_plot.h>
#include <qwt_scale_engine.h>

#if QWT_VERSION > 0x060000
#include <qwt_plot_renderer.h>
#endif

#if QWT_VERSION < 0x060000
// taken from qwt examples/bode
class PrintFilter: public QwtPlotPrintFilter
{
public:
  PrintFilter() {};

  virtual QFont font(const QFont &f, Item, int) const
  {
    QFont f2 = f;
    f2.setPointSize((int)(f.pointSize() * 0.75));
    return f2;
  }
};
#endif

//-----------------------------------------------------------------------------
CQOptPopulation::CQOptPopulation(COutputHandler * pHandler, CopasiUI3Window * pMainWindow):
  CWindowInterface(),
  mpHandler(pHandler),
  mpMainWindow(pMainWindow),
  mpWindowMenu(NULL),
  mpToolBar(NULL),
  mpaCloseWindow(NULL),
  mCounter(0),
  mDataInitialized(false),
  mGraphInitialized(false),
  initializing(false),
  mNumParameters(0)
{
  this->resize(640, 480);
  this->setWindowTitle("Population Visualization");

#ifndef Darwin
  setWindowIcon(CQIconResource::icon(CQIconResource::copasi));
#endif // not Darwin

  // set up the GUI - the toolbar

  mpGS = new QGraphicsScene(this);
  mpGV = new CQZoomableView(this);
  mpGV->setScene(mpGS);
  this->setCentralWidget(mpGV);

  mpGV->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);

  createActions();
  createMenus();
  createToolBar();

  //setCentralWidget(mpPlot);

  initializing  = true;
  initializing = false;

  addToMainWindow(mpMainWindow);

  connect(this, SIGNAL(updateSignal()), this, SLOT(update()));

}

void CQOptPopulation::createMenus()
{
  QMenu *fileMenu = menuBar()->addMenu("&File");
//  fileMenu->addAction(mpaSaveImage);

  QMenu *viewMenu = menuBar()->addMenu("&View");
//  viewMenu->addAction(mpaShowAll);
//  viewMenu->addSeparator();
  static_cast<CQZoomableView*>(mpGV)->fillZoomMenu(viewMenu);

  // add a place holder menu, to be filled by the main window
  mpWindowMenu = menuBar()->addMenu("&Window");
}
QMenu *CQOptPopulation::getWindowMenu() const
{
  return mpWindowMenu;
}

void CQOptPopulation::createActions()
{
  //mpaToggleLogX = new QAction("Log &X", this);
  //mpaToggleLogX->setCheckable(true);
  //mpaToggleLogX->setToolTip("Toggle x-axis logscale.");
  //connect(mpaToggleLogX, SIGNAL(toggled(bool)), this, SLOT(toggleLogX(bool)));

  mpaCloseWindow = new QAction("Close", this);
  mpaCloseWindow->setObjectName("close");
  mpaCloseWindow->setShortcut(Qt::CTRL + Qt::Key_W);
  connect(mpaCloseWindow, SIGNAL(triggered()), this, SLOT(slotCloseWindow()));
}

void CQOptPopulation::createToolBar()
{
  mpToolBar = addToolBar("plot operations");

//  mpToolBar->addAction(mpaPrint);

//  mpToolBar->addSeparator();

  mpToolBar->addAction(mpaCloseWindow);

  //TODO button icons...
  static_cast<CQZoomableView*>(mpGV)->fillZoomTooBar(mpToolBar);

  setUnifiedTitleAndToolBarOnMac(true);
}

bool CQOptPopulation::initFromSpec()
{
  return false;
}

void CQOptPopulation::setMethod(COptMethod* pMethod)
{
  mpSourceMethod = pMethod;
  mpPopulationMethod = dynamic_cast<COptPopulationMethod*>(pMethod);

  if (mpPopulationMethod == NULL)
  {
    mGraphInitialized = false;
    mDataInitialized = false;
  }
}

void CQOptPopulation::saveToFile(const QString& fileName) const
{
}

void CQOptPopulation::slotSaveData()
{
}

//-----------------------------------------------------------------------------

CQOptPopulation::~CQOptPopulation()
{
  if (mpHandler)
    mpHandler->removeInterface(this);

  if (mpMainWindow != NULL)
    removeFromMainWindow(mpMainWindow);

  pdelete(mpToolBar);
}

bool CQOptPopulation::compile(CObjectInterface::ContainerList listOfContainer)
{
  mObjects.clear();
  bool success = true;

  return success;
};

void CQOptPopulation::separate(const Activity & activity)
{
};

void CQOptPopulation::finish()
{
};

const CObjectInterface::ObjectSet & CQOptPopulation::getObjects() const
{

  return mObjects;
}

void CQOptPopulation::slotCloseWindow()
{
  QWidget::close();
}

void CQOptPopulation::closeEvent(QCloseEvent *closeEvent)
{
  mpMainWindow->removeWindow(this);
  mpHandler->removeInterface(this);
}

void CQOptPopulation::output(const Activity & activity)
{
  if (activity != COutputInterface::Activity(0x08))
    return;

  if (!mDataInitialized)
    {
      if (!mpSourceMethod)
        return;

      CCopasiTask* pTask = dynamic_cast<CCopasiTask*>(mpSourceMethod->getObjectParent());

      if (!pTask)
        return;

      COptProblem* pProblem = dynamic_cast<COptProblem*>(pTask->getProblem());

      if (!pProblem)
        return;

      //now that we have access to the problem we can retrieve the range information for the parameters.
      mNumParameters = pProblem->getOptItemList().size();
      mRangeMax.resize(mNumParameters);
      mRangeMin.resize(mNumParameters);
      mIsLog.resize(mNumParameters);

      unsigned C_INT32 i;

      for (i = 0; i < mNumParameters; ++i)
        {
          COptItem* pOI = pProblem->getOptItemList()[i];
          mRangeMax[i] = *pOI->getUpperBoundValue();
          mRangeMin[i] = *pOI->getLowerBoundValue();

          //guess if log scaling should be used. This could also be retrieved from the method?
          if (mRangeMin[i] > 0.0 && mRangeMax[i] > 0.0 && mRangeMax[i] / mRangeMin[i] > 1000)
            mIsLog[i] = true;
          else
            mIsLog[i] = false;

        }

      mDataInitialized = true;
    }

  //copy the data
  mPopulation = mpPopulationMethod->getPopulation();
  mObjectiveValues = mpPopulationMethod->getObjectiveValues();

  mCounter++;

  emit updateSignal();

}

void CQOptPopulation::update()
{

  if (!mGraphInitialized)
    {
      mpGS->clear();

      QGraphicsRectItem* rect = mpGS->addRect(-0, -0, 1, 1);
      rect->setBrush(QColor(220, 220, 220));

      C_INT32 numProjections = (mNumParameters+1) / 2;
      mShiftX.resize(numProjections);
      mShiftY.resize(numProjections);
      mXIndex.resize(numProjections);
      mYIndex.resize(numProjections);
      mGraphicItems.resize(numProjections+1); //extra space for the combined view

      //if there's more than 2 parameters, create the combined view
      if (mNumParameters>2)
      {
        QGraphicsRectItem* rect = mpGS->addRect(-2.2, 0, 2.1, 2.1);
        rect->setBrush(QColor(230, 230, 250));

        mGraphicItems[numProjections].resize(mPopulation.size());
        unsigned C_INT32 i;
        for (i = 0; i < mPopulation.size(); ++i)
        {
          QGraphicsEllipseItem* ei = mpGS->addEllipse(-2.2,0, 0.05, 0.05);
          mGraphicItems[numProjections][i] = ei;
          ei->setBrush(QColor(10, 100, 10));
          ei->setPen(QPen(QColor(0, 0, 0)));
        }

      }

      C_INT32 j;
      for (j=0; j<numProjections; ++j)
      {
        mShiftX[j] = (j/2)*1.1;
        mShiftY[j] = (j % 2)*1.1 ;
        mXIndex[j] = j*2;
        mYIndex[j] = (j*2+1) % mNumParameters;
        QGraphicsRectItem* rect = mpGS->addRect(mShiftX[j], mShiftY[j], 1, 1);
        rect->setBrush(QColor(240, 240, 240));

        mGraphicItems[j].resize(mPopulation.size());

        unsigned C_INT32 i;
        for (i = 0; i < mPopulation.size(); ++i)
        {

          QGraphicsEllipseItem* ei = mpGS->addEllipse(mShiftX[j], mShiftY[j], 0.05, 0.05);
          mGraphicItems[j][i] = ei;
          ei->setBrush(QColor(10, 100, 10));
          ei->setPen(QPen(QColor(0, 0, 0)));
        }
      }

      static_cast<CQZoomableView*>(mpGV)->slotFitOnScreen();
      mGraphInitialized = true;
    }

  //--------------------------------

  unsigned C_INT32 i;

  //Color scaling
  double tmp_min = 1e300;
  C_INT32 min_index = 0;
  CColorScaleAuto cs;
  cs.startAutomaticParameterCalculation();
  for (i = 0; i<mPopulation.size(); ++i)
  {
    cs.passValue(mObjectiveValues[i]);
    if (mObjectiveValues[i]<tmp_min)
      { tmp_min = mObjectiveValues[i]; min_index = i;}
  }
  cs.finishAutomaticParameterCalculation();
  //std::cout << std::endl;

  for (i=0; i<mPopulation.size(); ++i)
  {

    //first scale the parameters to a unit box
    bool isOnBorder = false;
    std::vector<double> scaled_values; scaled_values.resize(mNumParameters);
    double p0=0; double p1=0; C_INT32 count=0;
    C_INT32 j;
    for (j=0; j<mNumParameters; ++j)
    {
      if (mIsLog[j])
        scaled_values[j] = (log(mPopulation[i]->operator[](j))-log(mRangeMin[j]))/(log(mRangeMax[j])-log(mRangeMin[j])) ;
      else
        scaled_values[j] = (mPopulation[i]->operator[](j)-mRangeMin[j])/(mRangeMax[j]-mRangeMin[j]);

      if (scaled_values[j]<0.01 || scaled_values[j]>0.99)
        isOnBorder=true;

      if (j % 4 == 0)
        {p0 += scaled_values[j]; ++count;}
      if (j % 4 == 1)
        p1 += scaled_values[j];
      if (j % 4 == 2)
        p0 -= scaled_values[j];
      if (j % 4 == 3)
        p1 -= scaled_values[j];
    }

    //now update the graph

    if (mNumParameters>2)
    {
      QGraphicsEllipseItem* gie = dynamic_cast<QGraphicsEllipseItem*>(mGraphicItems[mShiftX.size()][i]);
      if (gie)
      {
        gie->setX((p0/count +1)*1.05  -0.025);
        gie->setY((p1/count +1)*1.05  -0.025);
        gie->setBrush(cs.getColor(mObjectiveValues[i]));
        //highlight parameters on the border of the allowed space
        if (i==min_index)
          gie->setPen(QPen(QColor(0,200,0,200), 0.01));
        else
          gie->setPen(isOnBorder ? QColor(200,0,0,200) : QColor(0,0,0,40));
      }
    }

    for (j=0; j<mShiftX.size(); ++j) //loop over the different projections
    {
      QGraphicsEllipseItem* gie = dynamic_cast<QGraphicsEllipseItem*>(mGraphicItems[j][i]);
      if (gie)
      {
        gie->setX(scaled_values[mXIndex[j]]-0.025);
        gie->setY(scaled_values[mYIndex[j]]-0.025);
        gie->setBrush(cs.getColor(mObjectiveValues[i]));
        //highlight parameters on the border of the allowed space
        if (i==min_index)
          gie->setPen(QPen(QColor(0,200,0,200), 0.01));
        else
          gie->setPen(isOnBorder ? QColor(200,0,0,200) : QColor(0,0,0,40));
      }
    }
  }

}

<commit_msg>- add close action to file menu - move the best member on top of the rest of the population<commit_after>// Copyright (C) 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// the window containing the plot and buttons for supported operations

#include <QtSvg/QtSvg>

#include <QtGui/QToolBar>
#include <QtGui/QPrinter>
#include <QtGui/QPixmap>
#include <QtGui/QPicture>
#include <QtSvg/QSvgGenerator>

#include "CQOptPopulation.h"

#include "UI/copasiui3window.h"
#include "UI/CQMessageBox.h"
#include "UI/qtUtilities.h"
#include "qlayout/CQZoomableView.h"
#include "UI/CColorScale.h"
#include "resourcesUI/CQIconResource.h"
#include "optimization/COptPopulationMethod.h"
#include "optimization/COptTask.h"
#include "optimization/COptProblem.h"
#include "optimization/COptItem.h"

#ifdef DEBUG_UI
#include <QtCore/QtDebug>
#endif

#include <qwt_plot.h>
#include <qwt_scale_engine.h>

#if QWT_VERSION > 0x060000
#include <qwt_plot_renderer.h>
#endif

#if QWT_VERSION < 0x060000
// taken from qwt examples/bode
class PrintFilter: public QwtPlotPrintFilter
{
public:
  PrintFilter() {};

  virtual QFont font(const QFont &f, Item, int) const
  {
    QFont f2 = f;
    f2.setPointSize((int)(f.pointSize() * 0.75));
    return f2;
  }
};
#endif

//-----------------------------------------------------------------------------
CQOptPopulation::CQOptPopulation(COutputHandler * pHandler, CopasiUI3Window * pMainWindow):
  CWindowInterface(),
  mpHandler(pHandler),
  mpMainWindow(pMainWindow),
  mpWindowMenu(NULL),
  mpToolBar(NULL),
  mpaCloseWindow(NULL),
  mCounter(0),
  mDataInitialized(false),
  mGraphInitialized(false),
  initializing(false),
  mNumParameters(0)
{
  this->resize(640, 480);
  this->setWindowTitle("Population Visualization");

#ifndef Darwin
  setWindowIcon(CQIconResource::icon(CQIconResource::copasi));
#endif // not Darwin

  // set up the GUI - the toolbar

  mpGS = new QGraphicsScene(this);
  mpGV = new CQZoomableView(this);
  mpGV->setScene(mpGS);
  this->setCentralWidget(mpGV);

  mpGV->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);

  createActions();
  createMenus();
  createToolBar();

  //setCentralWidget(mpPlot);

  initializing  = true;
  initializing = false;

  addToMainWindow(mpMainWindow);

  connect(this, SIGNAL(updateSignal()), this, SLOT(update()));

}

void CQOptPopulation::createMenus()
{
  QMenu *fileMenu = menuBar()->addMenu("&File");
  fileMenu->addAction(mpaCloseWindow);
//  fileMenu->addAction(mpaSaveImage);

  QMenu *viewMenu = menuBar()->addMenu("&View");
//  viewMenu->addAction(mpaShowAll);
//  viewMenu->addSeparator();
  static_cast<CQZoomableView*>(mpGV)->fillZoomMenu(viewMenu);

  // add a place holder menu, to be filled by the main window
  mpWindowMenu = menuBar()->addMenu("&Window");
}
QMenu *CQOptPopulation::getWindowMenu() const
{
  return mpWindowMenu;
}

void CQOptPopulation::createActions()
{
  //mpaToggleLogX = new QAction("Log &X", this);
  //mpaToggleLogX->setCheckable(true);
  //mpaToggleLogX->setToolTip("Toggle x-axis logscale.");
  //connect(mpaToggleLogX, SIGNAL(toggled(bool)), this, SLOT(toggleLogX(bool)));

  mpaCloseWindow = new QAction("Close", this);
  mpaCloseWindow->setObjectName("close");
  mpaCloseWindow->setShortcut(Qt::CTRL + Qt::Key_W);
  connect(mpaCloseWindow, SIGNAL(triggered()), this, SLOT(slotCloseWindow()));
}

void CQOptPopulation::createToolBar()
{
  mpToolBar = addToolBar("plot operations");

//  mpToolBar->addAction(mpaPrint);

//  mpToolBar->addSeparator();

  mpToolBar->addAction(mpaCloseWindow);

  //TODO button icons...
  static_cast<CQZoomableView*>(mpGV)->fillZoomTooBar(mpToolBar);

  setUnifiedTitleAndToolBarOnMac(true);
}

bool CQOptPopulation::initFromSpec()
{
  return false;
}

void CQOptPopulation::setMethod(COptMethod* pMethod)
{
  mpSourceMethod = pMethod;
  mpPopulationMethod = dynamic_cast<COptPopulationMethod*>(pMethod);

  if (mpPopulationMethod == NULL)
    {
      mGraphInitialized = false;
      mDataInitialized = false;
    }
}

void CQOptPopulation::saveToFile(const QString& fileName) const
{
}

void CQOptPopulation::slotSaveData()
{
}

//-----------------------------------------------------------------------------

CQOptPopulation::~CQOptPopulation()
{
  if (mpHandler)
    mpHandler->removeInterface(this);

  if (mpMainWindow != NULL)
    removeFromMainWindow(mpMainWindow);

  pdelete(mpToolBar);
}

bool CQOptPopulation::compile(CObjectInterface::ContainerList listOfContainer)
{
  mObjects.clear();
  bool success = true;

  return success;
};

void CQOptPopulation::separate(const Activity & activity)
{
};

void CQOptPopulation::finish()
{
};

const CObjectInterface::ObjectSet & CQOptPopulation::getObjects() const
{

  return mObjects;
}

void CQOptPopulation::slotCloseWindow()
{
  QWidget::close();
}

void CQOptPopulation::closeEvent(QCloseEvent *closeEvent)
{
  mpMainWindow->removeWindow(this);
  mpHandler->removeInterface(this);
}

void CQOptPopulation::output(const Activity & activity)
{
  if (activity != COutputInterface::Activity(0x08))
    return;

  if (!mDataInitialized)
    {
      if (!mpSourceMethod)
        return;

      CCopasiTask* pTask = dynamic_cast<CCopasiTask*>(mpSourceMethod->getObjectParent());

      if (!pTask)
        return;

      COptProblem* pProblem = dynamic_cast<COptProblem*>(pTask->getProblem());

      if (!pProblem)
        return;

      //now that we have access to the problem we can retrieve the range information for the parameters.
      mNumParameters = pProblem->getOptItemList().size();
      mRangeMax.resize(mNumParameters);
      mRangeMin.resize(mNumParameters);
      mIsLog.resize(mNumParameters);

      C_INT32 i;

      for (i = 0; i < mNumParameters; ++i)
        {
          COptItem* pOI = pProblem->getOptItemList()[i];
          mRangeMax[i] = *pOI->getUpperBoundValue();
          mRangeMin[i] = *pOI->getLowerBoundValue();

          //guess if log scaling should be used. This could also be retrieved from the method?
          if (mRangeMin[i] > 0.0 && mRangeMax[i] > 0.0 && mRangeMax[i] / mRangeMin[i] > 1000)
            mIsLog[i] = true;
          else
            mIsLog[i] = false;

        }

      mDataInitialized = true;
    }

  //copy the data
  mPopulation = mpPopulationMethod->getPopulation();
  mObjectiveValues = mpPopulationMethod->getObjectiveValues();

  mCounter++;

  emit updateSignal();

}

void CQOptPopulation::update()
{

  if (!mGraphInitialized)
    {
      mpGS->clear();

      QGraphicsRectItem* rect = mpGS->addRect(-0, -0, 1, 1);
      rect->setBrush(QColor(220, 220, 220));

      C_INT32 numProjections = (mNumParameters + 1) / 2;
      mShiftX.resize(numProjections);
      mShiftY.resize(numProjections);
      mXIndex.resize(numProjections);
      mYIndex.resize(numProjections);
      mGraphicItems.resize(numProjections + 1); //extra space for the combined view

      //if there's more than 2 parameters, create the combined view
      if (mNumParameters > 2)
        {
          QGraphicsRectItem* rect = mpGS->addRect(-2.2, 0, 2.1, 2.1);
          rect->setBrush(QColor(230, 230, 250));

          mGraphicItems[numProjections].resize(mPopulation.size());
          unsigned C_INT32 i;

          for (i = 0; i < mPopulation.size(); ++i)
            {
              QGraphicsEllipseItem* ei = mpGS->addEllipse(-2.2, 0, 0.05, 0.05);
              mGraphicItems[numProjections][i] = ei;
              ei->setBrush(QColor(10, 100, 10));
              ei->setPen(QPen(QColor(0, 0, 0)));
            }

        }

      C_INT32 j;

      for (j = 0; j < numProjections; ++j)
        {
          mShiftX[j] = (j / 2) * 1.1;
          mShiftY[j] = (j % 2) * 1.1 ;
          mXIndex[j] = j * 2;
          mYIndex[j] = (j * 2 + 1) % mNumParameters;
          QGraphicsRectItem* rect = mpGS->addRect(mShiftX[j], mShiftY[j], 1, 1);
          rect->setBrush(QColor(240, 240, 240));

          mGraphicItems[j].resize(mPopulation.size());

          unsigned C_INT32 i;

          for (i = 0; i < mPopulation.size(); ++i)
            {

              QGraphicsEllipseItem* ei = mpGS->addEllipse(mShiftX[j], mShiftY[j], 0.05, 0.05);
              mGraphicItems[j][i] = ei;
              ei->setBrush(QColor(10, 100, 10));
              ei->setPen(QPen(QColor(0, 0, 0)));
            }
        }

      static_cast<CQZoomableView*>(mpGV)->slotFitOnScreen();

      mGraphInitialized = true;
    }

  //--------------------------------

  unsigned C_INT32 i;

  //Color scaling
  double tmp_min = 1e300;
  C_INT32 min_index = 0;
  CColorScaleAuto cs;
  cs.startAutomaticParameterCalculation();

  for (i = 0; i < mPopulation.size(); ++i)
    {
      cs.passValue(mObjectiveValues[i]);

      if (mObjectiveValues[i] < tmp_min)
        { tmp_min = mObjectiveValues[i]; min_index = i;}
    }

  cs.finishAutomaticParameterCalculation();
  //std::cout << std::endl;

  for (i = 0; i < mPopulation.size(); ++i)
    {

      //first scale the parameters to a unit box
      bool isOnBorder = false;
      std::vector<double> scaled_values; scaled_values.resize(mNumParameters);
      double p0 = 0; double p1 = 0; C_INT32 count = 0;
      C_INT32 j;

      for (j = 0; j < mNumParameters; ++j)
        {
          if (mIsLog[j])
            scaled_values[j] = (log(mPopulation[i]->operator[](j)) - log(mRangeMin[j])) / (log(mRangeMax[j]) - log(mRangeMin[j])) ;
          else
            scaled_values[j] = (mPopulation[i]->operator[](j) - mRangeMin[j]) / (mRangeMax[j] - mRangeMin[j]);

          if (scaled_values[j] < 0.01 || scaled_values[j] > 0.99)
            isOnBorder = true;

          if (j % 4 == 0)
            {p0 += scaled_values[j]; ++count;}

          if (j % 4 == 1)
            p1 += scaled_values[j];

          if (j % 4 == 2)
            p0 -= scaled_values[j];

          if (j % 4 == 3)
            p1 -= scaled_values[j];
        }

      //now update the graph

      if (mNumParameters > 2)
        {
          QGraphicsEllipseItem* gie = dynamic_cast<QGraphicsEllipseItem*>(mGraphicItems[mShiftX.size()][i]);

          if (gie)
            {
              gie->setX((p0 / count + 1) * 1.05  - 0.025);
              gie->setY((p1 / count + 1) * 1.05  - 0.025);
              gie->setBrush(cs.getColor(mObjectiveValues[i]));

              //highlight parameters on the border of the allowed space
              if (i == min_index)
                {
                  gie->setPen(QPen(QColor(0, 200, 0, 200), 0.01));
                  gie->setZValue(1.0);
                }
              else
                {
                  gie->setPen(isOnBorder ? QColor(200, 0, 0, 200) : QColor(0, 0, 0, 40));
                  gie->setZValue(0.0);
                }
            }
        }

      for (j = 0; j < mShiftX.size(); ++j) //loop over the different projections
        {
          QGraphicsEllipseItem* gie = dynamic_cast<QGraphicsEllipseItem*>(mGraphicItems[j][i]);

          if (gie)
            {
              gie->setX(scaled_values[mXIndex[j]] - 0.025);
              gie->setY(scaled_values[mYIndex[j]] - 0.025);
              gie->setBrush(cs.getColor(mObjectiveValues[i]));

              //highlight parameters on the border of the allowed space
              if (i == min_index)
                {
                  gie->setPen(QPen(QColor(0, 200, 0, 200), 0.01));
                  gie->setZValue(1.0);
                }
              else
                {
                  gie->setPen(isOnBorder ? QColor(200, 0, 0, 200) : QColor(0, 0, 0, 40));
                  gie->setZValue(0.0);
                }
            }
        }
    }

}

<|endoftext|>


<commit_before>//
//  Created by Zinge on 7/4/16.
//
//
#include "ee/twitter/TwitterBridge.hpp"

#include "ee/core/MessageBridge.hpp"
#include "ee/core/Utils.hpp"
#include <ee/nlohmann/json.hpp>

namespace ee {
namespace twitter {
namespace {
// clang-format off
constexpr auto k__initialize        = "twitter_initialize";
constexpr auto k__shareContent      = "twitter_shareContent";
constexpr auto k__shareScreenShot   = "twitter_shareScreenShot";
constexpr auto k__onSuccess         = "twitter_onSuccess";
constexpr auto k__onFailure         = "twitter_onFailure";
constexpr auto k__onCancel          = "twitter_onCancel";
constexpr auto k__key               = "twitter_key";
constexpr auto k__secret            = "twitter_secret";
constexpr auto k__text              = "twitter_text";
constexpr auto k__image             = "twitter_image";
// clang-format on
} // namespace

using Self = Twitter;

Self::Twitter()
    : bridge_(MessageBridge::getInstance()) {
    bridge_.registerHandler(
        [this](const std::string& message) {
            onSuccess();
            return "";
        },
        k__onSuccess);
    bridge_.registerHandler(
        [this](const std::string& message) {
            onFailure();
            return "";
        },
        k__onFailure);
    bridge_.registerHandler(
        [this](const std::string& message) {
            onCancel();
            return "";
        },
        k__onCancel);
}

Self::~Twitter() {
    bridge_.deregisterHandler(k__onSuccess);
    bridge_.deregisterHandler(k__onFailure);
    bridge_.deregisterHandler(k__onCancel);
}

void Self::initialize(const std::string& key, const std::string& secret) {
    nlohmann::json json;
    json[k__key] = key;
    json[k__secret] = secret;
    bridge_.call(k__initialize, json.dump());
}

void Self::setShareResultCallback(const ShareResultCallback& callback) {
    _callback = callback;
}

void Self::shareContent(const std::string& text) {
    _hadCallFailure = false;
    nlohmann::json json;
    json[k__text] = text;
    bridge_.call(k__shareContent, json.dump());
}

void Self::shareScreenShot(const std::string& text, const std::string& image) {
    _hadCallFailure = false;
    nlohmann::json json;
    json[k__text] = text;
    json[k__image] = image;
    bridge_.call(k__shareScreenShot, json.dump());
}

void Self::onSuccess() {
    if (_callback) {
        _hadCallFailure = false;
        _callback(true);
    }
}

void Self::onFailure() {
    if (_callback) {
        _hadCallFailure = true;
        _callback(false);
    }
}

void Self::onCancel() {
    if (_callback) {
        if (!_hadCallFailure) {
            _callback(false);
        }
    }
}

} // namespace twitter
} // namespace ee
<commit_msg>fix format<commit_after>//
//  Created by Zinge on 7/4/16.
//
//
#include "ee/twitter/TwitterBridge.hpp"

#include <ee/nlohmann/json.hpp>

#include "ee/core/MessageBridge.hpp"
#include "ee/core/Utils.hpp"

namespace ee {
namespace twitter {
namespace {
// clang-format off
constexpr auto k__initialize        = "twitter_initialize";
constexpr auto k__shareContent      = "twitter_shareContent";
constexpr auto k__shareScreenShot   = "twitter_shareScreenShot";
constexpr auto k__onSuccess         = "twitter_onSuccess";
constexpr auto k__onFailure         = "twitter_onFailure";
constexpr auto k__onCancel          = "twitter_onCancel";
constexpr auto k__key               = "twitter_key";
constexpr auto k__secret            = "twitter_secret";
constexpr auto k__text              = "twitter_text";
constexpr auto k__image             = "twitter_image";
// clang-format on
} // namespace

using Self = Twitter;

Self::Twitter()
    : bridge_(MessageBridge::getInstance()) {
    bridge_.registerHandler(
        [this](const std::string& message) {
            onSuccess();
            return "";
        },
        k__onSuccess);
    bridge_.registerHandler(
        [this](const std::string& message) {
            onFailure();
            return "";
        },
        k__onFailure);
    bridge_.registerHandler(
        [this](const std::string& message) {
            onCancel();
            return "";
        },
        k__onCancel);
}

Self::~Twitter() {
    bridge_.deregisterHandler(k__onSuccess);
    bridge_.deregisterHandler(k__onFailure);
    bridge_.deregisterHandler(k__onCancel);
}

void Self::initialize(const std::string& key, const std::string& secret) {
    nlohmann::json json;
    json[k__key] = key;
    json[k__secret] = secret;
    bridge_.call(k__initialize, json.dump());
}

void Self::setShareResultCallback(const ShareResultCallback& callback) {
    _callback = callback;
}

void Self::shareContent(const std::string& text) {
    _hadCallFailure = false;
    nlohmann::json json;
    json[k__text] = text;
    bridge_.call(k__shareContent, json.dump());
}

void Self::shareScreenShot(const std::string& text, const std::string& image) {
    _hadCallFailure = false;
    nlohmann::json json;
    json[k__text] = text;
    json[k__image] = image;
    bridge_.call(k__shareScreenShot, json.dump());
}

void Self::onSuccess() {
    if (_callback) {
        _hadCallFailure = false;
        _callback(true);
    }
}

void Self::onFailure() {
    if (_callback) {
        _hadCallFailure = true;
        _callback(false);
    }
}

void Self::onCancel() {
    if (_callback) {
        if (!_hadCallFailure) {
            _callback(false);
        }
    }
}

} // namespace twitter
} // namespace ee
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
// This source file is part of Hect.
//
// Copyright (c) 2015 Colin Hill
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
///////////////////////////////////////////////////////////////////////////////
#include "PhysFSFileSystem.h"

#include <cassert>
#include <physfs.h>

#include "Hect/Core/Configuration.h"
#include "Hect/Core/Exception.h"
#include "Hect/Core/Format.h"
#include "Hect/Core/Logging.h"
#include "Hect/Core/Uncopyable.h"
#include "Hect/IO/FileSystems/PhysFSReadStream.h"
#include "Hect/IO/FileSystems/PhysFSWriteStream.h"

#ifdef HECT_WINDOWS_BUILD
#include <Windows.h>
#include <shlwapi.h>
#include <shlobj.h>
#else
#include <unistd.h>
#endif

using namespace hect;

PhysFSFileSystem::PhysFSFileSystem(int argc, char* const argv[])
{
    (void)argc;

    assert(!_initialized);
    if (!PHYSFS_init(argv[0]))
    {
        throw FatalError(format("Failed to initialize PhysFS: %s", PHYSFS_getLastError()));
    }
    _initialized = true;
}

PhysFSFileSystem::~PhysFSFileSystem()
{
    if (!PHYSFS_deinit())
    {
        throw FatalError(format("Failed to shutdown PhysFS: %s", PHYSFS_getLastError()));
    }
}

Path PhysFSFileSystem::baseDirectory()
{
    return convertPath(PHYSFS_getBaseDir());
}

Path PhysFSFileSystem::workingDirectory()
{
#ifdef HECT_WINDOWS_BUILD
    char path[2048];
    GetCurrentDirectory(2048, path);
    return convertPath(path);
#else
    char* rawPath = get_current_dir_name();
    Path path(rawPath);
    free(rawPath);
    return path;
#endif
}

Path PhysFSFileSystem::userDirectory()
{
    return convertPath(PHYSFS_getUserDir());
}

Path PhysFSFileSystem::applicationDataDirectory()
{
#ifdef HECT_WINDOWS_BUILD
    TCHAR path[MAX_PATH];
    assert(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, path)));
    return convertPath(path);
#else
    return Path();
#endif
}

void PhysFSFileSystem::setWriteDirectory(const Path& path)
{
    if (!PHYSFS_setWriteDir(path.asString().c_str()))
    {
        throw IOError(format("Failed to set write directory to '%s': %s", path.asString().c_str(), PHYSFS_getLastError()));
    }
}

void PhysFSFileSystem::mountArchive(const Path& path, const Path& mountPoint)
{
    const char* pathString = path.asString().c_str();
    const char* mountPointString = mountPoint.asString().c_str();

    if (!PHYSFS_mount(pathString, mountPointString, 0))
    {
        throw IOError(format("Failed to mount archive '%s': %s", pathString, PHYSFS_getLastError()));
    }

    if (mountPoint.empty())
    {
        HECT_INFO(format("Mounted archive '%s'", pathString));
    }
    else
    {
        HECT_INFO(format("Mounted archive '%s' to '%s'", pathString, mountPointString));
    }
}

std::unique_ptr<ReadStream> PhysFSFileSystem::openFileForRead(const Path& path)
{
    return std::unique_ptr<ReadStream>(new PhysFSReadStream(path));
}

std::unique_ptr<WriteStream> PhysFSFileSystem::openFileForWrite(const Path& path)
{
    return std::unique_ptr<WriteStream>(new PhysFSWriteStream(path));
}

void PhysFSFileSystem::createDirectory(const Path& path)
{
    if (!PHYSFS_mkdir(path.asString().c_str()))
    {
        throw IOError(format("Failed to create directory: %s", PHYSFS_getLastError()));
    }
}

std::vector<Path> PhysFSFileSystem::filesInDirectory(const Path& path)
{
    char** paths = PHYSFS_enumerateFiles(path.asString().c_str());

    std::vector<Path> resultingPaths;
    for (char** i = paths; *i != nullptr; ++i)
    {
        resultingPaths.push_back(path + *i);
    }

    PHYSFS_freeList(paths);

    return resultingPaths;
}

void PhysFSFileSystem::remove(const Path& path)
{
    if (!PHYSFS_delete(path.asString().c_str()))
    {
        throw IOError(format("Failed to remove directory: %s", PHYSFS_getLastError()));
    }
}

bool PhysFSFileSystem::exists(const Path& path)
{
    return PHYSFS_exists(path.asString().c_str()) != 0;
}

TimeStamp PhysFSFileSystem::lastModified(const Path& path)
{
    return PHYSFS_getLastModTime(path.asString().c_str());
}

Path PhysFSFileSystem::convertPath(const char* rawPath)
{
    std::string delimiter(PHYSFS_getDirSeparator());
    std::string string(rawPath);

    size_t start = 0;
    while ((start = string.find(delimiter, start)) != std::string::npos)
    {
        string.replace(start, delimiter.length(), "/");
        start += 1;
    }

    return Path(string);
}

bool PhysFSFileSystem::_initialized = false;
<commit_msg>Fixed a forgotten include change needed for last commit<commit_after>///////////////////////////////////////////////////////////////////////////////
// This source file is part of Hect.
//
// Copyright (c) 2015 Colin Hill
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
///////////////////////////////////////////////////////////////////////////////
#include "PhysFSFileSystem.h"

#include <cassert>
#include <physfs.h>

#include "Hect/Core/Configuration.h"
#include "Hect/Core/Exception.h"
#include "Hect/Core/Format.h"
#include "Hect/Core/Logging.h"
#include "Hect/Core/Uncopyable.h"
#include "Hect/IO/Internal/PhysFSReadStream.h"
#include "Hect/IO/Internal/PhysFSWriteStream.h"

#ifdef HECT_WINDOWS_BUILD
#include <Windows.h>
#include <shlwapi.h>
#include <shlobj.h>
#else
#include <unistd.h>
#endif

using namespace hect;

PhysFSFileSystem::PhysFSFileSystem(int argc, char* const argv[])
{
    (void)argc;

    assert(!_initialized);
    if (!PHYSFS_init(argv[0]))
    {
        throw FatalError(format("Failed to initialize PhysFS: %s", PHYSFS_getLastError()));
    }
    _initialized = true;
}

PhysFSFileSystem::~PhysFSFileSystem()
{
    if (!PHYSFS_deinit())
    {
        throw FatalError(format("Failed to shutdown PhysFS: %s", PHYSFS_getLastError()));
    }
}

Path PhysFSFileSystem::baseDirectory()
{
    return convertPath(PHYSFS_getBaseDir());
}

Path PhysFSFileSystem::workingDirectory()
{
#ifdef HECT_WINDOWS_BUILD
    char path[2048];
    GetCurrentDirectory(2048, path);
    return convertPath(path);
#else
    char* rawPath = get_current_dir_name();
    Path path(rawPath);
    free(rawPath);
    return path;
#endif
}

Path PhysFSFileSystem::userDirectory()
{
    return convertPath(PHYSFS_getUserDir());
}

Path PhysFSFileSystem::applicationDataDirectory()
{
#ifdef HECT_WINDOWS_BUILD
    TCHAR path[MAX_PATH];
    assert(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, 0, path)));
    return convertPath(path);
#else
    return Path();
#endif
}

void PhysFSFileSystem::setWriteDirectory(const Path& path)
{
    if (!PHYSFS_setWriteDir(path.asString().c_str()))
    {
        throw IOError(format("Failed to set write directory to '%s': %s", path.asString().c_str(), PHYSFS_getLastError()));
    }
}

void PhysFSFileSystem::mountArchive(const Path& path, const Path& mountPoint)
{
    const char* pathString = path.asString().c_str();
    const char* mountPointString = mountPoint.asString().c_str();

    if (!PHYSFS_mount(pathString, mountPointString, 0))
    {
        throw IOError(format("Failed to mount archive '%s': %s", pathString, PHYSFS_getLastError()));
    }

    if (mountPoint.empty())
    {
        HECT_INFO(format("Mounted archive '%s'", pathString));
    }
    else
    {
        HECT_INFO(format("Mounted archive '%s' to '%s'", pathString, mountPointString));
    }
}

std::unique_ptr<ReadStream> PhysFSFileSystem::openFileForRead(const Path& path)
{
    return std::unique_ptr<ReadStream>(new PhysFSReadStream(path));
}

std::unique_ptr<WriteStream> PhysFSFileSystem::openFileForWrite(const Path& path)
{
    return std::unique_ptr<WriteStream>(new PhysFSWriteStream(path));
}

void PhysFSFileSystem::createDirectory(const Path& path)
{
    if (!PHYSFS_mkdir(path.asString().c_str()))
    {
        throw IOError(format("Failed to create directory: %s", PHYSFS_getLastError()));
    }
}

std::vector<Path> PhysFSFileSystem::filesInDirectory(const Path& path)
{
    char** paths = PHYSFS_enumerateFiles(path.asString().c_str());

    std::vector<Path> resultingPaths;
    for (char** i = paths; *i != nullptr; ++i)
    {
        resultingPaths.push_back(path + *i);
    }

    PHYSFS_freeList(paths);

    return resultingPaths;
}

void PhysFSFileSystem::remove(const Path& path)
{
    if (!PHYSFS_delete(path.asString().c_str()))
    {
        throw IOError(format("Failed to remove directory: %s", PHYSFS_getLastError()));
    }
}

bool PhysFSFileSystem::exists(const Path& path)
{
    return PHYSFS_exists(path.asString().c_str()) != 0;
}

TimeStamp PhysFSFileSystem::lastModified(const Path& path)
{
    return PHYSFS_getLastModTime(path.asString().c_str());
}

Path PhysFSFileSystem::convertPath(const char* rawPath)
{
    std::string delimiter(PHYSFS_getDirSeparator());
    std::string string(rawPath);

    size_t start = 0;
    while ((start = string.find(delimiter, start)) != std::string::npos)
    {
        string.replace(start, delimiter.length(), "/");
        start += 1;
    }

    return Path(string);
}

bool PhysFSFileSystem::_initialized = false;
<|endoftext|>


<commit_before>/*=========================================================================

  Copyright (c) Kitware Inc.
  All rights reserved.

=========================================================================*/
// .SECTION Thanks
// This test was written by Charles Law and Philippe Pebay, Kitware 2012

#include "vtkHyperTreeGrid.h"
#include "vtkHyperTreeGridAxisCut.h"
#include "vtkHyperTreeGridFractalSource.h"
#include "vtkHyperTreeGridGeometry.h"

#include "vtkCamera.h"
#include "vtkCellData.h"
#include "vtkContourFilter.h"
#include "vtkCutter.h"
#include "vtkDataSetWriter.h"
#include "vtkNew.h"
#include "vtkPlane.h"
#include "vtkPolyDataMapper.h"
#include "vtkPolyDataWriter.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkShrinkFilter.h"
#include "vtkUnstructuredGrid.h"
#include "vtkUnstructuredGridWriter.h"
#include "vtkXMLUnstructuredGridWriter.h"

int TestHyperTreeGrid( int argc, char* argv[] )
{
  // Initialize return value of test
  int testIntValue = 0;

  // Dimension of hyper trees
  int dim = 3;

  // Create hyper tree grid source
  vtkHyperTreeGridFractalSource* fractal = vtkHyperTreeGridFractalSource::New();
  fractal->SetMaximumLevel( 3 );
  fractal->DualOn();
  if ( dim == 3 )
    {
    fractal->SetGridSize( 3, 4, 2 );
    }
  else if ( dim == 2 )
    {
    fractal->SetGridSize( 3, 4, 1 );
    }
  else if ( dim == 1 )
    {
    fractal->SetGridSize( 3, 1, 1 );
    }
  else
    {
    return 1;
    }
  fractal->SetDimension( dim );
  fractal->SetAxisBranchFactor( 3 );
  fractal->Update();
  vtkHyperTreeGrid* htGrid = fractal->GetOutput();

  cerr << "# Geometry" << endl;
  vtkNew<vtkHyperTreeGridGeometry> geometry;
  geometry->SetInputConnection( fractal->GetOutputPort() );
  vtkNew<vtkPolyDataWriter> writer4;
  writer4->SetFileName( "./hyperTreeGridGeometry.vtk" );
  writer4->SetInputConnection( geometry->GetOutputPort() );
  writer4->Write();

  cerr << "# Contour" << endl;
  vtkNew<vtkContourFilter> contour;
  contour->SetInputData( htGrid );
  contour->SetNumberOfContours( 2 );
  contour->SetValue( 0, 4. );
  contour->SetValue( 1, 18. );
  contour->SetInputArrayToProcess( 0, 0, 0,
                                   vtkDataObject::FIELD_ASSOCIATION_POINTS,
                                   "Cell Value" );
  vtkNew<vtkPolyDataWriter> writer0;
  writer0->SetFileName( "./hyperTreeGridContour.vtk" );
  writer0->SetInputConnection( contour->GetOutputPort() );
  writer0->Write();

  cerr << "# Shrink" << endl;
  vtkNew<vtkShrinkFilter> shrink;
  shrink->SetInputData( htGrid );
  shrink->SetShrinkFactor( 1. );
  vtkNew<vtkUnstructuredGridWriter> writer1;
  writer1->SetFileName( "./hyperTreeGridShrink.vtk" );
  writer1->SetInputConnection( shrink->GetOutputPort() );
  writer1->Write();

  // Axis-aligned cut works only in 3D for now
  if ( dim == 3 )
    {
    cerr << "# HyperTreeGridAxisCut" << endl;
    vtkNew<vtkHyperTreeGridAxisCut> axisCut;
    axisCut->SetInputConnection( fractal->GetOutputPort() );
    axisCut->SetPlaneNormalAxis( 2 );
    axisCut->SetPlanePosition( .1 );
    vtkNew<vtkPolyDataWriter> writer2;
    writer2->SetFileName( "./hyperTreeGridAxisCut.vtk" );
    writer2->SetInputConnection( axisCut->GetOutputPort() );
    writer2->Write();
    }

  cerr << "# Cut" << endl;
  vtkNew<vtkCutter> cut;
  vtkNew<vtkPlane> plane;
  plane->SetOrigin( .5, .5, .15 );
  plane->SetNormal( 0, 0, 1 );
  cut->SetInputData( htGrid );
  cut->SetCutFunction( plane.GetPointer() );
  vtkNew<vtkPolyDataWriter> writer3;
  writer3->SetFileName( "./hyperTreeGridCut.vtk" );
  writer3->SetInputConnection( cut->GetOutputPort() );
  writer3->Write();

  // Create mapper
  vtkNew<vtkPolyDataMapper> mapper;
  mapper->SetInputConnection( geometry->GetOutputPort() );
  vtkPolyData* pd = geometry->GetOutput();
  mapper->SetScalarRange( pd->GetCellData()->GetScalars()->GetRange() );

  // Create actor
  vtkNew<vtkActor> actor;
  actor->SetMapper( mapper.GetPointer() );

  // Create camera
  double bd[3];
  pd->GetBounds( bd );
  vtkNew<vtkCamera> camera;
  camera->SetClippingRange( 1., 100. );
  camera->SetFocalPoint( pd->GetCenter() );
  camera->SetPosition( -.8 * bd[1], 2.1 * bd[3], -4.8 * bd[5] );

  // Create a renderer, add actors to it
  vtkNew<vtkRenderer> renderer;
  renderer->SetActiveCamera( camera.GetPointer() );
  renderer->SetBackground( 1., 1., 1. );
  renderer->AddActor( actor.GetPointer() );

  // Create a renderWindow
  vtkNew<vtkRenderWindow> renWin;
  renWin->AddRenderer( renderer.GetPointer() );
  renWin->SetSize( 300, 300 );
  renWin->SetMultiSamples( 0 );

  // Create interactor
  vtkNew<vtkRenderWindowInteractor> iren;
  iren->SetRenderWindow( renWin.GetPointer() );

  // Render and test
  renWin->Render();

  int retVal = vtkRegressionTestImage( renWin.GetPointer() );
  if ( retVal == vtkRegressionTester::DO_INTERACTOR )
    {
    iren->Start();
    }

  // Clean up
  //htGrid->Delete();
  fractal->Delete();

  return testIntValue;
}
<commit_msg>A new test with plenty of options for thorough and convenient testing<commit_after>/*=========================================================================

Copyright (c) Kitware Inc.
All rights reserved.

=========================================================================*/
// .SECTION Thanks
// This test was written by Charles Law and Philippe Pebay, Kitware 2012

#include "vtkHyperTreeGrid.h"
#include "vtkHyperTreeGridAxisCut.h"
#include "vtkHyperTreeGridFractalSource.h"
#include "vtkHyperTreeGridGeometry.h"

#include "vtkCellData.h"
#include "vtkContourFilter.h"
#include "vtkCutter.h"
#include "vtkDataSetWriter.h"
#include "vtkNew.h"
#include "vtkPlane.h"
#include "vtkPolyDataWriter.h"
#include "vtkRenderer.h"
#include "vtkShrinkFilter.h"
#include "vtkUnstructuredGrid.h"
#include "vtkUnstructuredGridWriter.h"
#include "vtkXMLUnstructuredGridWriter.h"

#include "vtksys/CommandLineArguments.hxx"

int TestHyperTreeGrid( int argc, char* argv[] )
{
  // Default parameters and options
  int dim = 3;
  int nX = 3;
  int nY = 4;
  int nZ = 2;
  bool skipAxisCut = false;
  bool skipContour = false;
  bool skipCut = false;
  bool skipGeometry = false;
  bool skipShrink = false;

  // Initialize command line argument parser
  vtksys::CommandLineArguments clArgs;
  clArgs.Initialize( argc, argv );
  clArgs.StoreUnusedArguments( false );

  // Parse command line parameters and options
  clArgs.AddArgument("--dimension",
                     vtksys::CommandLineArguments::SPACE_ARGUMENT,
                     &dim, "Dimension of hyper tree grid");

  clArgs.AddArgument("--grid-size-X",
                     vtksys::CommandLineArguments::SPACE_ARGUMENT,
                     &nX, "Size of hyper tree grid in X direction");

  clArgs.AddArgument("--grid-size-Y",
                     vtksys::CommandLineArguments::SPACE_ARGUMENT,
                     &nY, "Size of hyper tree grid in Y direction");

  clArgs.AddArgument("--grid-size-Z",
                     vtksys::CommandLineArguments::SPACE_ARGUMENT,
                     &nZ, "Size of hyper tree grid in Z direction");

  clArgs.AddArgument("--skip-Axis-Cut",
                     vtksys::CommandLineArguments::NO_ARGUMENT,
                     &skipAxisCut, "Skip axis cut filter");

  clArgs.AddArgument("--skip-Contour",
                     vtksys::CommandLineArguments::NO_ARGUMENT,
                     &skipAxisCut, "Skip contour filter");

  clArgs.AddArgument("--skip-Cut",
                     vtksys::CommandLineArguments::NO_ARGUMENT,
                     &skipCut, "Skip cut filter");

  clArgs.AddArgument("--skip-Geometry",
                     vtksys::CommandLineArguments::NO_ARGUMENT,
                     &skipGeometry, "Skip geometry filter");

  clArgs.AddArgument("--skip-Shrink",
                     vtksys::CommandLineArguments::NO_ARGUMENT,
                     &skipShrink, "Skip shrink filter");

  // If incorrect arguments were provided, provide some help and terminate in error.
  if ( ! clArgs.Parse() )
    {
    cerr << "Usage: "
         << clArgs.GetHelp()
         << "\n";
    }

  // Initialize return value of test
  int testIntValue = 0;

  // Create hyper tree grid source
  vtkHyperTreeGridFractalSource* fractal = vtkHyperTreeGridFractalSource::New();
  fractal->SetMaximumLevel( 3 );
  fractal->DualOn();
  if ( dim == 3 )
    {
    fractal->SetGridSize( nX, nY, nZ );
    }
  else if ( dim == 2 )
    {
    fractal->SetGridSize( nX, nY, 1 );
    }
  else if ( dim == 1 )
    {
    fractal->SetGridSize( nX, 1, 1 );
    }
  else
    {
    return 1;
    }
  fractal->SetDimension( dim );
  fractal->SetAxisBranchFactor( 3 );
  fractal->Update();
  vtkHyperTreeGrid* htGrid = fractal->GetOutput();

  if ( ! skipGeometry )
    {
    cerr << "# Geometry" << endl;
    vtkNew<vtkHyperTreeGridGeometry> geometry;
    geometry->SetInputConnection( fractal->GetOutputPort() );
    vtkNew<vtkPolyDataWriter> writer4;
    writer4->SetFileName( "./hyperTreeGridGeometry.vtk" );
    writer4->SetInputConnection( geometry->GetOutputPort() );
    writer4->Write();
    }

  if ( ! skipContour )
    {
    cerr << "# Contour" << endl;
    vtkNew<vtkContourFilter> contour;
    contour->SetInputData( htGrid );
    contour->SetNumberOfContours( 2 );
    contour->SetValue( 0, 4. );
    contour->SetValue( 1, 18. );
    contour->SetInputArrayToProcess( 0, 0, 0,
                                     vtkDataObject::FIELD_ASSOCIATION_POINTS,
                                     "Cell Value" );
    vtkNew<vtkPolyDataWriter> writer0;
    writer0->SetFileName( "./hyperTreeGridContour.vtk" );
    writer0->SetInputConnection( contour->GetOutputPort() );
    writer0->Write();
    }

  if ( ! skipShrink )
    {
    cerr << "# Shrink" << endl;
    vtkNew<vtkShrinkFilter> shrink;
    shrink->SetInputData( htGrid );
    shrink->SetShrinkFactor( 1. );
    vtkNew<vtkUnstructuredGridWriter> writer1;
    writer1->SetFileName( "./hyperTreeGridShrink.vtk" );
    writer1->SetInputConnection( shrink->GetOutputPort() );
    writer1->Write();
    }

  if ( ! skipAxisCut )
    {
    // Axis-aligned cut works only in 3D for now
    if ( dim == 3 )
      {
      cerr << "# HyperTreeGridAxisCut" << endl;
      vtkNew<vtkHyperTreeGridAxisCut> axisCut;
      axisCut->SetInputConnection( fractal->GetOutputPort() );
      axisCut->SetPlaneNormalAxis( 2 );
      axisCut->SetPlanePosition( .1 );
      vtkNew<vtkPolyDataWriter> writer2;
      writer2->SetFileName( "./hyperTreeGridAxisCut.vtk" );
      writer2->SetInputConnection( axisCut->GetOutputPort() );
      writer2->Write();
      }
    }

  if ( ! skipCut )
    {
    cerr << "# Cut" << endl;
    vtkNew<vtkCutter> cut;
    vtkNew<vtkPlane> plane;
    plane->SetOrigin( .5, .5, .15 );
    plane->SetNormal( 0, 0, 1 );
    cut->SetInputData( htGrid );
    cut->SetCutFunction( plane.GetPointer() );
    vtkNew<vtkPolyDataWriter> writer3;
    writer3->SetFileName( "./hyperTreeGridCut.vtk" );
    writer3->SetInputConnection( cut->GetOutputPort() );
    writer3->Write();
    }

  // Clean up
  fractal->Delete();

  return testIntValue;
}
<|endoftext|>


<commit_before>#include "sceneLayer.h"

namespace Tangram {

    short SceneLayer::s_layerCount = 0;

    SceneLayer::SceneLayer(const std::vector<SceneLayer*>&& _subLayers, const StyleParamMap&& _styleParamMap, const std::string _name, Filter* _filter) :
        m_subLayers(std::move(_subLayers)), m_styleParams(std::move(_styleParamMap)), m_name(_name), m_filter(_filter) {

        m_id = 1 << (s_layerCount++);

    }

    SceneLayer::~SceneLayer() {
        for(auto& subLayer : m_subLayers) {
            delete subLayer;
        }
        m_subLayers.clear();
        delete m_filter;
    }
}

<commit_msg>Fix SceneLayer ID value<commit_after>#include "sceneLayer.h"

namespace Tangram {

    short SceneLayer::s_layerCount = 0;

    SceneLayer::SceneLayer(const std::vector<SceneLayer*>&& _subLayers, const StyleParamMap&& _styleParamMap, const std::string _name, Filter* _filter) :
        m_subLayers(std::move(_subLayers)), m_styleParams(std::move(_styleParamMap)), m_name(_name), m_filter(_filter) {

        m_id = s_layerCount++;

    }

    SceneLayer::~SceneLayer() {
        for(auto& subLayer : m_subLayers) {
            delete subLayer;
        }
        m_subLayers.clear();
        delete m_filter;
    }
}

<|endoftext|>


<commit_before>// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include "stdafx.h"
#include <vector>
#include <boost/bind.hpp>
#include "connection.h"
#include "http_server/request_handler.h"
#include "plugin/logger.h"

//namespace {
//using namespace AIMPControlPlugin::PluginLogger;
//ModuleLoggerType& logger()
//    { return getLogManager().getModuleLogger<Http::Server>(); }
//}

namespace Http {

template <typename SocketT>
Connection<SocketT>::Connection(boost::asio::io_service& io_service, RequestHandler& handler)
    :
    strand_(io_service),
    socket_(io_service),
    request_handler_(handler)
{
    try {
        BOOST_LOG_SEV(logger(), info) << "Creating connection to host " << socket().remote_endpoint();
    } catch (boost::system::system_error&) {
        BOOST_LOG_SEV(logger(), info) << "Creating connection.";
    }
}

template <typename SocketT>
Connection<SocketT>::~Connection()
{
    try {
        BOOST_LOG_SEV(logger(), info) << "Destroying connection to host " << socket().remote_endpoint();
    } catch (boost::system::system_error&) {
        BOOST_LOG_SEV(logger(), info) << "Destroying connection.";
    }
}

template <typename SocketT>
SocketT& Connection<SocketT>::socket()
{
    return socket_;
}

template <typename SocketT>
void Connection<SocketT>::start()
{
    read_some_to_buffer();
}

template <typename SocketT>
void Connection<SocketT>::read_some_to_buffer()
{
    socket_.async_read_some(boost::asio::buffer(buffer_),
                            strand_.wrap(boost::bind(&Connection<SocketT>::handle_read,
                                                     shared_from_this(),
                                                     boost::asio::placeholders::error,
                                                     boost::asio::placeholders::bytes_transferred
                                                     )
                                         )
                            );
}

template <typename SocketT>
void Connection<SocketT>::write_reply_content()
{
    boost::asio::async_write(socket_,
                             reply_.to_buffers(),
                             strand_.wrap(boost::bind(&Connection<SocketT>::handle_write,
                                                      shared_from_this(),
                                                      boost::asio::placeholders::error
                                                      )
                                          )
                             );
}

template <typename SocketT>
void Connection<SocketT>::handle_read(const boost::system::error_code& e,
                             std::size_t bytes_transferred)
{
    if (!e) {
        boost::tribool result;
        boost::tie(result, boost::tuples::ignore) = request_parser_.parse(request_,
                                                                          buffer_.data(),
                                                                          buffer_.data() + bytes_transferred
                                                                          );
        if (result) {
            ICometDelayedConnection_ptr comet_connection( new CometDelayedConnection<SocketT>( shared_from_this() ) );
            bool reply_immediately = request_handler_.handle_request(request_, reply_, comet_connection);
            if (reply_immediately) {
                write_reply_content();
            }
        } else if (!result) {
            reply_ = Reply::stock_reply(Reply::bad_request);
            write_reply_content();
        } else {
            read_some_to_buffer();
        }
    } else {
        // BOOST_LOG_SEV(logger(), debug) << "Connection<SocketT>::handle_read(): failed to read data. Reason: " << e.message();
    }

    // If an error occurs then no new asynchronous operations are started. This
    // means that all shared_ptr references to the connection object will
    // disappear and the object will be destroyed automatically after this
    // handler returns. The Connection class's destructor closes the socket.
}

template <typename SocketT>
void Connection<SocketT>::handle_write(const boost::system::error_code& e)
{
    if (!e) {
        // Initiate graceful connection closure.
        boost::system::error_code ignored_ec;
        socket_.shutdown(SocketT::shutdown_both, ignored_ec);
    }

    // No new asynchronous operations are started. This means that all shared_ptr
    // references to the connection object will disappear and the object will be
    // destroyed automatically after this handler returns. The Connection class's
    // destructor closes the socket.
}

template <typename SocketT>
void CometDelayedConnection<SocketT>::sendResponse(DelayedResponseSender_ptr comet_http_response_sender)
{
    BOOST_LOG_SEV(logger(), debug) << "CometDelayedConnection::sendResponse to " << connection_->socket().remote_endpoint();
    boost::asio::async_write( connection_->socket(),
                              comet_http_response_sender->get_reply().to_buffers(),
                              connection_->strand_.wrap(boost::bind(&CometDelayedConnection<SocketT>::handle_write,
                                                                    shared_from_this(),
                                                                    comet_http_response_sender,
                                                                    boost::asio::placeholders::error
                                                                    )
                                                         )
                             );
}

template <typename SocketT>
void CometDelayedConnection<SocketT>::handle_write(DelayedResponseSender_ptr comet_http_response_sender, const boost::system::error_code& e)
{
    if (!e) {
        BOOST_LOG_SEV(logger(), debug) << "CometDelayedConnection::success sending response to " << connection_->socket().remote_endpoint();
        // Initiate graceful connection closure.
        boost::system::error_code ignored_ec;
        connection_->socket().shutdown(SocketT::shutdown_both, ignored_ec);
    } else {
        BOOST_LOG_SEV(logger(), debug) << "CometDelayedConnection::fail to send response to "
                                       << connection_->socket_.remote_endpoint()
                                       << ". Reason: " << e.message();
    }

    // No new asynchronous operations are started. This means that all shared_ptr
    // references to the CometDelayedConnection object will disappear and the object will be
    // destroyed automatically after this handler returns. The Connection class's
    // destructor closes the socket.
}

} // namespace Http
<commit_msg>cosmetic<commit_after>// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include "stdafx.h"
#include <vector>
#include <boost/bind.hpp>
#include "connection.h"
#include "http_server/request_handler.h"
#include "plugin/logger.h"

//namespace {
//using namespace AIMPControlPlugin::PluginLogger;
//ModuleLoggerType& logger()
//    { return getLogManager().getModuleLogger<Http::Server>(); }
//}

namespace Http {

template <typename SocketT>
Connection<SocketT>::Connection(boost::asio::io_service& io_service, RequestHandler& handler)
    :
    strand_(io_service),
    socket_(io_service),
    request_handler_(handler)
{
    try {
        BOOST_LOG_SEV(logger(), info) << "Creating connection to host " << socket().remote_endpoint();
    } catch (boost::system::system_error&) {
        BOOST_LOG_SEV(logger(), info) << "Creating connection.";
    }
}

template <typename SocketT>
Connection<SocketT>::~Connection()
{
    try {
        BOOST_LOG_SEV(logger(), info) << "Destroying connection to host " << socket().remote_endpoint();
    } catch (boost::system::system_error&) {
        BOOST_LOG_SEV(logger(), info) << "Destroying connection.";
    }
}

template <typename SocketT>
SocketT& Connection<SocketT>::socket()
{
    return socket_;
}

template <typename SocketT>
void Connection<SocketT>::start()
{
    read_some_to_buffer();
}

template <typename SocketT>
void Connection<SocketT>::read_some_to_buffer()
{
    socket_.async_read_some(boost::asio::buffer(buffer_),
                            strand_.wrap(boost::bind(&Connection<SocketT>::handle_read,
                                                     shared_from_this(),
                                                     boost::asio::placeholders::error,
                                                     boost::asio::placeholders::bytes_transferred
                                                     )
                                         )
                            );
}

template <typename SocketT>
void Connection<SocketT>::write_reply_content()
{
    boost::asio::async_write(socket_,
                             reply_.to_buffers(),
                             strand_.wrap(boost::bind(&Connection<SocketT>::handle_write,
                                                      shared_from_this(),
                                                      boost::asio::placeholders::error
                                                      )
                                          )
                             );
}

template <typename SocketT>
void Connection<SocketT>::handle_read(const boost::system::error_code& e,
                                      std::size_t bytes_transferred)
{
    if (!e) {
        boost::tribool result;
        boost::tie(result, boost::tuples::ignore) = request_parser_.parse(request_,
                                                                          buffer_.data(),
                                                                          buffer_.data() + bytes_transferred
                                                                          );
        if (result) {
            ICometDelayedConnection_ptr comet_connection( new CometDelayedConnection<SocketT>( shared_from_this() ) );
            bool reply_immediately = request_handler_.handle_request(request_, reply_, comet_connection);
            if (reply_immediately) {
                write_reply_content();
            }
        } else if (!result) {
            reply_ = Reply::stock_reply(Reply::bad_request);
            write_reply_content();
        } else {
            read_some_to_buffer();
        }
    } else {
        // BOOST_LOG_SEV(logger(), debug) << "Connection<SocketT>::handle_read(): failed to read data. Reason: " << e.message();
    }

    // If an error occurs then no new asynchronous operations are started. This
    // means that all shared_ptr references to the connection object will
    // disappear and the object will be destroyed automatically after this
    // handler returns. The Connection class's destructor closes the socket.
}

template <typename SocketT>
void Connection<SocketT>::handle_write(const boost::system::error_code& e)
{
    if (!e) {
        // Initiate graceful connection closure.
        boost::system::error_code ignored_ec;
        socket_.shutdown(SocketT::shutdown_both, ignored_ec);
    }

    // No new asynchronous operations are started. This means that all shared_ptr
    // references to the connection object will disappear and the object will be
    // destroyed automatically after this handler returns. The Connection class's
    // destructor closes the socket.
}

template <typename SocketT>
void CometDelayedConnection<SocketT>::sendResponse(DelayedResponseSender_ptr comet_http_response_sender)
{
    BOOST_LOG_SEV(logger(), debug) << "CometDelayedConnection::sendResponse to " << connection_->socket().remote_endpoint();
    boost::asio::async_write( connection_->socket(),
                              comet_http_response_sender->get_reply().to_buffers(),
                              connection_->strand_.wrap(boost::bind(&CometDelayedConnection<SocketT>::handle_write,
                                                                    shared_from_this(),
                                                                    comet_http_response_sender,
                                                                    boost::asio::placeholders::error
                                                                    )
                                                         )
                             );
}

template <typename SocketT>
void CometDelayedConnection<SocketT>::handle_write(DelayedResponseSender_ptr comet_http_response_sender, const boost::system::error_code& e)
{
    if (!e) {
        BOOST_LOG_SEV(logger(), debug) << "CometDelayedConnection::success sending response to " << connection_->socket().remote_endpoint();
        // Initiate graceful connection closure.
        boost::system::error_code ignored_ec;
        connection_->socket().shutdown(SocketT::shutdown_both, ignored_ec);
    } else {
        BOOST_LOG_SEV(logger(), debug) << "CometDelayedConnection::fail to send response to "
                                       << connection_->socket_.remote_endpoint()
                                       << ". Reason: " << e.message();
    }

    // No new asynchronous operations are started. This means that all shared_ptr
    // references to the CometDelayedConnection object will disappear and the object will be
    // destroyed automatically after this handler returns. The Connection class's
    // destructor closes the socket.
}

} // namespace Http
<|endoftext|>


<commit_before>#include <allegro.h>
#include "allegro-joystick.h"

void AllegroJoystick::poll(){
    ::poll_joystick();
}

JoystickInput AllegroJoystick::readAll(){
    JoystickInput input;
    JOYSTICK_INFO * info = &joy[0];
    switch(info->num_buttons > 4 ? 4 : info->num_buttons){
        case 4: input.button4 = info->button[3].b;
        case 3: input.button3 = info->button[2].b;
        case 2: input.button2 = info->button[1].b;
        case 1: input.button1 = info->button[0].b;
        case 0: {
            break;
        }
    }

    for (int stick = 0; stick < info->num_sticks; stick++){
        if (info->stick[stick].num_axis > 0){
            int position = info->stick[stick].axis[0].pos;
            if (position < 0){
                input.left = true;
            } else if (position > 0){
                input.right = true;
            }
        }
        if (info->stick[stick].num_axis > 1){
            int position = info->stick[stick].axis[1].pos;
            if (position < 0){
                input.up = true;
            } else if (position > 0){
                input.down = true;
            }
        }
    }

    return input;
}

bool AllegroJoystick::pressed(){
    JoystickInput input = readAll();
    return input.up || input.down || input.left || input.right ||
           input.button1 || input.button2 || input.button3 || input.button4;
}

AllegroJoystick::~AllegroJoystick(){
}

AllegroJoystick::AllegroJoystick(){
}
<commit_msg>store current joystick in a local variable<commit_after>#include <allegro.h>
#include "allegro-joystick.h"

void AllegroJoystick::poll(){
    ::poll_joystick();
}

JoystickInput AllegroJoystick::readAll(){
    JoystickInput input;
    JOYSTICK_INFO * info = &joy[0];
    switch(info->num_buttons > 4 ? 4 : info->num_buttons){
        case 4: input.button4 = info->button[3].b;
        case 3: input.button3 = info->button[2].b;
        case 2: input.button2 = info->button[1].b;
        case 1: input.button1 = info->button[0].b;
        case 0: {
            break;
        }
    }

    for (int stick = 0; stick < info->num_sticks; stick++){
        JOYSTICK_STICK_INFO * this_stick = &info->stick[stick];
        if (this_stick->num_axis > 0){
            int position = this_stick->axis[0].pos;
            if (position < 0){
                input.left = true;
            } else if (position > 0){
                input.right = true;
            }
        }
        if (this_stick->num_axis > 1){
            int position = this_stick->axis[1].pos;
            if (position < 0){
                input.up = true;
            } else if (position > 0){
                input.down = true;
            }
        }
    }

    return input;
}

bool AllegroJoystick::pressed(){
    JoystickInput input = readAll();
    return input.up || input.down || input.left || input.right ||
           input.button1 || input.button2 || input.button3 || input.button4;
}

AllegroJoystick::~AllegroJoystick(){
}

AllegroJoystick::AllegroJoystick(){
}
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Facebook, Inc.
 *
 * 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.
 */

#include <thrift/lib/cpp/concurrency/PosixThreadFactory.h>
#include <thrift/lib/cpp/concurrency/Exception.h>
#include <thrift/lib/cpp/concurrency/Mutex.h>
#include <thrift/lib/cpp/thrift_config.h>

#if GOOGLE_PERFTOOLS_REGISTER_THREAD
#  include <google/base/Profiler.h>
#endif

#include <assert.h>
#include <pthread.h>
#include <sys/resource.h>

#include <iostream>

#include <glog/logging.h>

namespace apache { namespace thrift { namespace concurrency {

using std::shared_ptr;
using std::weak_ptr;

const PosixThreadFactory::POLICY PosixThreadFactory::kDefaultPolicy;
const PosixThreadFactory::PRIORITY PosixThreadFactory::kDefaultPriority;
const int PosixThreadFactory::kDefaultStackSizeMB;

// global set to track the ids of live threads.
std::set<pthread_t> liveThreadIds;
Mutex liveThreadIdMutex;

void addLiveThreadId(pthread_t tid) {
  Guard g(liveThreadIdMutex);
  liveThreadIds.insert(tid);
}

void removeLiveThreadId(pthread_t tid) {
  Guard g(liveThreadIdMutex);
  liveThreadIds.erase(tid);
}

void getLiveThreadIds(std::set<pthread_t>* tids) {
  Guard g(liveThreadIdMutex);
  for (std::set<pthread_t>::const_iterator it = liveThreadIds.begin();
       it != liveThreadIds.end(); ++it) {
    tids->insert(*it);
  }
}

// push our given name upstream into pthreads
bool PthreadThread::updateName() {
  if (!pthread_ || name_.empty()) {
    return false;
  }
  return setPosixThreadName(pthread_, name_);
}

PthreadThread::PthreadThread(int policy, int priority, int stackSize,
                             bool detached,
                             shared_ptr<Runnable> runnable) :
  pthread_(pthread_t_init),
  state_(uninitialized),
  policy_(policy),
  priority_(priority),
  stackSize_(stackSize),
  detached_(detached) {

  this->Thread::runnable(runnable);
}

PthreadThread::~PthreadThread() {
  /* Nothing references this thread, if is is not detached, do a join
     now, otherwise the thread-id and, possibly, other resources will
     be leaked. */
  if(!detached_) {
    try {
      join();
    } catch(...) {
      // We're really hosed.
    }
  }
  removeLiveThreadId(pthread_);
}

void PthreadThread::start() {
  Guard g(stateLock_);

  if (state_ != uninitialized) {
    return;
  }

  pthread_attr_t thread_attr;
  if (pthread_attr_init(&thread_attr) != 0) {
      throw SystemResourceException("pthread_attr_init failed");
  }

  if(pthread_attr_setdetachstate(&thread_attr,
                                 detached_ ?
                                 PTHREAD_CREATE_DETACHED :
                                 PTHREAD_CREATE_JOINABLE) != 0) {
      throw SystemResourceException("pthread_attr_setdetachstate failed");
  }

  // Set thread stack size
  if (pthread_attr_setstacksize(&thread_attr, MB * stackSize_) != 0) {
    throw SystemResourceException("pthread_attr_setstacksize failed");
  }

  // Create reference
  shared_ptr<PthreadThread>* selfRef = new shared_ptr<PthreadThread>();
  *selfRef = self_.lock();

  state_ = starting;

  if (pthread_create(&pthread_, &thread_attr, threadMain, (void*)selfRef) != 0) {
    throw SystemResourceException("pthread_create failed");
  }

  // Now that we have a thread, we can set the name we've been given, if any.
  updateName();
  addLiveThreadId(pthread_);
}

void PthreadThread::join() {
  Guard g(stateLock_);
  STATE join_state = state_;

  if (!detached_ && join_state != uninitialized) {
    void* ignore;
    /* XXX
       If join fails it is most likely due to the fact
       that the last reference was the thread itself and cannot
       join.  This results in leaked threads and will eventually
       cause the process to run out of thread resources.
       We're beyond the point of throwing an exception.  Not clear how
       best to handle this. */
    int res = pthread_join(pthread_, &ignore);
    detached_ = (res == 0);
    if (res != 0) {
      LOG(ERROR) << "PthreadThread::join(): fail with code " << res;
    }
  } else {
    LOG(ERROR) << "PthreadThread::join(): detached thread";
  }
}

Thread::id_t PthreadThread::getId() {
#ifdef _MSC_VER
  return (Thread::id_t)pthread_getw32threadid_np(pthread_);
#else
  return (Thread::id_t)pthread_;
#endif
}

shared_ptr<Runnable> PthreadThread::runnable() const {
  return Thread::runnable();
}

void PthreadThread::runnable(shared_ptr<Runnable> value) {
  Thread::runnable(value);
}

void PthreadThread::weakRef(shared_ptr<PthreadThread> self) {
  assert(self.get() == this);
  self_ = weak_ptr<PthreadThread>(self);
}

bool PthreadThread::setName(const std::string& name) {
  Guard g(stateLock_);
  name_ = name;
  return updateName();
}

void* PthreadThread::threadMain(void* arg) {
  shared_ptr<PthreadThread> thread = *(shared_ptr<PthreadThread>*)arg;
  delete reinterpret_cast<shared_ptr<PthreadThread>*>(arg);

  if (thread == nullptr) {
    return (void*)0;
  }

#if GOOGLE_PERFTOOLS_REGISTER_THREAD
  ProfilerRegisterThread();
#endif
  // Using pthread_attr_setschedparam() at thread creation doesn't actually
  // change the new thread's priority for some reason... Other people on the
  // 'net also complain about it.  The solution is to set priority inside the
  // new thread's threadMain.
  if (thread->policy_ == SCHED_FIFO || thread->policy_ == SCHED_RR) {
    struct sched_param sched_param;
    sched_param.sched_priority = thread->priority_;
    int err =
      pthread_setschedparam(pthread_self(), thread->policy_, &sched_param);
    if (err != 0) {
      VLOG(1) << "pthread_setschedparam failed (are you root?) with error " <<
        err, strerror(err);
    }
  } else if (thread->policy_ == SCHED_OTHER) {
    if (setpriority(PRIO_PROCESS, 0, thread->priority_) != 0) {
      VLOG(1) << "setpriority failed (are you root?) with error " <<
        errno, strerror(errno);
    }
  }

  thread->runnable()->run();

  return (void*)0;
}

int PosixThreadFactory::Impl::toPthreadPolicy(POLICY policy) {
  switch (policy) {
  case OTHER:
    return SCHED_OTHER;
  case FIFO:
    return SCHED_FIFO;
  case ROUND_ROBIN:
    return SCHED_RR;
  }
  return SCHED_OTHER;
}

int PosixThreadFactory::Impl::toPthreadPriority(
    POLICY policy, PRIORITY priority) {
  int pthread_policy = toPthreadPolicy(policy);
  int min_priority = 0;
  int max_priority = 0;
  if (pthread_policy == SCHED_FIFO || pthread_policy == SCHED_RR) {
#ifdef THRIFT_HAVE_SCHED_GET_PRIORITY_MIN
    min_priority = sched_get_priority_min(pthread_policy);
#endif
#ifdef THRIFT_HAVE_SCHED_GET_PRIORITY_MAX
    max_priority = sched_get_priority_max(pthread_policy);
#endif
  } else if (pthread_policy == SCHED_OTHER) {
    min_priority = 19;
    max_priority = -20;
  }
  int quanta = HIGHEST - LOWEST;
  float stepsperquanta = (float)(max_priority - min_priority) / quanta;

  if (priority <= HIGHEST) {
    return (int)(min_priority + stepsperquanta * priority);
  } else {
    // should never get here for priority increments.
    assert(false);
    return (int)(min_priority + stepsperquanta * NORMAL);
  }
}

PosixThreadFactory::Impl::Impl(
  POLICY policy, PRIORITY priority, int stackSize, DetachState detached) :
  policy_(policy),
  priority_(priority),
  stackSize_(stackSize),
  detached_(detached) {}

shared_ptr<Thread> PosixThreadFactory::Impl::newThread(
    const shared_ptr<Runnable>& runnable,
    PosixThreadFactory::DetachState detachState) const {
  shared_ptr<PthreadThread> result = shared_ptr<PthreadThread>(
      new PthreadThread(toPthreadPolicy(policy_),
                        toPthreadPriority(policy_, priority_), stackSize_,
                        detachState == DETACHED, runnable));
  result->weakRef(result);
  runnable->thread(result);
  return result;
}

int PosixThreadFactory::Impl::getStackSize() const {
  return stackSize_;
}

void PosixThreadFactory::Impl::setStackSize(int value) {
  stackSize_ = value;
}

PosixThreadFactory::PRIORITY PosixThreadFactory::Impl::getPriority()
    const {
  return priority_;
}

/**
 * Sets priority.
 *
 *  XXX
 *  Need to handle incremental priorities properly.
 */
void PosixThreadFactory::Impl::setPriority(PRIORITY value) {
  priority_ = value;
}

PosixThreadFactory::DetachState PosixThreadFactory::Impl::getDetachState()
    const {
  return detached_;
}

void PosixThreadFactory::Impl::setDetachState(DetachState value) {
  detached_ = value;
}

Thread::id_t PosixThreadFactory::Impl::getCurrentThreadId() const {
#ifdef _MSC_VER
  return (Thread::id_t)pthread_getw32threadid_np(pthread_self());
#else
  return (Thread::id_t)pthread_self();
#endif
}

PosixThreadFactory::PosixThreadFactory(POLICY policy, PRIORITY priority,
                                       int stackSize, bool detached)
  : impl_(new PosixThreadFactory::Impl(policy, priority, stackSize,
                                       detached ? DETACHED : ATTACHED)) {
}

PosixThreadFactory::PosixThreadFactory(DetachState detached)
  : impl_(new PosixThreadFactory::Impl(kDefaultPolicy, kDefaultPriority,
                                       kDefaultStackSizeMB, detached)) {
}

shared_ptr<Thread> PosixThreadFactory::newThread(
    const shared_ptr<Runnable>& runnable) const {
  return impl_->newThread(runnable, impl_->getDetachState());
}

shared_ptr<Thread> PosixThreadFactory::newThread(
    const shared_ptr<Runnable>& runnable,
    DetachState detachState) const {
  return impl_->newThread(runnable, detachState);
}

int PosixThreadFactory::getStackSize() const { return impl_->getStackSize(); }

void PosixThreadFactory::setStackSize(int value) { impl_->setStackSize(value); }

PosixThreadFactory::PRIORITY PosixThreadFactory::getPriority() const { return impl_->getPriority(); }

void PosixThreadFactory::setPriority(PosixThreadFactory::PRIORITY value) { impl_->setPriority(value); }

bool PosixThreadFactory::isDetached() const {
  return impl_->getDetachState() == DETACHED;
}

void PosixThreadFactory::setDetached(bool value) {
  impl_->setDetachState(value ? DETACHED : ATTACHED);
}

void PosixThreadFactory::setDetached(DetachState value) {
  impl_->setDetachState(value);
}

Thread::id_t PosixThreadFactory::getCurrentThreadId() const { return impl_->getCurrentThreadId(); }

}}} // apache::thrift::concurrency
<commit_msg>Don't you just love it when you forget to add a file to the diff?<commit_after>/*
 * Copyright 2014 Facebook, Inc.
 *
 * 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.
 */

#include <thrift/lib/cpp/concurrency/PosixThreadFactory.h>
#include <thrift/lib/cpp/concurrency/Exception.h>
#include <thrift/lib/cpp/concurrency/Mutex.h>
#include <thrift/lib/cpp/thrift_config.h>

#if GOOGLE_PERFTOOLS_REGISTER_THREAD
#  include <google/base/Profiler.h>
#endif

#include <assert.h>
#include <pthread.h>
#include <sys/resource.h>

#include <iostream>

#include <glog/logging.h>

namespace apache { namespace thrift { namespace concurrency {

using std::shared_ptr;
using std::weak_ptr;

const PosixThreadFactory::POLICY PosixThreadFactory::kDefaultPolicy;
const PosixThreadFactory::PRIORITY PosixThreadFactory::kDefaultPriority;
const int PosixThreadFactory::kDefaultStackSizeMB;

// global set to track the ids of live threads.
std::set<pthread_t> liveThreadIds;
Mutex liveThreadIdMutex;

void addLiveThreadId(pthread_t tid) {
  Guard g(liveThreadIdMutex);
  liveThreadIds.insert(tid);
}

void removeLiveThreadId(pthread_t tid) {
  Guard g(liveThreadIdMutex);
  liveThreadIds.erase(tid);
}

void getLiveThreadIds(std::set<pthread_t>* tids) {
  Guard g(liveThreadIdMutex);
  for (std::set<pthread_t>::const_iterator it = liveThreadIds.begin();
       it != liveThreadIds.end(); ++it) {
    tids->insert(*it);
  }
}

// push our given name upstream into pthreads
bool PthreadThread::updateName() {
  if (!pthread_ || name_.empty()) {
    return false;
  }
  return setPosixThreadName(pthread_, name_);
}

PthreadThread::PthreadThread(int policy, int priority, int stackSize,
                             bool detached,
                             shared_ptr<Runnable> runnable) :
  pthread_(pthread_zero),
  state_(uninitialized),
  policy_(policy),
  priority_(priority),
  stackSize_(stackSize),
  detached_(detached) {

  this->Thread::runnable(runnable);
}

PthreadThread::~PthreadThread() {
  /* Nothing references this thread, if is is not detached, do a join
     now, otherwise the thread-id and, possibly, other resources will
     be leaked. */
  if(!detached_) {
    try {
      join();
    } catch(...) {
      // We're really hosed.
    }
  }
  removeLiveThreadId(pthread_);
}

void PthreadThread::start() {
  Guard g(stateLock_);

  if (state_ != uninitialized) {
    return;
  }

  pthread_attr_t thread_attr;
  if (pthread_attr_init(&thread_attr) != 0) {
      throw SystemResourceException("pthread_attr_init failed");
  }

  if(pthread_attr_setdetachstate(&thread_attr,
                                 detached_ ?
                                 PTHREAD_CREATE_DETACHED :
                                 PTHREAD_CREATE_JOINABLE) != 0) {
      throw SystemResourceException("pthread_attr_setdetachstate failed");
  }

  // Set thread stack size
  if (pthread_attr_setstacksize(&thread_attr, MB * stackSize_) != 0) {
    throw SystemResourceException("pthread_attr_setstacksize failed");
  }

  // Create reference
  shared_ptr<PthreadThread>* selfRef = new shared_ptr<PthreadThread>();
  *selfRef = self_.lock();

  state_ = starting;

  if (pthread_create(&pthread_, &thread_attr, threadMain, (void*)selfRef) != 0) {
    throw SystemResourceException("pthread_create failed");
  }

  // Now that we have a thread, we can set the name we've been given, if any.
  updateName();
  addLiveThreadId(pthread_);
}

void PthreadThread::join() {
  Guard g(stateLock_);
  STATE join_state = state_;

  if (!detached_ && join_state != uninitialized) {
    void* ignore;
    /* XXX
       If join fails it is most likely due to the fact
       that the last reference was the thread itself and cannot
       join.  This results in leaked threads and will eventually
       cause the process to run out of thread resources.
       We're beyond the point of throwing an exception.  Not clear how
       best to handle this. */
    int res = pthread_join(pthread_, &ignore);
    detached_ = (res == 0);
    if (res != 0) {
      LOG(ERROR) << "PthreadThread::join(): fail with code " << res;
    }
  } else {
    LOG(ERROR) << "PthreadThread::join(): detached thread";
  }
}

Thread::id_t PthreadThread::getId() {
#ifdef _MSC_VER
  return (Thread::id_t)pthread_getw32threadid_np(pthread_);
#else
  return (Thread::id_t)pthread_;
#endif
}

shared_ptr<Runnable> PthreadThread::runnable() const {
  return Thread::runnable();
}

void PthreadThread::runnable(shared_ptr<Runnable> value) {
  Thread::runnable(value);
}

void PthreadThread::weakRef(shared_ptr<PthreadThread> self) {
  assert(self.get() == this);
  self_ = weak_ptr<PthreadThread>(self);
}

bool PthreadThread::setName(const std::string& name) {
  Guard g(stateLock_);
  name_ = name;
  return updateName();
}

void* PthreadThread::threadMain(void* arg) {
  shared_ptr<PthreadThread> thread = *(shared_ptr<PthreadThread>*)arg;
  delete reinterpret_cast<shared_ptr<PthreadThread>*>(arg);

  if (thread == nullptr) {
    return (void*)0;
  }

#if GOOGLE_PERFTOOLS_REGISTER_THREAD
  ProfilerRegisterThread();
#endif
  // Using pthread_attr_setschedparam() at thread creation doesn't actually
  // change the new thread's priority for some reason... Other people on the
  // 'net also complain about it.  The solution is to set priority inside the
  // new thread's threadMain.
  if (thread->policy_ == SCHED_FIFO || thread->policy_ == SCHED_RR) {
    struct sched_param sched_param;
    sched_param.sched_priority = thread->priority_;
    int err =
      pthread_setschedparam(pthread_self(), thread->policy_, &sched_param);
    if (err != 0) {
      VLOG(1) << "pthread_setschedparam failed (are you root?) with error " <<
        err, strerror(err);
    }
  } else if (thread->policy_ == SCHED_OTHER) {
    if (setpriority(PRIO_PROCESS, 0, thread->priority_) != 0) {
      VLOG(1) << "setpriority failed (are you root?) with error " <<
        errno, strerror(errno);
    }
  }

  thread->runnable()->run();

  return (void*)0;
}

int PosixThreadFactory::Impl::toPthreadPolicy(POLICY policy) {
  switch (policy) {
  case OTHER:
    return SCHED_OTHER;
  case FIFO:
    return SCHED_FIFO;
  case ROUND_ROBIN:
    return SCHED_RR;
  }
  return SCHED_OTHER;
}

int PosixThreadFactory::Impl::toPthreadPriority(
    POLICY policy, PRIORITY priority) {
  int pthread_policy = toPthreadPolicy(policy);
  int min_priority = 0;
  int max_priority = 0;
  if (pthread_policy == SCHED_FIFO || pthread_policy == SCHED_RR) {
#ifdef THRIFT_HAVE_SCHED_GET_PRIORITY_MIN
    min_priority = sched_get_priority_min(pthread_policy);
#endif
#ifdef THRIFT_HAVE_SCHED_GET_PRIORITY_MAX
    max_priority = sched_get_priority_max(pthread_policy);
#endif
  } else if (pthread_policy == SCHED_OTHER) {
    min_priority = 19;
    max_priority = -20;
  }
  int quanta = HIGHEST - LOWEST;
  float stepsperquanta = (float)(max_priority - min_priority) / quanta;

  if (priority <= HIGHEST) {
    return (int)(min_priority + stepsperquanta * priority);
  } else {
    // should never get here for priority increments.
    assert(false);
    return (int)(min_priority + stepsperquanta * NORMAL);
  }
}

PosixThreadFactory::Impl::Impl(
  POLICY policy, PRIORITY priority, int stackSize, DetachState detached) :
  policy_(policy),
  priority_(priority),
  stackSize_(stackSize),
  detached_(detached) {}

shared_ptr<Thread> PosixThreadFactory::Impl::newThread(
    const shared_ptr<Runnable>& runnable,
    PosixThreadFactory::DetachState detachState) const {
  shared_ptr<PthreadThread> result = shared_ptr<PthreadThread>(
      new PthreadThread(toPthreadPolicy(policy_),
                        toPthreadPriority(policy_, priority_), stackSize_,
                        detachState == DETACHED, runnable));
  result->weakRef(result);
  runnable->thread(result);
  return result;
}

int PosixThreadFactory::Impl::getStackSize() const {
  return stackSize_;
}

void PosixThreadFactory::Impl::setStackSize(int value) {
  stackSize_ = value;
}

PosixThreadFactory::PRIORITY PosixThreadFactory::Impl::getPriority()
    const {
  return priority_;
}

/**
 * Sets priority.
 *
 *  XXX
 *  Need to handle incremental priorities properly.
 */
void PosixThreadFactory::Impl::setPriority(PRIORITY value) {
  priority_ = value;
}

PosixThreadFactory::DetachState PosixThreadFactory::Impl::getDetachState()
    const {
  return detached_;
}

void PosixThreadFactory::Impl::setDetachState(DetachState value) {
  detached_ = value;
}

Thread::id_t PosixThreadFactory::Impl::getCurrentThreadId() const {
#ifdef _MSC_VER
  return (Thread::id_t)pthread_getw32threadid_np(pthread_self());
#else
  return (Thread::id_t)pthread_self();
#endif
}

PosixThreadFactory::PosixThreadFactory(POLICY policy, PRIORITY priority,
                                       int stackSize, bool detached)
  : impl_(new PosixThreadFactory::Impl(policy, priority, stackSize,
                                       detached ? DETACHED : ATTACHED)) {
}

PosixThreadFactory::PosixThreadFactory(DetachState detached)
  : impl_(new PosixThreadFactory::Impl(kDefaultPolicy, kDefaultPriority,
                                       kDefaultStackSizeMB, detached)) {
}

shared_ptr<Thread> PosixThreadFactory::newThread(
    const shared_ptr<Runnable>& runnable) const {
  return impl_->newThread(runnable, impl_->getDetachState());
}

shared_ptr<Thread> PosixThreadFactory::newThread(
    const shared_ptr<Runnable>& runnable,
    DetachState detachState) const {
  return impl_->newThread(runnable, detachState);
}

int PosixThreadFactory::getStackSize() const { return impl_->getStackSize(); }

void PosixThreadFactory::setStackSize(int value) { impl_->setStackSize(value); }

PosixThreadFactory::PRIORITY PosixThreadFactory::getPriority() const { return impl_->getPriority(); }

void PosixThreadFactory::setPriority(PosixThreadFactory::PRIORITY value) { impl_->setPriority(value); }

bool PosixThreadFactory::isDetached() const {
  return impl_->getDetachState() == DETACHED;
}

void PosixThreadFactory::setDetached(bool value) {
  impl_->setDetachState(value ? DETACHED : ATTACHED);
}

void PosixThreadFactory::setDetached(DetachState value) {
  impl_->setDetachState(value);
}

Thread::id_t PosixThreadFactory::getCurrentThreadId() const { return impl_->getCurrentThreadId(); }

}}} // apache::thrift::concurrency
<|endoftext|>