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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkAddImageFilterTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/

#include <itkImage.h>
#include <itkAddImageFilter.h>
#include <itkImageRegionIteratorWithIndex.h>

int main()
{

  // Define the dimension of the images
  const unsigned int myDimension = 3;

  // Declare the types of the images
  typedef itk::Image<float, myDimension>  myImageType1;
  typedef itk::Image<float, myDimension>  myImageType2;
  typedef itk::Image<float, myDimension>  myImageType3;

  // Declare the type of the index to access images
  typedef itk::Index<myDimension>         myIndexType;

  // Declare the type of the size
  typedef itk::Size<myDimension>          mySizeType;

  // Declare the type of the Region
  typedef itk::ImageRegion<myDimension>        myRegionType;

  // Create two images
  myImageType1::Pointer inputImageA  = myImageType1::New();
  myImageType2::Pointer inputImageB  = myImageType2::New();

  // Define their size, and start index
  mySizeType size;
  size[0] = 2;
  size[1] = 2;
  size[2] = 2;

  myIndexType start;
  start[0] = 0;
  start[1] = 0;
  start[2] = 0;

  myRegionType region;
  region.SetIndex( start );
  region.SetSize( size );

  // Initialize Image A
  inputImageA->SetLargestPossibleRegion( region );
  inputImageA->SetBufferedRegion( region );
  inputImageA->SetRequestedRegion( region );
  inputImageA->Allocate();

  // Initialize Image B
  inputImageB->SetLargestPossibleRegion( region );
  inputImageB->SetBufferedRegion( region );
  inputImageB->SetRequestedRegion( region );
  inputImageB->Allocate();

  // Declare Iterator types apropriated for each image
  typedef itk::ImageRegionIteratorWithIndex<myImageType1>  myIteratorType1;
  typedef itk::ImageRegionIteratorWithIndex<myImageType2>  myIteratorType2;
  typedef itk::ImageRegionIteratorWithIndex<myImageType3>  myIteratorType3;

  // Create one iterator for Image A (this is a light object)
  myIteratorType1 it1( inputImageA, inputImageA->GetBufferedRegion() );

  // Initialize the content of Image A
  std::cout << "First operand " << std::endl;
  while( !it1.IsAtEnd() )
  {
    it1.Set( 2.0 );
    std::cout << it1.Get() << std::endl;
    ++it1;
  }

  // Create one iterator for Image B (this is a light object)
  myIteratorType2 it2( inputImageB, inputImageB->GetBufferedRegion() );

  // Initialize the content of Image B
  std::cout << "Second operand " << std::endl;
  while( !it2.IsAtEnd() )
  {
    it2.Set( 3.0 );
    std::cout << it2.Get() << std::endl;
    ++it2;
  }

  // Declare the type for the ADD filter
  typedef itk::AddImageFilter<
                                myImageType1,
                                myImageType2,
                                myImageType3  >       myFilterType;

  // Create an ADD Filter
  myFilterType::Pointer filter = myFilterType::New();

  // Connect the input images
  filter->SetInput1( inputImageA );
  filter->SetInput2( inputImageB );

  // Get the Smart Pointer to the Filter Output
  myImageType3::Pointer outputImage = filter->GetOutput();

  // Execute the filter
  filter->Update();

  // Create an iterator for going through the image output
  myIteratorType3 it3(outputImage, outputImage->GetBufferedRegion());

  //  Print the content of the result image
  std::cout << " Result " << std::endl;
  while( !it3.IsAtEnd() )
  {
    std::cout << it3.Get() << std::endl;
    ++it3;
  }

  // All objects should be automatically destroyed at this point
  return 0;

}

<commit_msg>FIX: typedefs for Pointers added. Declaration of AddImageFilter fixed.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkAddImageFilterTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/

#include <itkImage.h>
#include <itkAddImageFilter.h>
#include <itkImageRegionIteratorWithIndex.h>

int main()
{

  // Define the dimension of the images
  const unsigned int myDimension = 3;

  // Declare the types of the images
  typedef itk::Image<float, myDimension>  myImageType1;
  typedef itk::Image<float, myDimension>  myImageType2;
  typedef itk::Image<float, myDimension>  myImageType3;

  // Declare the type of the index to access images
  typedef itk::Index<myDimension>         myIndexType;

  // Declare the type of the size
  typedef itk::Size<myDimension>          mySizeType;

  // Declare the type of the Region
  typedef itk::ImageRegion<myDimension>        myRegionType;

  // Declare the type for the ADD filter
  typedef itk::AddImageFilter<
                                myImageType1,
                                myImageType2,
                                myImageType3  >       myFilterType;

  // Declare the pointers to images
  typedef myImageType1::Pointer   myImageType1Pointer;
  typedef myImageType2::Pointer   myImageType2Pointer;
  typedef myImageType3::Pointer   myImageType3Pointer;
  typedef myFilterType::Pointer   myFilterTypePointer;

  // Create two images
  myImageType1Pointer inputImageA  = myImageType1::New();
  myImageType2Pointer inputImageB  = myImageType2::New();

  // Define their size, and start index
  mySizeType size;
  size[0] = 2;
  size[1] = 2;
  size[2] = 2;

  myIndexType start;
  start[0] = 0;
  start[1] = 0;
  start[2] = 0;

  myRegionType region;
  region.SetIndex( start );
  region.SetSize( size );

  // Initialize Image A
  inputImageA->SetLargestPossibleRegion( region );
  inputImageA->SetBufferedRegion( region );
  inputImageA->SetRequestedRegion( region );
  inputImageA->Allocate();

  // Initialize Image B
  inputImageB->SetLargestPossibleRegion( region );
  inputImageB->SetBufferedRegion( region );
  inputImageB->SetRequestedRegion( region );
  inputImageB->Allocate();

  // Declare Iterator types apropriated for each image
  typedef itk::ImageRegionIteratorWithIndex<myImageType1>  myIteratorType1;
  typedef itk::ImageRegionIteratorWithIndex<myImageType2>  myIteratorType2;
  typedef itk::ImageRegionIteratorWithIndex<myImageType3>  myIteratorType3;

  // Create one iterator for Image A (this is a light object)
  myIteratorType1 it1( inputImageA, inputImageA->GetBufferedRegion() );

  // Initialize the content of Image A
  std::cout << "First operand " << std::endl;
  while( !it1.IsAtEnd() )
  {
    it1.Set( 2.0 );
    std::cout << it1.Get() << std::endl;
    ++it1;
  }

  // Create one iterator for Image B (this is a light object)
  myIteratorType2 it2( inputImageB, inputImageB->GetBufferedRegion() );

  // Initialize the content of Image B
  std::cout << "Second operand " << std::endl;
  while( !it2.IsAtEnd() )
  {
    it2.Set( 3.0 );
    std::cout << it2.Get() << std::endl;
    ++it2;
  }

  // Create an ADD Filter
  myFilterTypePointer filter = myFilterType::New();

  // Connect the input images
  filter->SetInput1( inputImageA );
  filter->SetInput2( inputImageB );

  // Get the Smart Pointer to the Filter Output
  myImageType3Pointer outputImage = filter->GetOutput();

  // Execute the filter
  filter->Update();

  // Create an iterator for going through the image output
  myIteratorType3 it3(outputImage, outputImage->GetBufferedRegion());

  //  Print the content of the result image
  std::cout << " Result " << std::endl;
  while( !it3.IsAtEnd() )
  {
    std::cout << it3.Get() << std::endl;
    ++it3;
  }

  // All objects should be automatically destroyed at this point
  return 0;

}

<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkStructuredPointsToPolyDataFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include "vtkStructuredPointsToPolyDataFilter.h"

//----------------------------------------------------------------------------
// Specify the input data or filter.
void vtkStructuredPointsToPolyDataFilter::SetInput(vtkImageData *input)
{
  this->vtkProcessObject::SetNthInput(0, input);
}

//----------------------------------------------------------------------------
// Specify the input data or filter.
vtkImageData *vtkStructuredPointsToPolyDataFilter::GetInput()
{
  if (this->NumberOfInputs < 1)
    {
    return NULL;
    }

  return (vtkImageData *)(this->Inputs[0]);
}

//----------------------------------------------------------------------------
void vtkStructuredPointsToPolyDataFilter::ComputeInputUpdateExtents(
                                                        vtkDataObject *output)
{
  this->vtkPolyDataSource::ComputeInputUpdateExtents(output);

  // assume that we cannot handle more than the requested extent.
  this->GetInput()->RequestExactExtentOn();
}
<commit_msg>ERR: NULL input caused trouble<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkStructuredPointsToPolyDataFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include "vtkStructuredPointsToPolyDataFilter.h"

//----------------------------------------------------------------------------
// Specify the input data or filter.
void vtkStructuredPointsToPolyDataFilter::SetInput(vtkImageData *input)
{
  this->vtkProcessObject::SetNthInput(0, input);
}

//----------------------------------------------------------------------------
// Specify the input data or filter.
vtkImageData *vtkStructuredPointsToPolyDataFilter::GetInput()
{
  if (this->NumberOfInputs < 1)
    {
    return NULL;
    }

  return (vtkImageData *)(this->Inputs[0]);
}

//----------------------------------------------------------------------------
void vtkStructuredPointsToPolyDataFilter::ComputeInputUpdateExtents(
                                                        vtkDataObject *output)
{
  this->vtkPolyDataSource::ComputeInputUpdateExtents(output);

  if (!this->GetInput())
    {
    return;
    }
  // assume that we cannot handle more than the requested extent.
  this->GetInput()->RequestExactExtentOn();
}
<|endoftext|>


<commit_before>#include <experimental/coroutine>

#include "promise.hpp"
#include "suspendable.hpp"

#include <asyncio/config.hpp>

USING_ASYNNCIO_NAMESPACE;

void done_suspend::await_suspend(std::experimental::coroutine_handle<>) const
    noexcept {
  promise->set_done();
}<commit_msg>minor changes<commit_after>#include <experimental/coroutine>

#include "promise.hpp"
#include "suspendable.hpp"

#include <asyncio/config.hpp>

USING_ASYNNCIO_NAMESPACE;
using namespace std::experimental;

void done_suspend::await_suspend(coroutine_handle<>) const noexcept {
  promise->set_done();
}<|endoftext|>


<commit_before>#include "battery.h"

RazorPlugin* init(RazorBar* panel, QWidget* parent, const QString & name)
{
    Battery * ret = new Battery(panel, parent, name);
    Q_ASSERT(ret);
    return ret;
}

Battery::Battery(RazorBar * panel, QWidget * parent, const QString & name)
    : RazorPluginSquare(panel, parent, name)
{
    info = new QSystemDeviceInfo(this);
    gui = new QLabel(this);
    gui->setScaledContents(true);
    mainLayout()->addWidget(gui);

    connect(info, SIGNAL(batteryLevelChanged(int)),
            this, SLOT(batteryLevelChanged(int)));
    connect(info, SIGNAL(batteryStatusChanged(QSystemDeviceInfo::BatteryStatus)),
            this, SLOT(batteryStatusChanged(QSystemDeviceInfo::BatteryStatus)));
    connect(info, SIGNAL(powerStateChanged(QSystemDeviceInfo::PowerState)),
            this, SLOT(powerStateChanged(QSystemDeviceInfo::PowerState)));

    handleIcon();
}

void Battery::batteryLevelChanged(int level)
{
    Q_UNUSED(level);
    handleIcon();
}

void Battery::batteryStatusChanged(QSystemDeviceInfo::BatteryStatus status)
{
    if (status == QSystemDeviceInfo::BatteryCritical)
    {
        QMessageBox::warning(this, tr("Battery Critical Level"),
                             tr("Battery level is less than 3%."));
    }
}

void Battery::powerStateChanged(QSystemDeviceInfo::PowerState state)
{
    Q_UNUSED(state);
    handleIcon();
}

void Battery::handleIcon()
{
    QString charging;
    QString fileLevel;
    int level = info->batteryLevel();

    switch (info->currentPowerState())
    {
        case QSystemDeviceInfo::UnknownPower:
            qDebug() << "Battery: UnknownPower";
        case QSystemDeviceInfo::WallPower:
            gui->setPixmap(QPixmap(":/battery-missing.png"));
            gui->setToolTip(tr("No battery found"));
            return; // exit here
            break;
        case QSystemDeviceInfo::WallPowerChargingBattery:
            charging = "-charging";
            break;
        case QSystemDeviceInfo::BatteryPower:
            break;
    }

    if (level <= 100 && level > 80)
        fileLevel = "100";
    else if (level <= 80 && level > 60)
        fileLevel = "80";
    else if (level <= 60 && level > 40)
        fileLevel = "60";
    else if (level <= 40 && level > 3)
        fileLevel = "40";
    else
        fileLevel = "low";

    QString icon(":/battery%1-%2");
    gui->setPixmap(icon.arg(charging, fileLevel));
    gui->setToolTip(tr("Charged: %1 %").arg(level));
}
<commit_msg>battery icon names fixed<commit_after>#include "battery.h"

RazorPlugin* init(RazorBar* panel, QWidget* parent, const QString & name)
{
    Battery * ret = new Battery(panel, parent, name);
    Q_ASSERT(ret);
    return ret;
}

Battery::Battery(RazorBar * panel, QWidget * parent, const QString & name)
    : RazorPluginSquare(panel, parent, name)
{
    info = new QSystemDeviceInfo(this);
    gui = new QLabel(this);
    gui->setScaledContents(true);
    mainLayout()->addWidget(gui);

    connect(info, SIGNAL(batteryLevelChanged(int)),
            this, SLOT(batteryLevelChanged(int)));
    connect(info, SIGNAL(batteryStatusChanged(QSystemDeviceInfo::BatteryStatus)),
            this, SLOT(batteryStatusChanged(QSystemDeviceInfo::BatteryStatus)));
    connect(info, SIGNAL(powerStateChanged(QSystemDeviceInfo::PowerState)),
            this, SLOT(powerStateChanged(QSystemDeviceInfo::PowerState)));

    handleIcon();
}

void Battery::batteryLevelChanged(int level)
{
    Q_UNUSED(level);
    handleIcon();
}

void Battery::batteryStatusChanged(QSystemDeviceInfo::BatteryStatus status)
{
    if (status == QSystemDeviceInfo::BatteryCritical)
    {
        QMessageBox::warning(this, tr("Battery Critical Level"),
                             tr("Battery level is less than 3%."));
    }
}

void Battery::powerStateChanged(QSystemDeviceInfo::PowerState state)
{
    Q_UNUSED(state);
    handleIcon();
}

void Battery::handleIcon()
{
    QString charging;
    QString fileLevel;
    int level = info->batteryLevel();

    switch (info->currentPowerState())
    {
        case QSystemDeviceInfo::UnknownPower:
            qDebug() << "Battery: UnknownPower";
        case QSystemDeviceInfo::WallPower:
            gui->setPixmap(QPixmap(":/battery-missing.png"));
            gui->setToolTip(tr("No battery found"));
            return; // exit here
            break;
        case QSystemDeviceInfo::WallPowerChargingBattery:
            charging = "-charging";
            break;
        case QSystemDeviceInfo::BatteryPower:
            break;
    }

    if (level <= 100 && level > 80)
        fileLevel = "100";
    else if (level <= 80 && level > 60)
        fileLevel = "080";
    else if (level <= 60 && level > 40)
        fileLevel = "060";
    else if (level <= 40 && level > 3)
        fileLevel = "040";
    else
        fileLevel = "low";

    QString icon(":/battery%1-%2");
    gui->setPixmap(icon.arg(charging, fileLevel));
    gui->setToolTip(tr("Charged: %1 %").arg(level));
}
<|endoftext|>


<commit_before>/* this program takes in Tetra code and produces a parse tree which allows it
 * to be tested and visualized.  It now produces a structured text dump.
 * TODO add graphical output with graphiz or similar */

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include "tetra.hpp"
#include "parser.gen.hpp"

using namespace std;

/* returns a string representation of a node type */
string stringType(Node* node) {
  stringstream ss;

  switch (node->node_type) {
    /* statements and groups */
    case NODE_FUNCTION: return "FUNC " + node->stringval;
    case NODE_FUNCTION_LIST: return "FUNCS";
    case NODE_STATEMENT: return "STMTS";
    case NODE_FORMAL_PARAM: return "PARAM: " + node->stringval;
    case NODE_FORMAL_PARAM_LIST: return "PARAMS";
    case NODE_PASS: return "PASS";
    case NODE_RETURN: return "RETURN";
    case NODE_BREAK: return "BREAK";
    case NODE_CONTINUE: return "CONTINUE";
    case NODE_IF: return "IF";
    case NODE_WHILE: return "WHILE";
    case NODE_ELIF: return "ELIF";
    case NODE_ELIF_CHAIN: return "ELIF CHAIN";
    case NODE_ELIF_CLAUSE: return "ELIF CLAUSE";

    /* operators */
    case NODE_ASSIGN: return "=";
    case NODE_OR: return "or";
    case NODE_AND: return "and";
    case NODE_LT: return "<";
    case NODE_LTE: return "<=";
    case NODE_GT: return ">";
    case NODE_GTE: return ">=";
    case NODE_EQ: return "==";
    case NODE_NEQ: return "!=";
    case NODE_NOT: return "not";
    case NODE_BITXOR: return "^";
    case NODE_BITAND: return "&";
    case NODE_BITOR: return "|";
    case NODE_BITNOT: return "~";
    case NODE_SHIFTL: return "<<";
    case NODE_SHIFTR: return ">>";
    case NODE_PLUS: return "+";
    case NODE_MINUS: return "-";
    case NODE_TIMES: return "*";
    case NODE_DIVIDE: return "/";
    case NODE_MODULUS: return "%";
    case NODE_EXP: return "EXP";

    /* functions */
    case NODE_FUNCALL: return "CALL: " + node->stringval;
    case NODE_ACTUAL_PARAM_LIST: return "ARGS";

    /* leafs */
    case NODE_INTVAL:
      ss << "INT: " << node->intval;
      return ss.str( );
    case NODE_REALVAL:
      ss << "REAL: " << node->realval;
      return ss.str( );
    case NODE_STRINGVAL: return "\\\"" +  node->stringval + "\\\"";
    case NODE_IDENTIFIER: return "ID " + node->stringval;
    case NODE_BOOLVAL:
      if (node->boolval) {
        return "true";
      } else {
        return "false";
      }
    default:
      throw Error("Unsupported node type!");
  }
}

/* generate a unique label for a node */
string genId( ) {
  static int count = 0;
  count++;
  stringstream ss;
  ss << "n" << count;
  return ss.str( );
}

void dumpNodeGraphviz(Node* node, string id, ofstream& out) {
  if (!node) {
    return;
  }

  /* dump the node designator */
  out << "  " << id << "[label=\"";
  out << stringType(node);
  out << "\"];\n";

  /* for each child */
  for (unsigned int i = 0; i < node->children.size( ); i++) {
    /* generate a new id */
    string childId = genId( );

    /* dump the connection */
    out << "  " << id << " -> " << childId << ";\n";

    /* dump the child itself */
    dumpNodeGraphviz(node->children[i], childId, out);
  }
}

void dumpTreeGraphviz(Node* node) {
  ofstream out("tree.gv");
  out << "digraph G {\n";
  dumpNodeGraphviz(node, "n0", out);
  out << "}\n";
  out.close( );

  system("rm tree.png");
  system("dot -Tpng tree.gv -o tree.png");
  system("rm tree.gv");
  system("xdg-open tree.png");
}

void dumpTreeStdout(Node* node, int level = 0) {
  /* base case */
  if (!node) {
    return;
  }

  /* dump leading spaces */
  for (int i = 0; i < level; i++) {
    cout << "    ";
  }

  /* dump this type of node */
  cout << stringType(node);

  /* dump the type and line if relevant */
  if (node->data_type != TYPE_VOID) {
    cout << " (TYPE:" << typeToString(node->data_type) << ")";
  }

  if (node->lineno) {
    cout << " (LINE:" << node->lineno << ")";
  }

  cout << endl;

  /* dump children */
  for (unsigned int i = 0; i < node->children.size( ); i++) {
    dumpTreeStdout(node->children[i], level + 1);
  }
}

/* the main function */
int main(int argc, char** argv) {
  /* if a file was passed, use that over stdin */
  if (argc < 2) {
    cerr << "Please pass a file name!" << endl;
    return 0;
  }

  /* try to parse the tree from this file and dump it to the screen */
  try {
    Node* tree = parseFile(argv[1]);
    dumpTreeStdout(tree);
    dumpTreeGraphviz(tree);
  } catch(Error e) {
    cout << e;
  }

  return 0;
}

<commit_msg>Changed font of graphs.<commit_after>/* this program takes in Tetra code and produces a parse tree which allows it
 * to be tested and visualized.  It now produces a structured text dump.
 * along with graphical output with graphiz */

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include "tetra.hpp"
#include "parser.gen.hpp"

using namespace std;

/* returns a string representation of a node type */
string stringType(Node* node) {
  stringstream ss;

  switch (node->node_type) {
    /* statements and groups */
    case NODE_FUNCTION: return "FUNC " + node->stringval;
    case NODE_FUNCTION_LIST: return "FUNCS";
    case NODE_STATEMENT: return "STMTS";
    case NODE_FORMAL_PARAM: return "PARAM: " + node->stringval;
    case NODE_FORMAL_PARAM_LIST: return "PARAMS";
    case NODE_PASS: return "PASS";
    case NODE_RETURN: return "RETURN";
    case NODE_BREAK: return "BREAK";
    case NODE_CONTINUE: return "CONTINUE";
    case NODE_IF: return "IF";
    case NODE_WHILE: return "WHILE";
    case NODE_ELIF: return "ELIF";
    case NODE_ELIF_CHAIN: return "ELIF CHAIN";
    case NODE_ELIF_CLAUSE: return "ELIF CLAUSE";

    /* operators */
    case NODE_ASSIGN: return "=";
    case NODE_OR: return "or";
    case NODE_AND: return "and";
    case NODE_LT: return "<";
    case NODE_LTE: return "<=";
    case NODE_GT: return ">";
    case NODE_GTE: return ">=";
    case NODE_EQ: return "==";
    case NODE_NEQ: return "!=";
    case NODE_NOT: return "not";
    case NODE_BITXOR: return "^";
    case NODE_BITAND: return "&";
    case NODE_BITOR: return "|";
    case NODE_BITNOT: return "~";
    case NODE_SHIFTL: return "<<";
    case NODE_SHIFTR: return ">>";
    case NODE_PLUS: return "+";
    case NODE_MINUS: return "-";
    case NODE_TIMES: return "*";
    case NODE_DIVIDE: return "/";
    case NODE_MODULUS: return "%";
    case NODE_EXP: return "EXP";

    /* functions */
    case NODE_FUNCALL: return "CALL: " + node->stringval;
    case NODE_ACTUAL_PARAM_LIST: return "ARGS";

    /* leafs */
    case NODE_INTVAL:
      ss << "INT: " << node->intval;
      return ss.str( );
    case NODE_REALVAL:
      ss << "REAL: " << node->realval;
      return ss.str( );
    case NODE_STRINGVAL: return "\\\"" +  node->stringval + "\\\"";
    case NODE_IDENTIFIER: return "ID " + node->stringval;
    case NODE_BOOLVAL:
      if (node->boolval) {
        return "true";
      } else {
        return "false";
      }
    default:
      throw Error("Unsupported node type!");
  }
}

/* generate a unique label for a node */
string genId( ) {
  static int count = 0;
  count++;
  stringstream ss;
  ss << "n" << count;
  return ss.str( );
}

void dumpNodeGraphviz(Node* node, string id, ofstream& out) {
  if (!node) {
    return;
  }

  /* dump the node designator */
  out << "  " << id << "[label=\"";
  out << stringType(node);
  out << "\", fontname=\"courier\"];\n";

  /* for each child */
  for (unsigned int i = 0; i < node->children.size( ); i++) {
    /* generate a new id */
    string childId = genId( );

    /* dump the connection */
    out << "  " << id << " -> " << childId << ";\n";

    /* dump the child itself */
    dumpNodeGraphviz(node->children[i], childId, out);
  }
}

void dumpTreeGraphviz(Node* node) {
  ofstream out("tree.gv");
  out << "digraph G {\n";
  dumpNodeGraphviz(node, "n0", out);
  out << "}\n";
  out.close( );

  system("rm tree.png");
  system("dot -Tpng tree.gv -o tree.png");
  system("rm tree.gv");
  system("xdg-open tree.png");
}

void dumpTreeStdout(Node* node, int level = 0) {
  /* base case */
  if (!node) {
    return;
  }

  /* dump leading spaces */
  for (int i = 0; i < level; i++) {
    cout << "    ";
  }

  /* dump this type of node */
  cout << stringType(node);

  /* dump the type and line if relevant */
  if (node->data_type != TYPE_VOID) {
    cout << " (TYPE:" << typeToString(node->data_type) << ")";
  }

  if (node->lineno) {
    cout << " (LINE:" << node->lineno << ")";
  }

  cout << endl;

  /* dump children */
  for (unsigned int i = 0; i < node->children.size( ); i++) {
    dumpTreeStdout(node->children[i], level + 1);
  }
}

/* the main function */
int main(int argc, char** argv) {
  /* if a file was passed, use that over stdin */
  if (argc < 2) {
    cerr << "Please pass a file name!" << endl;
    return 0;
  }

  /* try to parse the tree from this file and dump it to the screen */
  try {
    Node* tree = parseFile(argv[1]);
    dumpTreeStdout(tree);
    dumpTreeGraphviz(tree);
  } catch(Error e) {
    cout << e;
  }

  return 0;
}

<|endoftext|>


<commit_before>/*!
 * \file glyph_render_data_texels.hpp
 * \brief file glyph_render_data_texels.hpp
 *
 * Copyright 2016 by Intel.
 *
 * Contact: kevin.rogovin@intel.com
 *
 * This Source Code Form is subject to the
 * terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with
 * this file, You can obtain one at
 * http://mozilla.org/MPL/2.0/.
 *
 * \author Kevin Rogovin <kevin.rogovin@intel.com>
 *
 */

#pragma once

#include <fastuidraw/text/glyph_render_data.hpp>

namespace fastuidraw
{
/*!\addtogroup Text
 * @{
 */

  /*!
   * \brief
   * A GlyphRenderDataTexels holds texel data for
   * rendering a glyph. Such texel data can be for
   * both distance field and coverage glyph rendeding.
   */
  class GlyphRenderDataTexels:public GlyphRenderData
  {
  public:
    /*!
     * Ctor, initialized the resolution as (0,0).
     */
    GlyphRenderDataTexels(void);

    ~GlyphRenderDataTexels();

    /*!
     * Returns the resolution of the glyph.
     */
    ivec2
    resolution(void) const;

    /*!
     * Returns the texel data for rendering.
     * The texel (x,y) is located at I where I is
     * given by I = x + y * resolution().x(). Value
     * is an 8-bit value.
     */
    c_array<const uint8_t>
    texel_data(void) const;

    /*!
     * Returns the coverage values for rendering.
     * The texel (x,y) is located at I where I is
     * given by I = x + y * resolution().x(). Value
     * is an 8-bit value.
     */
    c_array<uint8_t>
    texel_data(void);

    /*!
     * Change the resolution
     * \param sz new resolution
     */
    void
    resize(ivec2 sz);

    virtual
    c_array<const c_string>
    render_info_labels(void) const;

    virtual
    enum fastuidraw::return_code
    upload_to_atlas(GlyphAtlasProxy &atlas_proxy,
                    GlyphAttribute::Array &attributes,
                    c_array<float> render_costs) const;

  private:
    void *m_d;
  };
/*! @} */
}
<commit_msg>fastuidraw/text/glyph_render_data_texels: document attribute values of GlyphRenderDataTexels<commit_after>/*!
 * \file glyph_render_data_texels.hpp
 * \brief file glyph_render_data_texels.hpp
 *
 * Copyright 2016 by Intel.
 *
 * Contact: kevin.rogovin@intel.com
 *
 * This Source Code Form is subject to the
 * terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with
 * this file, You can obtain one at
 * http://mozilla.org/MPL/2.0/.
 *
 * \author Kevin Rogovin <kevin.rogovin@intel.com>
 *
 */

#pragma once

#include <fastuidraw/text/glyph_render_data.hpp>

namespace fastuidraw
{
/*!\addtogroup Text
 * @{
 */

  /*!
   * \brief
   * A GlyphRenderDataTexels holds texel data for
   * rendering a glyph. Such texel data can be for
   * both distance field and coverage glyph rendeding.
   */
  class GlyphRenderDataTexels:public GlyphRenderData
  {
  public:
    /*!
     * This enumeration describes the meaning of the
     * attributes.
     */
    enum attribute_values_t
      {
        /*!
         * Dimensions of the glyph as packed by
         * \ref GlyphAttribute::rect_glyph_layout
         */
        glyph_size_xy,

        /*!
         * Location of the texel data within the
         * \ref GlyphAtlas
         */
        glyph_texel_data_offset,
      };

    /*!
     * Ctor, initialized the resolution as (0,0).
     */
    GlyphRenderDataTexels(void);

    ~GlyphRenderDataTexels();

    /*!
     * Returns the resolution of the glyph.
     */
    ivec2
    resolution(void) const;

    /*!
     * Returns the texel data for rendering.
     * The texel (x,y) is located at I where I is
     * given by I = x + y * resolution().x(). Value
     * is an 8-bit value.
     */
    c_array<const uint8_t>
    texel_data(void) const;

    /*!
     * Returns the coverage values for rendering.
     * The texel (x,y) is located at I where I is
     * given by I = x + y * resolution().x(). Value
     * is an 8-bit value.
     */
    c_array<uint8_t>
    texel_data(void);

    /*!
     * Change the resolution
     * \param sz new resolution
     */
    void
    resize(ivec2 sz);

    virtual
    c_array<const c_string>
    render_info_labels(void) const;

    virtual
    enum fastuidraw::return_code
    upload_to_atlas(GlyphAtlasProxy &atlas_proxy,
                    GlyphAttribute::Array &attributes,
                    c_array<float> render_costs) const;

  private:
    void *m_d;
  };
/*! @} */
}
<|endoftext|>


<commit_before>#pragma once

// std
#include <cstddef>
#include <cstdint>
#include <vector>

// libraries
#include <nop/serializer.h>
#include <nop/structure.h>
#include <nop/utility/buffer_reader.h>
#include <nop/utility/stream_writer.h>

// project
#include "NlohmannJsonCompat.hpp"

// To not require exceptions for embedded usecases.
#ifndef __has_feature           // Optional of course.
    #define __has_feature(x) 0  // Compatibility with non-clang compilers.
#endif
#if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) || (defined(_MSC_VER) && defined(_CPPUNWIND)) || defined(__EXCEPTIONS)
    #define DEPTHAI_EXCEPTIONS
#endif

namespace dai {

enum class SerializationType {
    LIBNOP,
    JSON,
    JSON_MSGPACK,
};
constexpr auto static DEFAULT_SERIALIZATION_TYPE = SerializationType::LIBNOP;

namespace utility {

// JSON-msgpack serialization
template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::JSON_MSGPACK, bool> = true>
inline bool serialize(const T& obj, std::vector<std::uint8_t>& data) {
    nlohmann::json j = obj;
    data = nlohmann::json::to_msgpack(j);
    return true;
}
template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::JSON_MSGPACK, bool> = true>
inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj) {
    nlohmann::from_json(nlohmann::json::from_msgpack(data, data + size), obj);
    return true;
}

// JSON serialization
template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::JSON, bool> = true>
inline bool serialize(const T& obj, std::vector<std::uint8_t>& data) {
    nlohmann::json j = obj;
    auto json = j.dump();
    data = std::vector<std::uint8_t>(reinterpret_cast<const std::uint8_t*>(json.data()), reinterpret_cast<const std::uint8_t*>(json.data()) + json.size());
    return true;
}
template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::JSON, bool> = true>
inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj) {
    nlohmann::from_json(nlohmann::json::parse(data, data + size), obj);
    return true;
}

// NOLINTBEGIN
class VectorWriter {
   public:
    template <typename... Args>
    VectorWriter(Args&&... args) : vector{std::forward<Args>(args)...} {}
    VectorWriter(const VectorWriter&) = default;
    VectorWriter& operator=(const VectorWriter&) = default;

    nop::Status<void> Prepare(std::size_t /*size*/) {
        return {};
    }

    nop::Status<void> Write(std::uint8_t byte) {
        vector.push_back(byte);
        return ReturnStatus();
    }

    nop::Status<void> Write(const void* begin, const void* end) {
        vector.insert(vector.end(), static_cast<const std::uint8_t*>(begin), static_cast<const std::uint8_t*>(end));
        return ReturnStatus();
    }

    nop::Status<void> Skip(std::size_t padding_bytes, std::uint8_t padding_value = 0x00) {
        for(std::size_t i = 0; i < padding_bytes; i++) {
            vector.push_back(padding_value);
            auto status = ReturnStatus();
            if(!status) return status;
        }

        return {};
    }

    const std::vector<std::uint8_t>& ref() const {
        return vector;
    }
    std::vector<std::uint8_t>& ref() {
        return vector;
    }
    std::vector<std::uint8_t>&& take() {
        return std::move(vector);
    }

   private:
    nop::Status<void> ReturnStatus() {
        return {};
    }

    std::vector<std::uint8_t> vector;
};
// NOLINTEND

// libnop serialization
// If exceptions are available it throws in error cases
// Otherwise return value can be checked
template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::LIBNOP, bool> = true>
inline bool serialize(const T& obj, std::vector<std::uint8_t>& data) {
    nop::Serializer<VectorWriter> serializer{std::move(data)};
    auto status = serializer.Write(obj);
    if(!status) {
#ifdef DEPTHAI_EXCEPTIONS
        throw std::runtime_error(status.GetErrorMessage());
#else
        return false;
#endif
    }
    data = std::move(serializer.writer().take());
    return true;
}
template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::LIBNOP, bool> = true>
inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj) {
    nop::Deserializer<nop::BufferReader> deserializer{data, size};
    auto status = deserializer.Read(&obj);
    if(!status) {
#ifdef DEPTHAI_EXCEPTIONS
        throw std::runtime_error(status.GetErrorMessage());
#else
        return false;
#endif
    }
    return true;
}

// Serialization using enum
template <typename T>
inline bool serialize(const T& obj, std::vector<std::uint8_t>& data, SerializationType type) {
    switch(type) {
        case SerializationType::LIBNOP:
            return serialize<SerializationType::LIBNOP>(obj, data);
        case SerializationType::JSON:
            return serialize<SerializationType::JSON>(obj, data);
        case SerializationType::JSON_MSGPACK:
            return serialize<SerializationType::JSON_MSGPACK>(obj, data);
        default:
            throw std::invalid_argument("Unknown serialization type");
    };
}
template <typename T>
inline std::vector<std::uint8_t> serialize(const T& obj, SerializationType type) {
    std::vector<std::uint8_t> data;
    if(serialize(obj, data, type)) {
        return data;
    } else {
        return {};
    }
}

template <typename T>
inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj, SerializationType type) {
    switch(type) {
        case SerializationType::LIBNOP:
            return deserialize<SerializationType::LIBNOP>(data, size, obj);
        case SerializationType::JSON:
            return deserialize<SerializationType::JSON>(data, size, obj);
        case SerializationType::JSON_MSGPACK:
            return deserialize<SerializationType::JSON_MSGPACK>(data, size, obj);
        default:
            throw std::invalid_argument("Unknown serialization type");
    };
}
template <typename T>
inline bool deserialize(const std::vector<std::uint8_t>& data, T& obj, SerializationType type) {
    return deserialize(data.data(), data.size(), obj, type);
}

// Serialization using templates
template <SerializationType TYPE, typename T>
inline std::vector<std::uint8_t> serialize(const T& obj) {
    std::vector<std::uint8_t> data;
    if(serialize<TYPE>(obj, data)) {
        return data;
    } else {
        return {};
    }
}
template <SerializationType TYPE, typename T>
inline bool deserialize(const std::vector<std::uint8_t>& data, T& obj) {
    return deserialize<TYPE>(data.data(), data.size(), obj);
}

// Defaults
template <typename T>
inline bool serialize(const T& obj, std::vector<std::uint8_t>& data) {
    return serialize<DEFAULT_SERIALIZATION_TYPE>(obj, data);
}
template <typename T>
inline std::vector<std::uint8_t> serialize(const T& obj) {
    return serialize<DEFAULT_SERIALIZATION_TYPE>(obj);
}
template <typename T>
inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj) {
    return deserialize<DEFAULT_SERIALIZATION_TYPE>(data, size, obj);
}
template <typename T>
inline bool deserialize(const std::vector<std::uint8_t>& data, T& obj) {
    return deserialize<DEFAULT_SERIALIZATION_TYPE>(data, obj);
}

}  // namespace utility

// // In dai scope
// template<typename Base, typename Derived>
// struct Serializable : Base {
//     virtual void serialize(std::vector<std::uint8_t>& data) {
//         utility::serialize(static_cast<const Derived&>(*this), data);
//     }
// };

}  // namespace dai

#define DEPTHAI_DEFERRED_EXPAND(x) x
#if defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)
   // Logic using the traditional preprocessor
    // This is for suppressing false positive warnings when compiling
    // without /Zc:preprocessor
    #pragma warning(disable : 4003)
#endif

#define DEPTHAI_NLOHMANN_JSON_OPTIONAL_TO(v1) nlohmann::to_json(nlohmann_json_j[#v1], nlohmann_json_t.v1);
#define DEPTHAI_NLOHMANN_JSON_OPTIONAL_FROM(v1) \
    if(nlohmann_json_j.contains(#v1)) nlohmann_json_j[#v1].get_to(nlohmann_json_t.v1);
#define DEPTHAI_NLOHMANN_DEFINE_TYPE_OPTIONAL_NON_INTRUSIVE(Type, ...)                              \
    inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) {             \
        DEPTHAI_NLOHMANN_JSON_EXPAND(DEPTHAI_NLOHMANN_JSON_PASTE(DEPTHAI_NLOHMANN_JSON_OPTIONAL_TO, __VA_ARGS__))   \
    }                                                                                \
    inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) {           \
        DEPTHAI_NLOHMANN_JSON_EXPAND(DEPTHAI_NLOHMANN_JSON_PASTE(DEPTHAI_NLOHMANN_JSON_OPTIONAL_FROM, __VA_ARGS__)) \
    }
#define DEPTHAI_NLOHMANN_DEFINE_TYPE_OPTIONAL_INTRUSIVE(Type, ...)                                  \
    friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) {             \
        DEPTHAI_NLOHMANN_JSON_EXPAND(DEPTHAI_NLOHMANN_JSON_PASTE(DEPTHAI_NLOHMANN_JSON_OPTIONAL_TO, __VA_ARGS__))   \
    }                                                                                \
    friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) {           \
        DEPTHAI_NLOHMANN_JSON_EXPAND(DEPTHAI_NLOHMANN_JSON_PASTE(DEPTHAI_NLOHMANN_JSON_OPTIONAL_FROM, __VA_ARGS__)) \
    }

// Macros
#define DEPTHAI_SERIALIZE_OPTIONAL_EXT(...)                                                   \
    DEPTHAI_DEFERRED_EXPAND(DEPTHAI_NLOHMANN_DEFINE_TYPE_OPTIONAL_NON_INTRUSIVE(__VA_ARGS__)) \
    DEPTHAI_DEFERRED_EXPAND(NOP_EXTERNAL_STRUCTURE(__VA_ARGS__))

#define DEPTHAI_SERIALIZE_OPTIONAL(...)                                                   \
    DEPTHAI_DEFERRED_EXPAND(DEPTHAI_NLOHMANN_DEFINE_TYPE_OPTIONAL_INTRUSIVE(__VA_ARGS__)) \
    DEPTHAI_DEFERRED_EXPAND(NOP_EXTERNAL_STRUCTURE(__VA_ARGS__))

#define DEPTHAI_SERIALIZE_EXT(...)                                                   \
    DEPTHAI_DEFERRED_EXPAND(DEPTHAI_NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(__VA_ARGS__)) \
    DEPTHAI_DEFERRED_EXPAND(NOP_EXTERNAL_STRUCTURE(__VA_ARGS__))

#define DEPTHAI_SERIALIZE(...)                                                   \
    DEPTHAI_DEFERRED_EXPAND(DEPTHAI_NLOHMANN_DEFINE_TYPE_INTRUSIVE(__VA_ARGS__)) \
    DEPTHAI_DEFERRED_EXPAND(NOP_STRUCTURE(__VA_ARGS__))
<commit_msg>Updated style<commit_after>#pragma once

// std
#include <cstddef>
#include <cstdint>
#include <vector>

// libraries
#include <nop/serializer.h>
#include <nop/structure.h>
#include <nop/utility/buffer_reader.h>
#include <nop/utility/stream_writer.h>

// project
#include "NlohmannJsonCompat.hpp"

// To not require exceptions for embedded usecases.
#ifndef __has_feature           // Optional of course.
    #define __has_feature(x) 0  // Compatibility with non-clang compilers.
#endif
#if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) || (defined(_MSC_VER) && defined(_CPPUNWIND)) || defined(__EXCEPTIONS)
    #define DEPTHAI_EXCEPTIONS
#endif

namespace dai {

enum class SerializationType {
    LIBNOP,
    JSON,
    JSON_MSGPACK,
};
constexpr auto static DEFAULT_SERIALIZATION_TYPE = SerializationType::LIBNOP;

namespace utility {

// JSON-msgpack serialization
template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::JSON_MSGPACK, bool> = true>
inline bool serialize(const T& obj, std::vector<std::uint8_t>& data) {
    nlohmann::json j = obj;
    data = nlohmann::json::to_msgpack(j);
    return true;
}
template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::JSON_MSGPACK, bool> = true>
inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj) {
    nlohmann::from_json(nlohmann::json::from_msgpack(data, data + size), obj);
    return true;
}

// JSON serialization
template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::JSON, bool> = true>
inline bool serialize(const T& obj, std::vector<std::uint8_t>& data) {
    nlohmann::json j = obj;
    auto json = j.dump();
    data = std::vector<std::uint8_t>(reinterpret_cast<const std::uint8_t*>(json.data()), reinterpret_cast<const std::uint8_t*>(json.data()) + json.size());
    return true;
}
template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::JSON, bool> = true>
inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj) {
    nlohmann::from_json(nlohmann::json::parse(data, data + size), obj);
    return true;
}

// NOLINTBEGIN
class VectorWriter {
   public:
    template <typename... Args>
    VectorWriter(Args&&... args) : vector{std::forward<Args>(args)...} {}
    VectorWriter(const VectorWriter&) = default;
    VectorWriter& operator=(const VectorWriter&) = default;

    nop::Status<void> Prepare(std::size_t /*size*/) {
        return {};
    }

    nop::Status<void> Write(std::uint8_t byte) {
        vector.push_back(byte);
        return ReturnStatus();
    }

    nop::Status<void> Write(const void* begin, const void* end) {
        vector.insert(vector.end(), static_cast<const std::uint8_t*>(begin), static_cast<const std::uint8_t*>(end));
        return ReturnStatus();
    }

    nop::Status<void> Skip(std::size_t padding_bytes, std::uint8_t padding_value = 0x00) {
        for(std::size_t i = 0; i < padding_bytes; i++) {
            vector.push_back(padding_value);
            auto status = ReturnStatus();
            if(!status) return status;
        }

        return {};
    }

    const std::vector<std::uint8_t>& ref() const {
        return vector;
    }
    std::vector<std::uint8_t>& ref() {
        return vector;
    }
    std::vector<std::uint8_t>&& take() {
        return std::move(vector);
    }

   private:
    nop::Status<void> ReturnStatus() {
        return {};
    }

    std::vector<std::uint8_t> vector;
};
// NOLINTEND

// libnop serialization
// If exceptions are available it throws in error cases
// Otherwise return value can be checked
template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::LIBNOP, bool> = true>
inline bool serialize(const T& obj, std::vector<std::uint8_t>& data) {
    nop::Serializer<VectorWriter> serializer{std::move(data)};
    auto status = serializer.Write(obj);
    if(!status) {
#ifdef DEPTHAI_EXCEPTIONS
        throw std::runtime_error(status.GetErrorMessage());
#else
        return false;
#endif
    }
    data = std::move(serializer.writer().take());
    return true;
}
template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::LIBNOP, bool> = true>
inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj) {
    nop::Deserializer<nop::BufferReader> deserializer{data, size};
    auto status = deserializer.Read(&obj);
    if(!status) {
#ifdef DEPTHAI_EXCEPTIONS
        throw std::runtime_error(status.GetErrorMessage());
#else
        return false;
#endif
    }
    return true;
}

// Serialization using enum
template <typename T>
inline bool serialize(const T& obj, std::vector<std::uint8_t>& data, SerializationType type) {
    switch(type) {
        case SerializationType::LIBNOP:
            return serialize<SerializationType::LIBNOP>(obj, data);
        case SerializationType::JSON:
            return serialize<SerializationType::JSON>(obj, data);
        case SerializationType::JSON_MSGPACK:
            return serialize<SerializationType::JSON_MSGPACK>(obj, data);
        default:
            throw std::invalid_argument("Unknown serialization type");
    };
}
template <typename T>
inline std::vector<std::uint8_t> serialize(const T& obj, SerializationType type) {
    std::vector<std::uint8_t> data;
    if(serialize(obj, data, type)) {
        return data;
    } else {
        return {};
    }
}

template <typename T>
inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj, SerializationType type) {
    switch(type) {
        case SerializationType::LIBNOP:
            return deserialize<SerializationType::LIBNOP>(data, size, obj);
        case SerializationType::JSON:
            return deserialize<SerializationType::JSON>(data, size, obj);
        case SerializationType::JSON_MSGPACK:
            return deserialize<SerializationType::JSON_MSGPACK>(data, size, obj);
        default:
            throw std::invalid_argument("Unknown serialization type");
    };
}
template <typename T>
inline bool deserialize(const std::vector<std::uint8_t>& data, T& obj, SerializationType type) {
    return deserialize(data.data(), data.size(), obj, type);
}

// Serialization using templates
template <SerializationType TYPE, typename T>
inline std::vector<std::uint8_t> serialize(const T& obj) {
    std::vector<std::uint8_t> data;
    if(serialize<TYPE>(obj, data)) {
        return data;
    } else {
        return {};
    }
}
template <SerializationType TYPE, typename T>
inline bool deserialize(const std::vector<std::uint8_t>& data, T& obj) {
    return deserialize<TYPE>(data.data(), data.size(), obj);
}

// Defaults
template <typename T>
inline bool serialize(const T& obj, std::vector<std::uint8_t>& data) {
    return serialize<DEFAULT_SERIALIZATION_TYPE>(obj, data);
}
template <typename T>
inline std::vector<std::uint8_t> serialize(const T& obj) {
    return serialize<DEFAULT_SERIALIZATION_TYPE>(obj);
}
template <typename T>
inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj) {
    return deserialize<DEFAULT_SERIALIZATION_TYPE>(data, size, obj);
}
template <typename T>
inline bool deserialize(const std::vector<std::uint8_t>& data, T& obj) {
    return deserialize<DEFAULT_SERIALIZATION_TYPE>(data, obj);
}

}  // namespace utility

// // In dai scope
// template<typename Base, typename Derived>
// struct Serializable : Base {
//     virtual void serialize(std::vector<std::uint8_t>& data) {
//         utility::serialize(static_cast<const Derived&>(*this), data);
//     }
// };

}  // namespace dai

#define DEPTHAI_DEFERRED_EXPAND(x) x
#if defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)
   // Logic using the traditional preprocessor
    // This is for suppressing false positive warnings when compiling
    // without /Zc:preprocessor
    #pragma warning(disable : 4003)
#endif

#define DEPTHAI_NLOHMANN_JSON_OPTIONAL_TO(v1) nlohmann::to_json(nlohmann_json_j[#v1], nlohmann_json_t.v1);
#define DEPTHAI_NLOHMANN_JSON_OPTIONAL_FROM(v1) \
    if(nlohmann_json_j.contains(#v1)) nlohmann_json_j[#v1].get_to(nlohmann_json_t.v1);
#define DEPTHAI_NLOHMANN_DEFINE_TYPE_OPTIONAL_NON_INTRUSIVE(Type, ...)                                              \
    inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) {                             \
        DEPTHAI_NLOHMANN_JSON_EXPAND(DEPTHAI_NLOHMANN_JSON_PASTE(DEPTHAI_NLOHMANN_JSON_OPTIONAL_TO, __VA_ARGS__))   \
    }                                                                                \
    inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) {                           \
        DEPTHAI_NLOHMANN_JSON_EXPAND(DEPTHAI_NLOHMANN_JSON_PASTE(DEPTHAI_NLOHMANN_JSON_OPTIONAL_FROM, __VA_ARGS__)) \
    }
#define DEPTHAI_NLOHMANN_DEFINE_TYPE_OPTIONAL_INTRUSIVE(Type, ...)                                                  \
    friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) {                             \
        DEPTHAI_NLOHMANN_JSON_EXPAND(DEPTHAI_NLOHMANN_JSON_PASTE(DEPTHAI_NLOHMANN_JSON_OPTIONAL_TO, __VA_ARGS__))   \
    }                                                                                \
    friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) {                           \
        DEPTHAI_NLOHMANN_JSON_EXPAND(DEPTHAI_NLOHMANN_JSON_PASTE(DEPTHAI_NLOHMANN_JSON_OPTIONAL_FROM, __VA_ARGS__)) \
    }

// Macros
#define DEPTHAI_SERIALIZE_OPTIONAL_EXT(...)                                                   \
    DEPTHAI_DEFERRED_EXPAND(DEPTHAI_NLOHMANN_DEFINE_TYPE_OPTIONAL_NON_INTRUSIVE(__VA_ARGS__)) \
    DEPTHAI_DEFERRED_EXPAND(NOP_EXTERNAL_STRUCTURE(__VA_ARGS__))

#define DEPTHAI_SERIALIZE_OPTIONAL(...)                                                   \
    DEPTHAI_DEFERRED_EXPAND(DEPTHAI_NLOHMANN_DEFINE_TYPE_OPTIONAL_INTRUSIVE(__VA_ARGS__)) \
    DEPTHAI_DEFERRED_EXPAND(NOP_EXTERNAL_STRUCTURE(__VA_ARGS__))

#define DEPTHAI_SERIALIZE_EXT(...)                                                   \
    DEPTHAI_DEFERRED_EXPAND(DEPTHAI_NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(__VA_ARGS__)) \
    DEPTHAI_DEFERRED_EXPAND(NOP_EXTERNAL_STRUCTURE(__VA_ARGS__))

#define DEPTHAI_SERIALIZE(...)                                                   \
    DEPTHAI_DEFERRED_EXPAND(DEPTHAI_NLOHMANN_DEFINE_TYPE_INTRUSIVE(__VA_ARGS__)) \
    DEPTHAI_DEFERRED_EXPAND(NOP_STRUCTURE(__VA_ARGS__))
<|endoftext|>


<commit_before>#ifndef GAMELIB_PROPERTY_CONTAINER_HPP
#define GAMELIB_PROPERTY_CONTAINER_HPP

#include <string>
#include <unordered_map>
#include "gamelib/json/JsonSerializer.hpp"
#include "gamelib/utils/log.hpp"
#include "PropertyHandle.hpp"
#include "basictypes.hpp"

// Helper for registering properties with member function setters that take
// exactly the new value as argument,
// Usage: props.registerProperty("size", _size, PROP_METHOD(_size, setSize), this);
#define PROP_METHOD(T, F) PROP_METHOD_TYPE(decltype(T), F)
#define PROP_METHOD_TYPE(T, F) +[](T const* val, decltype(this) self) { self->F(*val); }
#define PROP_METHOD_CLASS(T, F, C) +[](T const* val, C* self) { self->F(*val); }

namespace gamelib
{
    class PropertyContainer : public JsonSerializer
    {
        public:
            typedef std::unordered_map<std::string, PropertyHandle> PropertyMap;

        public:
            auto loadFromJson(const Json::Value& node) -> bool final override;
            auto writeToJson(Json::Value& node) const  -> void final override;

            auto unregisterProperty(const std::string& name) -> void;

            template <typename T, typename U = void>
            void registerProperty(const std::string& name, T& prop,
                    int min = 0, int max = 0, const char* const* hints = nullptr, U* data = nullptr);

            template <typename T, typename U>
            void registerProperty(const std::string& name, const T& prop, NicePropSetterCallback<T, U> setter, U* self,
                    int min = 0, int max = 0, const char* const* hints = nullptr);

            template <typename T, typename U = void>
            void registerProperty(const std::string& name, T& prop, const IPropType* type,
                    int min = 0, int max = 0, const char* const* hints = nullptr, U* data = nullptr);

            template <typename T, typename U>
            void registerProperty(const std::string& name, const T& prop, NicePropSetterCallback<T, U> setter, U* self, const IPropType* type,
                    int min = 0, int max = 0, const char* const* hints = nullptr);

            template <typename T, typename U>
            void registerProperty(const std::string& name, NicePropAccessorCallback<T, U> accessor, U* self,
                    int min = 0, int max = 0, const char* const* hints = nullptr);

            template <typename T, typename U>
            void registerProperty(const std::string& name, NicePropAccessorCallback<T, U> accessor, U* self, const IPropType* type,
                    int min = 0, int max = 0, const char* const* hints = nullptr);

            auto begin() const -> PropertyMap::const_iterator;
            auto begin()       -> PropertyMap::iterator;
            auto end() const   -> PropertyMap::const_iterator;
            auto end()         -> PropertyMap::iterator;

            auto size() const -> size_t;
            auto clear()      -> void;

            auto find(const std::string& name) const -> const PropertyHandle*;
            auto find(const std::string& name)       -> PropertyHandle*;
            auto get(const std::string& name) const  -> const void*;

            template <typename T>
            auto getAs(const std::string& name) const -> const T*;

            template <typename T>
            auto set(const std::string& name, const T& val) const -> void;

        private:
            auto _registerProperty(const std::string& name, const void* constprop, void* prop,
                    PropSetterCallback setter, PropAccessorCallback accessor, void* self,
                    const IPropType* type, int min, int max, const char* const* hints)
                -> void;

        private:
            PropertyMap _properties;
    };

    // Implementation
    template <typename T>
    const T* PropertyContainer::getAs(const std::string& name) const
    {
        auto ptr = find(name);
        return ptr ? &ptr->getAs<T>() : nullptr;
    }

    template <typename T>
    void PropertyContainer::set(const std::string& name, const T& val) const
    {
        auto handle = find(name);
        if (handle)
            handle->set(val);
        else
            LOG_WARN("Unknown property: ", name);
    }

    template <typename T, typename U>
    void PropertyContainer::registerProperty(const std::string& name, T& prop, int min, int max, const char* const* hints, U* data)
    {
        _registerProperty(name, nullptr, &prop, nullptr, nullptr, data, categorizeProperty(prop), min, max, hints);
    }

    template <typename T, typename U>
    void PropertyContainer::registerProperty(const std::string& name, T& prop, const IPropType* type, int min, int max, const char* const* hints, U* data)
    {
        _registerProperty(name, nullptr, &prop, nullptr, nullptr, data, type, min, max, hints);
    }

    template <typename T, typename U>
    void PropertyContainer::registerProperty(const std::string& name, const T& prop, NicePropSetterCallback<T, U> setter, U* self, int min, int max, const char* const* hints)
    {
        _registerProperty(name, &prop, nullptr, (PropSetterCallback)setter, nullptr, self, categorizeProperty(prop), min, max, hints);
    }

    template <typename T, typename U>
    void PropertyContainer::registerProperty(const std::string& name, const T& prop, NicePropSetterCallback<T, U> setter, U* self, const IPropType* type, int min, int max, const char* const* hints)
    {
        _registerProperty(name, &prop, nullptr, (PropSetterCallback)setter, nullptr, self, type, min, max, hints);
    }

    template <typename T, typename U>
    void PropertyContainer::registerProperty(const std::string& name, NicePropAccessorCallback<T, U> accessor, U* self,
            int min, int max, const char* const* hints)
    {
        const T* emptyptr = nullptr;    // passed to categorizeProperty()
        _registerProperty(name, nullptr, nullptr, nullptr, (PropAccessorCallback)accessor, self, categorizeProperty(*emptyptr), min, max, hints);
    }

    template <typename T, typename U>
    void PropertyContainer::registerProperty(const std::string& name, NicePropAccessorCallback<T, U> accessor, U* self, const IPropType* type,
            int min, int max, const char* const* hints)
    {
        _registerProperty(name, nullptr, nullptr, nullptr, (PropAccessorCallback)accessor, self, type, min, max, hints);
    }
}

#endif
<commit_msg>Add helper macros for properties with accessors<commit_after>#ifndef GAMELIB_PROPERTY_CONTAINER_HPP
#define GAMELIB_PROPERTY_CONTAINER_HPP

#include <string>
#include <unordered_map>
#include "gamelib/json/JsonSerializer.hpp"
#include "gamelib/utils/log.hpp"
#include "PropertyHandle.hpp"
#include "basictypes.hpp"

// Helper for registering properties with member function setters that take
// exactly the new value as argument,
// Usage: props.registerProperty("size", _size, PROP_METHOD(_size, setSize), this);
#define PROP_METHOD(T, F) PROP_METHOD_TYPE(decltype(T), F)
#define PROP_METHOD_TYPE(T, F) PROP_METHOD_CLASS(T, F, std::remove_pointer_t<decltype(this)>)
// #define PROP_METHOD_TYPE(T, F) +[](T const* val, decltype(this) self) { self->F(*val); }
#define PROP_METHOD_CLASS(T, F, C) +[](T const* val, C* self) { self->F(*val); }

// Helpers for registering properties that don't have direct variable access,
// but use getter and setter functions.
// The setter takes exactly the new value as argument.
// The getter takes no arguments and returns a const reference (const T&).
// If the getter returns a copy, use PROP_ACCESSOR_BUFFERED.
// Other getter return values are not supported by these macros.
// Usage:
//     props.registerProperty("size", PROP_ACCESSOR(setSize, getSize), this);
//     props.registerProperty("somefloat", PROP_ACCESSOR_BUFFERED(setFloat, getFloat), this);
#define PROP_ACCESSOR(S, G) \
    PROP_ACCESSOR_TYPES(S, G, std::remove_pointer_t<decltype(this)>, \
            std::remove_reference_t<std::remove_pointer_t<decltype(G())>>)

// Same as PROP_ACCESSOR but for getter functions that return a copy instead of a const reference.
#define PROP_ACCESSOR_BUFFERED(S, G) \
    PROP_ACCESSOR_TYPES_BUFFERED(S, G, std::remove_pointer_t<decltype(this)>, \
            std::remove_reference_t<std::remove_pointer_t<decltype(G())>>)

#define PROP_ACCESSOR_TYPES_BUFFERED(S, G, C, T) \
+[](T const* val, C* self) -> T const* { \
    static T tmp; \
    if (val) \
        self->S(*val); \
    tmp = self->G(); \
    return &tmp; \
}

#define PROP_ACCESSOR_TYPES(S, G, C, T) \
+[](T const* val, C* self) -> T const* { \
    if (val) \
        self->S(*val); \
    return &self->G(); \
}

namespace gamelib
{
    class PropertyContainer : public JsonSerializer
    {
        public:
            typedef std::unordered_map<std::string, PropertyHandle> PropertyMap;

        public:
            auto loadFromJson(const Json::Value& node) -> bool final override;
            auto writeToJson(Json::Value& node) const  -> void final override;

            auto unregisterProperty(const std::string& name) -> void;

            template <typename T, typename U = void>
            void registerProperty(const std::string& name, T& prop,
                    int min = 0, int max = 0, const char* const* hints = nullptr, U* data = nullptr);

            template <typename T, typename U>
            void registerProperty(const std::string& name, const T& prop, NicePropSetterCallback<T, U> setter, U* self,
                    int min = 0, int max = 0, const char* const* hints = nullptr);

            template <typename T, typename U = void>
            void registerProperty(const std::string& name, T& prop, const IPropType* type,
                    int min = 0, int max = 0, const char* const* hints = nullptr, U* data = nullptr);

            template <typename T, typename U>
            void registerProperty(const std::string& name, const T& prop, NicePropSetterCallback<T, U> setter, U* self, const IPropType* type,
                    int min = 0, int max = 0, const char* const* hints = nullptr);

            template <typename T, typename U>
            void registerProperty(const std::string& name, NicePropAccessorCallback<T, U> accessor, U* self,
                    int min = 0, int max = 0, const char* const* hints = nullptr);

            template <typename T, typename U>
            void registerProperty(const std::string& name, NicePropAccessorCallback<T, U> accessor, U* self, const IPropType* type,
                    int min = 0, int max = 0, const char* const* hints = nullptr);

            auto begin() const -> PropertyMap::const_iterator;
            auto begin()       -> PropertyMap::iterator;
            auto end() const   -> PropertyMap::const_iterator;
            auto end()         -> PropertyMap::iterator;

            auto size() const -> size_t;
            auto clear()      -> void;

            auto find(const std::string& name) const -> const PropertyHandle*;
            auto find(const std::string& name)       -> PropertyHandle*;
            auto get(const std::string& name) const  -> const void*;

            template <typename T>
            auto getAs(const std::string& name) const -> const T*;

            template <typename T>
            auto set(const std::string& name, const T& val) const -> void;

        private:
            auto _registerProperty(const std::string& name, const void* constprop, void* prop,
                    PropSetterCallback setter, PropAccessorCallback accessor, void* self,
                    const IPropType* type, int min, int max, const char* const* hints)
                -> void;

        private:
            PropertyMap _properties;
    };

    // Implementation
    template <typename T>
    const T* PropertyContainer::getAs(const std::string& name) const
    {
        auto ptr = find(name);
        return ptr ? &ptr->getAs<T>() : nullptr;
    }

    template <typename T>
    void PropertyContainer::set(const std::string& name, const T& val) const
    {
        auto handle = find(name);
        if (handle)
            handle->set(val);
        else
            LOG_WARN("Unknown property: ", name);
    }

    template <typename T, typename U>
    void PropertyContainer::registerProperty(const std::string& name, T& prop, int min, int max, const char* const* hints, U* data)
    {
        _registerProperty(name, nullptr, &prop, nullptr, nullptr, data, categorizeProperty(prop), min, max, hints);
    }

    template <typename T, typename U>
    void PropertyContainer::registerProperty(const std::string& name, T& prop, const IPropType* type, int min, int max, const char* const* hints, U* data)
    {
        _registerProperty(name, nullptr, &prop, nullptr, nullptr, data, type, min, max, hints);
    }

    template <typename T, typename U>
    void PropertyContainer::registerProperty(const std::string& name, const T& prop, NicePropSetterCallback<T, U> setter, U* self, int min, int max, const char* const* hints)
    {
        _registerProperty(name, &prop, nullptr, (PropSetterCallback)setter, nullptr, self, categorizeProperty(prop), min, max, hints);
    }

    template <typename T, typename U>
    void PropertyContainer::registerProperty(const std::string& name, const T& prop, NicePropSetterCallback<T, U> setter, U* self, const IPropType* type, int min, int max, const char* const* hints)
    {
        _registerProperty(name, &prop, nullptr, (PropSetterCallback)setter, nullptr, self, type, min, max, hints);
    }

    template <typename T, typename U>
    void PropertyContainer::registerProperty(const std::string& name, NicePropAccessorCallback<T, U> accessor, U* self,
            int min, int max, const char* const* hints)
    {
        const T* emptyptr = nullptr;    // passed to categorizeProperty()
        _registerProperty(name, nullptr, nullptr, nullptr, (PropAccessorCallback)accessor, self, categorizeProperty(*emptyptr), min, max, hints);
    }

    template <typename T, typename U>
    void PropertyContainer::registerProperty(const std::string& name, NicePropAccessorCallback<T, U> accessor, U* self, const IPropType* type,
            int min, int max, const char* const* hints)
    {
        _registerProperty(name, nullptr, nullptr, nullptr, (PropAccessorCallback)accessor, self, type, min, max, hints);
    }
}

#endif
<|endoftext|>


<commit_before>/*
* 2014+ Copyright (c) Andrey Kashin <kashin.andrej@gmail.com>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*/

#ifndef COMPLEX_AGGREGATOR_HPP
#define COMPLEX_AGGREGATOR_HPP

#include "aggregator.hpp"

namespace react {

class complex_aggregator_t : public aggregator_t {
public:
	complex_aggregator_t(const actions_set_t &actions_set): aggregator_t(actions_set) {}
	~complex_aggregator_t() {}

	void add_aggregator(std::shared_ptr<aggregator_t> aggregator) {
		aggregators.push_back(aggregator);
	}

	void aggregate(const call_tree_t &call_tree) {
		for (auto it = aggregators.begin(); it != aggregators.end(); ++it) {
			it->aggregate(call_tree);
		}
	}

	void to_json(rapidjson::Value &value, rapidjson::Document::AllocatorType &allocator) const {
		rapidjson::Value complex_aggregator_value(rapidjson::kArrayType);
		for (auto it = aggregators.begin(); it != aggregators.end(); ++it) {
			rapidjson::Value aggregator_value(rapidjson::kObjectType);
			it->to_json(aggregator_value, allocator);
			complex_aggregator_value.PushBack(aggregator_value, allocator);
		}
		value.AddMember("complex_aggregator", complex_aggregator_value, allocator);
	}

private:
	std::vector<std::shared_ptr<aggregator_t>> aggregators;
};

} // namespace react

#endif // COMPLEX_AGGREGATOR_HPP
<commit_msg>aggregators: iterator dereference fixed<commit_after>/*
* 2014+ Copyright (c) Andrey Kashin <kashin.andrej@gmail.com>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*/

#ifndef COMPLEX_AGGREGATOR_HPP
#define COMPLEX_AGGREGATOR_HPP

#include "aggregator.hpp"

namespace react {

class complex_aggregator_t : public aggregator_t {
public:
	complex_aggregator_t(const actions_set_t &actions_set): aggregator_t(actions_set) {}
	~complex_aggregator_t() {}

	void add_aggregator(std::shared_ptr<aggregator_t> aggregator) {
		aggregators.push_back(aggregator);
	}

	void aggregate(const call_tree_t &call_tree) {
		for (auto it = aggregators.begin(); it != aggregators.end(); ++it) {
			(*it)->aggregate(call_tree);
		}
	}

	void to_json(rapidjson::Value &value, rapidjson::Document::AllocatorType &allocator) const {
		rapidjson::Value complex_aggregator_value(rapidjson::kArrayType);
		for (auto it = aggregators.begin(); it != aggregators.end(); ++it) {
			rapidjson::Value aggregator_value(rapidjson::kObjectType);
			(*it)->to_json(aggregator_value, allocator);
			complex_aggregator_value.PushBack(aggregator_value, allocator);
		}
		value.AddMember("complex_aggregator", complex_aggregator_value, allocator);
	}

private:
	std::vector<std::shared_ptr<aggregator_t>> aggregators;
};

} // namespace react

#endif // COMPLEX_AGGREGATOR_HPP
<|endoftext|>


<commit_before>/*
 * json_request_handler.hpp
 *
 *  Created on: Oct 27, 2016
 *      Author: zmij
 */

#ifndef HTTP_SERVER_JSON_REQUEST_HANDLER_HPP_
#define HTTP_SERVER_JSON_REQUEST_HANDLER_HPP_

#include <tip/http/server/json_body_context.hpp>
#include <atomic>
#include <type_traits>

namespace tip {
namespace http {
namespace server {

struct json_reply {
public:
    explicit
    json_reply(reply r)
        : r_{r}, sent_{ ::std::make_shared< ::std::atomic_flag >(false) } {}
    json_reply(json_reply const&) = default;
    json_reply(json_reply&&) = default;

    json_reply&
    operator = (json_reply const&) = default;
    json_reply&
    operator = (json_reply&&) = default;

    tip::iri::path const&
    path() const
    { return r_.path(); }

    reply::query_type const&
    query() const
    { return r_.query(); }

    headers const&
    request_headers() const
    { return r_.request_headers(); }

    void
    add_header(header const& h) const
    {
        r_.add_header(h);
    }
    void
    add_header(header&& h) const
    {
        r_.add_header(::std::move(h));
    }

    void
    on_finish(reply::finished_func f)
    {
        r_.on_finish(f);
    }

    template < typename T >
    bool
    parse(T& val, bool allow_empty_body = false)
    {
        auto& json = use_context<json_body_context>(r_);
        if ((bool)json) {
            try {
                json.input(val);
                return true;
            } catch(::std::exception const& e) {
                throw json_error{e.what()};
            } catch(...) {
                throw json_error("Invalid JSON request");
            }
        }
        switch (json.status()) {
            case json_body_context::empty_body:
                if (!allow_empty_body)
                    throw json_error("Empty body (expected JSON object)");
                break;
            case json_body_context::invalid_json:
                throw json_error("Malformed JSON");
            default:
                throw json_error("Unknown JSON status");
        }
        return false;
    }

    template < typename T >
    void
    done(T&& body, response_status status = response_status::ok) const
    {
        if (!sent_->test_and_set()) {
            r_.add_header({ ContentType, "application/json; charset=utf8" });
            r_.response_body().clear();
            auto& json = use_context<json_body_context>(r_);
            json << ::std::forward<T>(body);
            r_.done(status);
        } else {
            log_already_sent();
        }
    }
    template < typename T >
    void
    operator()(T&& body, response_status status = response_status::ok) const
    { done(::std::forward<T>(body), status); }
    void
    error(http::server::error const& e) const
    {
        e.log_error();
        done(e, e.status());
    }
    void
    operator()(http::server::error const& e) const
    { error(e); }

    template < typename Context >
    friend bool
    has_context(json_reply& r);
    template < typename Context >
    friend Context&
    use_context(json_reply& r);
private:
    void
    log_already_sent() const;
    using shared_flag = ::std::shared_ptr<::std::atomic_flag>;

    reply mutable   r_;
    shared_flag     sent_;
};

template < typename Context >
bool
has_context(json_reply& r)
{
    return has_context<Context>(r.r_);
}

template < typename Context >
Context&
use_context(json_reply& r)
{
    return use_context<Context>(r.r_);
}

template < typename T >
struct json_request_handler {
    using handler_type = T;
    using base_type = json_request_handler< T >;

    void
    operator()(reply r)
    {
        rebind()(json_reply{r});
    }
private:
    handler_type&
    rebind()
    {
        return static_cast<handler_type&>(*this);
    }
    handler_type&
    rebind() const
    {
        return static_cast<handler_type const&>(*this);
    }
};

template < typename T, typename BodyType >
struct json_transform_handler :
        json_request_handler< json_transform_handler<T, BodyType> >{
    using base_type = json_request_handler< json_transform_handler<T, BodyType> >;
    using handler_type = T;
    using request_body_type     = BodyType;
    using request_pointer       = ::std::shared_ptr<BodyType>;

    using base_type::operator();
    void
    operator()(json_reply r)
    {
        try {
            request_pointer req{ ::std::make_shared<request_body_type>() };
            if (r.parse(*req)) {
                rebind()(r, req);
            }
        } catch ( ::tip::http::server::error const& e ) {
            r.error(e);
        } catch (::std::exception const& e) {
            r.error(::tip::http::server::error{"REQUEST", e.what(), response_status::ok});
        } catch (...) {
            r.error(::tip::http::server::error{"REQUEST", "Unexpected exception", response_status::ok});
        }
    }
private:
    handler_type&
    rebind()
    {
        return static_cast<handler_type&>(*this);
    }
    handler_type&
    rebind() const
    {
        return static_cast<handler_type const&>(*this);
    }
};

}  /* namespace server */
}  /* namespace http */
}  /* namespace tip */

#endif /* HTTP_SERVER_JSON_REQUEST_HANDLER_HPP_ */
<commit_msg>AWM-7129 Add user's counters viewer<commit_after>/*
 * json_request_handler.hpp
 *
 *  Created on: Oct 27, 2016
 *      Author: zmij
 */

#ifndef HTTP_SERVER_JSON_REQUEST_HANDLER_HPP_
#define HTTP_SERVER_JSON_REQUEST_HANDLER_HPP_

#include <tip/http/server/json_body_context.hpp>
#include <atomic>
#include <type_traits>

namespace tip {
namespace http {
namespace server {

struct json_reply {
public:
    explicit
    json_reply(reply r)
        : r_{r}, sent_{ ::std::make_shared< ::std::atomic_flag >(false) } {}
    json_reply(json_reply const&) = default;
    json_reply(json_reply&&) = default;

    json_reply&
    operator = (json_reply const&) = default;
    json_reply&
    operator = (json_reply&&) = default;

    tip::iri::path const&
    path() const
    { return r_.path(); }

    reply::query_type const&
    query() const
    { return r_.query(); }

    headers const&
    request_headers() const
    { return r_.request_headers(); }

    void
    add_header(header const& h) const
    {
        r_.add_header(h);
    }
    void
    add_header(header&& h) const
    {
        r_.add_header(::std::move(h));
    }

    void
    on_finish(reply::finished_func f)
    {
        r_.on_finish(f);
    }

    template < typename T >
    bool
    parse(T& val, bool allow_empty_body = false)
    {
        auto& json = use_context<json_body_context>(r_);
        if ((bool)json) {
            try {
                json.input(val);
                return true;
            } catch(::std::exception const& e) {
                throw json_error{e.what()};
            } catch(...) {
                throw json_error("Invalid JSON request");
            }
        }
        switch (json.status()) {
            case json_body_context::empty_body:
                if (!allow_empty_body)
                    throw json_error("Empty body (expected JSON object)");
                break;
            case json_body_context::invalid_json:
                throw json_error("Malformed JSON");
            default:
                throw json_error("Unknown JSON status");
        }
        return false;
    }

    template < typename T >
    void
    done(T&& body, response_status status = response_status::ok) const
    {
        if (!sent_->test_and_set()) {
            r_.add_header({ ContentType, "application/json; charset=utf8" });
            r_.response_body().clear();
            auto& json = use_context<json_body_context>(r_);
            json << ::std::forward<T>(body);
            r_.done(status);
        } else {
            log_already_sent();
        }
    }
    template < typename T >
    void
    operator()(T&& body, response_status status = response_status::ok) const
    { done(::std::forward<T>(body), status); }
    void
    error(http::server::error const& e) const
    {
        e.log_error();
        done(e, e.status());
    }
    void
    operator()(http::server::error const& e) const
    { error(e); }

    template < typename Context >
    friend bool
    has_context(json_reply& r);
    template < typename Context >
    friend Context&
    use_context(json_reply& r);

    void
    raw_response(::std::string const& body,
            response_status status = response_status::ok) const
    {
        if (!sent_->test_and_set()) {
            r_.add_header({ ContentType, "application/json; charset=utf8" });
            r_.response_body().clear();
            ::std::copy(body.begin(), body.end(), ::std::back_inserter(r_.response_body()));
            r_.done(status);
        } else {
            log_already_sent();
        }
    }
private:
    void
    log_already_sent() const;
    using shared_flag = ::std::shared_ptr<::std::atomic_flag>;

    reply mutable   r_;
    shared_flag     sent_;
};

template < typename Context >
bool
has_context(json_reply& r)
{
    return has_context<Context>(r.r_);
}

template < typename Context >
Context&
use_context(json_reply& r)
{
    return use_context<Context>(r.r_);
}

template < typename T >
struct json_request_handler {
    using handler_type = T;
    using base_type = json_request_handler< T >;

    void
    operator()(reply r)
    {
        rebind()(json_reply{r});
    }
private:
    handler_type&
    rebind()
    {
        return static_cast<handler_type&>(*this);
    }
    handler_type&
    rebind() const
    {
        return static_cast<handler_type const&>(*this);
    }
};

template < typename T, typename BodyType >
struct json_transform_handler :
        json_request_handler< json_transform_handler<T, BodyType> >{
    using base_type = json_request_handler< json_transform_handler<T, BodyType> >;
    using handler_type = T;
    using request_body_type     = BodyType;
    using request_pointer       = ::std::shared_ptr<BodyType>;

    using base_type::operator();
    void
    operator()(json_reply r)
    {
        try {
            request_pointer req{ ::std::make_shared<request_body_type>() };
            if (r.parse(*req)) {
                rebind()(r, req);
            }
        } catch ( ::tip::http::server::error const& e ) {
            r.error(e);
        } catch (::std::exception const& e) {
            r.error(::tip::http::server::error{"REQUEST", e.what(), response_status::ok});
        } catch (...) {
            r.error(::tip::http::server::error{"REQUEST", "Unexpected exception", response_status::ok});
        }
    }
private:
    handler_type&
    rebind()
    {
        return static_cast<handler_type&>(*this);
    }
    handler_type&
    rebind() const
    {
        return static_cast<handler_type const&>(*this);
    }
};

}  /* namespace server */
}  /* namespace http */
}  /* namespace tip */

#endif /* HTTP_SERVER_JSON_REQUEST_HANDLER_HPP_ */
<|endoftext|>


<commit_before>/*
 * Joystick driver
 *
 * Copyright (C)2016 Laurentiu Badea
 *
 * This file may be redistributed under the terms of the MIT license.
 * A copy of this license has been included with this distribution in the file LICENSE.
 */

#include <Arduino.h>
#include "joystick.h"

/*
 * Interrupt handler triggered by joystick button click
 */
volatile static int button_clicked = false;
void button_click(){
    button_clicked = true;
}

Joystick::Joystick(int sw_pin, int x_pin, int y_pin)
:sw_pin(sw_pin),
 x_pin(x_pin),
 y_pin(y_pin)
{
    pinMode(sw_pin, INPUT_PULLUP);
    pinMode(x_pin, INPUT);
    pinMode(y_pin, INPUT);
    sw_state = HIGH;
    x_state = 0;
    y_state = 0;
    read();
    attachInterrupt(digitalPinToInterrupt(sw_pin), button_click, FALLING);
}

Joystick::~Joystick(void){
    // clean up
    detachInterrupt(digitalPinToInterrupt(sw_pin));
}

unsigned Joystick::read(void){
    unsigned event = EVENT_NONE;
    int current_state;

    if (millis() - last_read < 100){
        return EVENT_NONE;
    }

    // read click switch
    current_state = (button_clicked) ? LOW : digitalRead(sw_pin);
    if (current_state != sw_state){
        sw_state = current_state;
        if (sw_state == LOW){
            event |= EVENT_OK;
            for (int i=50; i && digitalRead(sw_pin) == LOW; i--){
                delay(10);
            };
        }
        button_clicked = false;
    }

    // read X position
    current_state = getPositionX();
    if (current_state > x_state && current_state > 0){
        event |= EVENT_RIGHT;
    } else if (current_state < x_state && current_state < 0){
        event |= EVENT_LEFT;
    }
    x_state = current_state;

    // read Y position
    current_state = getPositionY();
    if (current_state > y_state && current_state > 0){
        event |= EVENT_UP;
    } else if (current_state < y_state && current_state < 0){
        event |= EVENT_DOWN;
    }
    y_state = current_state;

    last_read = millis();
    return event;
}

int Joystick::getPositionX(void){
    return (analogRead(x_pin)-512+(1<<(sensitivity-1))) >> sensitivity;
}

int Joystick::getPositionY(void){
    return (512-analogRead(y_pin)+(1<<(sensitivity-1))) >> sensitivity;
}

bool Joystick::getButtonState(void){
    return digitalRead(sw_pin) == LOW;
}
<commit_msg>Cast (int)analogRead() to avoid unsigned arithmetic #59<commit_after>/*
 * Joystick driver
 *
 * Copyright (C)2016 Laurentiu Badea
 *
 * This file may be redistributed under the terms of the MIT license.
 * A copy of this license has been included with this distribution in the file LICENSE.
 */

#include <Arduino.h>
#include "joystick.h"

/*
 * Interrupt handler triggered by joystick button click
 */
volatile static int button_clicked = false;
void button_click(){
    button_clicked = true;
}

Joystick::Joystick(int sw_pin, int x_pin, int y_pin)
:sw_pin(sw_pin),
 x_pin(x_pin),
 y_pin(y_pin)
{
    pinMode(sw_pin, INPUT_PULLUP);
    pinMode(x_pin, INPUT);
    pinMode(y_pin, INPUT);
    sw_state = HIGH;
    x_state = 0;
    y_state = 0;
    read();
    attachInterrupt(digitalPinToInterrupt(sw_pin), button_click, FALLING);
}

Joystick::~Joystick(void){
    // clean up
    detachInterrupt(digitalPinToInterrupt(sw_pin));
}

unsigned Joystick::read(void){
    unsigned event = EVENT_NONE;
    int current_state;

    if (millis() - last_read < 100){
        return EVENT_NONE;
    }

    // read click switch
    current_state = (button_clicked) ? LOW : digitalRead(sw_pin);
    if (current_state != sw_state){
        sw_state = current_state;
        if (sw_state == LOW){
            event |= EVENT_OK;
            for (int i=50; i && digitalRead(sw_pin) == LOW; i--){
                delay(10);
            };
        }
        button_clicked = false;
    }

    // read X position
    current_state = getPositionX();
    if (current_state > x_state && current_state > 0){
        event |= EVENT_RIGHT;
    } else if (current_state < x_state && current_state < 0){
        event |= EVENT_LEFT;
    }
    x_state = current_state;

    // read Y position
    current_state = getPositionY();
    if (current_state > y_state && current_state > 0){
        event |= EVENT_UP;
    } else if (current_state < y_state && current_state < 0){
        event |= EVENT_DOWN;
    }
    y_state = current_state;

    last_read = millis();
    return event;
}

int Joystick::getPositionX(void){
    return ((int)analogRead(x_pin)-512+(1<<(sensitivity-1))) >> sensitivity;
}

int Joystick::getPositionY(void){
    return (512-(int)analogRead(y_pin)+(1<<(sensitivity-1))) >> sensitivity;
}

bool Joystick::getButtonState(void){
    return digitalRead(sw_pin) == LOW;
}
<|endoftext|>