<commit_before>/*
 * Copyright 2008 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */
// .SECTION Thanks
// Thanks to Philippe Pebay from Sandia National Laboratories
// for implementing this test.

#include "vtkDoubleArray.h"
#include "vtkStringArray.h"
#include "vtkTable.h"
#include "vtkOrderStatistics.h"
#include "vtkMultiBlockDataSet.h"

#include <vtkstd/map>
//=============================================================================
int TestOrderStatistics( int, char *[] )
{
  int testStatus = 0;

  double mingledData[] =
    {
    46,
    45,
    47,
    49,
    46,
    47,
    46,
    46,
    47,
    46,
    47,
    49,
    49,
    49,
    47,
    45,
    50,
    50,
    46,
    46,
    51,
    50,
    48,
    48,
    52,
    54,
    48,
    47,
    52,
    52,
    49,
    49,
    53,
    54,
    50,
    50,
    53,
    54,
    50,
    52,
    53,
    53,
    50,
    51,
    54,
    54,
    49,
    49,
    52,
    52,
    50,
    51,
    52,
    52,
    49,
    47,
    48,
    48,
    48,
    50,
    46,
    48,
    47,
    47,
    };
  int nVals = 32;

  vtkDoubleArray* dataset1Arr = vtkDoubleArray::New();
  dataset1Arr->SetNumberOfComponents( 1 );
  dataset1Arr->SetName( "Metric 0" );

  vtkDoubleArray* dataset2Arr = vtkDoubleArray::New();
  dataset2Arr->SetNumberOfComponents( 1 );
  dataset2Arr->SetName( "Metric 1" );

  vtkDoubleArray* dataset3Arr = vtkDoubleArray::New();
  dataset3Arr->SetNumberOfComponents( 1 );
  dataset3Arr->SetName( "Metric 2" );

  for ( int i = 0; i < nVals; ++ i )
    {
    int ti = i << 1;
    dataset1Arr->InsertNextValue( mingledData[ti] );
    dataset2Arr->InsertNextValue( mingledData[ti + 1] );
    dataset3Arr->InsertNextValue( -1. );
    }

  vtkTable* datasetTable = vtkTable::New();
  datasetTable->AddColumn( dataset1Arr );
  dataset1Arr->Delete();
  datasetTable->AddColumn( dataset2Arr );
  dataset2Arr->Delete();
  datasetTable->AddColumn( dataset3Arr );
  dataset3Arr->Delete();

  int nMetrics = 3;
  vtkStdString columns[] = { "Metric 1", "Metric 2", "Metric 0" };

  // Set order statistics algorithm and its input data port
  vtkOrderStatistics* os = vtkOrderStatistics::New();

  // First verify that absence of input does not cause trouble
  cout << "## Verifying that absence of input does not cause trouble... ";
  os->Update();
  cout << "done.\n";

  os->SetInput( vtkStatisticsAlgorithm::INPUT_DATA, datasetTable );
  datasetTable->Delete();

  // Select Columns of Interest
  os->AddColumn( "Metric 3" ); // Include invalid Metric 3
  for ( int i = 0; i< nMetrics; ++ i )
    {  // Try to add all valid indices once more
    os->AddColumn( columns[i] );
    }

  // Test Learn only (Derive does not do anything for order statistics)
  os->SetLearnOption( true );
  os->SetAssessOption( false );
  os->Update();

  // Offset between baseline values for each variable
  int valsOffset = 6;

  double valsTest1 [] =
    { 0.,
      32., 46., 47., 49., 51.5, 54.,
      32., 45., 47., 49., 52., 54.,
      32., -1., -1., -1., -1., -1.,
    };

  // Get calculated model
  vtkMultiBlockDataSet* outputMetaDS = vtkMultiBlockDataSet::SafeDownCast( os->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
  vtkTable* outputPrimary = vtkTable::SafeDownCast( outputMetaDS->GetBlock( 0 ) );

  cout << "## Calculated the following 5-points statistics with InverseCDFAveragedSteps quantile definition):\n";
  for ( vtkIdType r = 0; r < outputPrimary->GetNumberOfRows(); ++ r )
    {
    cout << "   ";
    for ( int i = 0; i < outputPrimary->GetNumberOfColumns(); ++ i )
      {
      cout << outputPrimary->GetColumnName( i )
           << "="
           << outputPrimary->GetValue( r, i ).ToString()
           << "  ";

      // Verify some of the calculated primary statistics
      if ( i && outputPrimary->GetValue( r, i ).ToDouble() - valsTest1[r * valsOffset + i] > 1.e-6 )
        {
        vtkGenericWarningMacro("Incorrect 5-points statistics: " << valsTest1[r * valsOffset + i] << ".");
        testStatus = 1;
        }
      }
    cout << "\n";
    }

  // Test Learn and Assess options for quartiles with InverseCDF quantile definition
  os->SetQuantileDefinition( vtkOrderStatistics::InverseCDF );
  os->SetAssessOption( true );
  os->Update();

  double valsTest2 [] =
    { 0.,
      32., 46., 47., 49., 51., 54.,
      32., 45., 47., 49., 52., 54.,
      32., -1., -1., -1., -1., -1.,
    };

  // Get calculated model
  outputMetaDS = vtkMultiBlockDataSet::SafeDownCast( os->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
  outputPrimary = vtkTable::SafeDownCast( outputMetaDS->GetBlock( 0 ) );

  cout << "## Calculated the following 5-points statistics with InverseCDF quantile definition:\n";
  for ( vtkIdType r = 0; r < outputPrimary->GetNumberOfRows(); ++ r )
    {
    cout << "   ";
    for ( int i = 0; i < outputPrimary->GetNumberOfColumns(); ++ i )
      {
      cout << outputPrimary->GetColumnName( i )
           << "="
           << outputPrimary->GetValue( r, i ).ToString()
           << "  ";

      // Verify some of the calculated primary statistics
      if ( i && outputPrimary->GetValue( r, i ).ToDouble() - valsTest1[r * valsOffset + i] > 1.e-6 )
        {
        vtkGenericWarningMacro("Incorrect 5-points statistics: " << valsTest2[r * valsOffset + i] << ".");
        testStatus = 1;
        }
      }
    cout << "\n";
    }

  // Get output (annotated) data
  vtkTable* outputData = os->GetOutput( vtkStatisticsAlgorithm::OUTPUT_DATA );
  vtkstd::map<int,int> histoMetric[2];
  for ( vtkIdType r = 0; r < outputData->GetNumberOfRows(); ++ r )
    {
    ++ histoMetric[0][outputData->GetValueByName( r, "Quantile(Metric 0)" ).ToInt()];
    ++ histoMetric[1][outputData->GetValueByName( r, "Quantile(Metric 1)" ).ToInt()];
    }

  int cpt[] = { 0, 0 };
  cout << "## Calculated the following histograms:\n";
  for ( int i = 0; i < 2; ++ i )
    {
    cout << "   "
         << outputData->GetColumnName( i )
         << ":\n";

    for ( vtkstd::map<int,int>::iterator it = histoMetric[i].begin();
          it != histoMetric[i].end(); ++ it )
      {
      cpt[i] += it->second;
      cout << "    "
           << it->first
           << " |-> "
           << it->second
           << "\n";
      }

    if ( cpt[i] != outputData->GetNumberOfRows() )
      {
      vtkGenericWarningMacro("Incorrect histogram count: " << cpt[i] << " != " << outputData->GetNumberOfRows() << ".");
      testStatus = 1;
      }
    }

  // Test Learn option for deciles with InverseCDF quantile definition (as with Octave)
  os->SetQuantileDefinition( 0 ); // 0: vtkOrderStatistics::InverseCDF
  os->SetNumberOfIntervals( 10 );
  os->SetAssessOption( false );
  os->Update();

  // Get calculated model
  outputMetaDS = vtkMultiBlockDataSet::SafeDownCast( os->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
  outputPrimary = vtkTable::SafeDownCast( outputMetaDS->GetBlock( 0 ) );

  cout << "## Calculated the following deciles with InverseCDF quantile definition:\n";
  for ( vtkIdType r = 0; r < outputPrimary->GetNumberOfRows(); ++ r )
    {
    cout << "   ";
    for ( int i = 0; i < outputPrimary->GetNumberOfColumns(); ++ i )
      {
      cout << outputPrimary->GetColumnName( i )
           << "="
           << outputPrimary->GetValue( r, i ).ToString()
           << "  ";
      }
    cout << "\n";
    }

  // Test Learn option for quartiles with non-numeric ordinal data
  vtkStdString text[] = {
    "an",
    "ordinal",
    "scale",
    "defines",
    "a",
    "total",
    "preorder",
    "of",
    "objects",
    "the",
    "scale",
    "values",
    "themselves",
    "have",
    "a",
    "total",
    "order",
    "names",
    "may",
    "be",
    "used",
    "like",
    "bad",
    "medium",
    "good",
    "if",
    "numbers",
    "are",
    "used",
    "they",
    "are",
    "only",
    "relevant",
    "up",
    "to",
    "strictly",
    "monotonically",
    "increasing",
    "transformations",
    "order",
    "isomorphism"
  };
  int textLength = 41;

  vtkStringArray* textArr = vtkStringArray::New();
  textArr->SetNumberOfComponents( 1 );
  textArr->SetName( "Text" );

  for ( int i = 0; i < textLength; ++ i )
    {
    textArr->InsertNextValue( text[i] );
    }

  vtkTable* textTable = vtkTable::New();
  textTable->AddColumn( textArr );
  textArr->Delete();

  os->SetInput( vtkStatisticsAlgorithm::INPUT_DATA, textTable );
  textTable->Delete();
  os->ResetAllColumnStates(); // Clear list of columns of interest
  os->AddColumn( "Text" ); // Add column of interest

  // Test Learn and Assess with 4 intervals (use SetParameter method for Learn parameters)
  os->SetParameter( "QuantileDefinition", 0, 0 ); // Does not matter and should be ignored by the engine as the column contains strings
  os->SetParameter( "NumberOfIntervals", 0, 4 );
  os->SetLearnOption( true );
  os->SetAssessOption( true );
  os->Update();

  // Get calculated model
  outputMetaDS = vtkMultiBlockDataSet::SafeDownCast( os->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
  outputPrimary = vtkTable::SafeDownCast( outputMetaDS->GetBlock( 0 ) );

  cout << "## Calculated the following 5-points statistics with non-numerical ordinal data (letters):\n";
  for ( vtkIdType r = 0; r < outputPrimary->GetNumberOfRows(); ++ r )
    {
    cout << "   ";
    for ( int i = 0; i < outputPrimary->GetNumberOfColumns(); ++ i )
      {
      cout << outputPrimary->GetColumnName( i )
           << "="
           << outputPrimary->GetValue( r, i ).ToString()
           << "  ";
      }
    cout << "\n";
    }

  vtkstd::map<int,int> histoText;
  for ( vtkIdType r = 0; r < outputData->GetNumberOfRows(); ++ r )
    {
    ++ histoText[outputData->GetValueByName( r, "Quantile(Text)" ).ToInt()];
    }

  int sum = 0;
  cout << "## Calculated the following histogram:\n";
  cout << "   "
       << outputData->GetColumnName( 0 )
       << ":\n";

  for ( vtkstd::map<int,int>::iterator it = histoText.begin(); it != histoText.end(); ++ it )
    {
    sum += it->second;
    cout << "    "
         << it->first
         << " |-> "
         << it->second
         << "\n";
    }

  if ( sum != outputData->GetNumberOfRows() )
    {
    vtkGenericWarningMacro("Incorrect histogram count: " << sum << " != " << outputData->GetNumberOfRows() << ".");
    testStatus = 1;
    }

  os->Delete();

  return testStatus;
}
<commit_msg>ENH: added empty input test (good practice)<commit_after>/*
 * Copyright 2008 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */
// .SECTION Thanks
// Thanks to Philippe Pebay from Sandia National Laboratories
// for implementing this test.

#include "vtkDoubleArray.h"
#include "vtkStringArray.h"
#include "vtkTable.h"
#include "vtkOrderStatistics.h"
#include "vtkMultiBlockDataSet.h"

#include <vtkstd/map>
//=============================================================================
int TestOrderStatistics( int, char *[] )
{
  int testStatus = 0;

  double mingledData[] =
    {
    46,
    45,
    47,
    49,
    46,
    47,
    46,
    46,
    47,
    46,
    47,
    49,
    49,
    49,
    47,
    45,
    50,
    50,
    46,
    46,
    51,
    50,
    48,
    48,
    52,
    54,
    48,
    47,
    52,
    52,
    49,
    49,
    53,
    54,
    50,
    50,
    53,
    54,
    50,
    52,
    53,
    53,
    50,
    51,
    54,
    54,
    49,
    49,
    52,
    52,
    50,
    51,
    52,
    52,
    49,
    47,
    48,
    48,
    48,
    50,
    46,
    48,
    47,
    47,
    };
  int nVals = 32;

  vtkDoubleArray* dataset1Arr = vtkDoubleArray::New();
  dataset1Arr->SetNumberOfComponents( 1 );
  dataset1Arr->SetName( "Metric 0" );

  vtkDoubleArray* dataset2Arr = vtkDoubleArray::New();
  dataset2Arr->SetNumberOfComponents( 1 );
  dataset2Arr->SetName( "Metric 1" );

  vtkDoubleArray* dataset3Arr = vtkDoubleArray::New();
  dataset3Arr->SetNumberOfComponents( 1 );
  dataset3Arr->SetName( "Metric 2" );

  for ( int i = 0; i < nVals; ++ i )
    {
    int ti = i << 1;
    dataset1Arr->InsertNextValue( mingledData[ti] );
    dataset2Arr->InsertNextValue( mingledData[ti + 1] );
    dataset3Arr->InsertNextValue( -1. );
    }

  vtkTable* datasetTable = vtkTable::New();
  datasetTable->AddColumn( dataset1Arr );
  dataset1Arr->Delete();
  datasetTable->AddColumn( dataset2Arr );
  dataset2Arr->Delete();
  datasetTable->AddColumn( dataset3Arr );
  dataset3Arr->Delete();

  int nMetrics = 3;
  vtkStdString columns[] = { "Metric 1", "Metric 2", "Metric 0" };

  // Set order statistics algorithm and its input data port
  vtkOrderStatistics* os = vtkOrderStatistics::New();

  // First verify that absence of input does not cause trouble
  cout << "## Verifying that absence of input does not cause trouble... ";
  os->Update();
  cout << "done.\n";

  // Prepare first test with data
  os->SetInput( vtkStatisticsAlgorithm::INPUT_DATA, datasetTable );
  datasetTable->Delete();

  // Select Columns of Interest
  os->AddColumn( "Metric 3" ); // Include invalid Metric 3
  for ( int i = 0; i< nMetrics; ++ i )
    {  // Try to add all valid indices once more
    os->AddColumn( columns[i] );
    }

  // Test Learn only (Derive does not do anything for order statistics)
  os->SetLearnOption( true );
  os->SetAssessOption( false );
  os->Update();

  // Offset between baseline values for each variable
  int valsOffset = 6;

  double valsTest1 [] =
    { 0.,
      32., 46., 47., 49., 51.5, 54.,
      32., 45., 47., 49., 52., 54.,
      32., -1., -1., -1., -1., -1.,
    };

  // Get calculated model
  vtkMultiBlockDataSet* outputMetaDS = vtkMultiBlockDataSet::SafeDownCast( os->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
  vtkTable* outputPrimary = vtkTable::SafeDownCast( outputMetaDS->GetBlock( 0 ) );

  cout << "## Calculated the following 5-points statistics with InverseCDFAveragedSteps quantile definition):\n";
  for ( vtkIdType r = 0; r < outputPrimary->GetNumberOfRows(); ++ r )
    {
    cout << "   ";
    for ( int i = 0; i < outputPrimary->GetNumberOfColumns(); ++ i )
      {
      cout << outputPrimary->GetColumnName( i )
           << "="
           << outputPrimary->GetValue( r, i ).ToString()
           << "  ";

      // Verify some of the calculated primary statistics
      if ( i && outputPrimary->GetValue( r, i ).ToDouble() - valsTest1[r * valsOffset + i] > 1.e-6 )
        {
        vtkGenericWarningMacro("Incorrect 5-points statistics: " << valsTest1[r * valsOffset + i] << ".");
        testStatus = 1;
        }
      }
    cout << "\n";
    }

  // Test Learn and Assess options for quartiles with InverseCDF quantile definition
  os->SetQuantileDefinition( vtkOrderStatistics::InverseCDF );
  os->SetAssessOption( true );
  os->Update();

  double valsTest2 [] =
    { 0.,
      32., 46., 47., 49., 51., 54.,
      32., 45., 47., 49., 52., 54.,
      32., -1., -1., -1., -1., -1.,
    };

  // Get calculated model
  outputMetaDS = vtkMultiBlockDataSet::SafeDownCast( os->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
  outputPrimary = vtkTable::SafeDownCast( outputMetaDS->GetBlock( 0 ) );

  cout << "## Calculated the following 5-points statistics with InverseCDF quantile definition:\n";
  for ( vtkIdType r = 0; r < outputPrimary->GetNumberOfRows(); ++ r )
    {
    cout << "   ";
    for ( int i = 0; i < outputPrimary->GetNumberOfColumns(); ++ i )
      {
      cout << outputPrimary->GetColumnName( i )
           << "="
           << outputPrimary->GetValue( r, i ).ToString()
           << "  ";

      // Verify some of the calculated primary statistics
      if ( i && outputPrimary->GetValue( r, i ).ToDouble() - valsTest1[r * valsOffset + i] > 1.e-6 )
        {
        vtkGenericWarningMacro("Incorrect 5-points statistics: " << valsTest2[r * valsOffset + i] << ".");
        testStatus = 1;
        }
      }
    cout << "\n";
    }

  // Get output (annotated) data
  vtkTable* outputData = os->GetOutput( vtkStatisticsAlgorithm::OUTPUT_DATA );
  vtkstd::map<int,int> histoMetric[2];
  for ( vtkIdType r = 0; r < outputData->GetNumberOfRows(); ++ r )
    {
    ++ histoMetric[0][outputData->GetValueByName( r, "Quantile(Metric 0)" ).ToInt()];
    ++ histoMetric[1][outputData->GetValueByName( r, "Quantile(Metric 1)" ).ToInt()];
    }

  int cpt[] = { 0, 0 };
  cout << "## Calculated the following histograms:\n";
  for ( int i = 0; i < 2; ++ i )
    {
    cout << "   "
         << outputData->GetColumnName( i )
         << ":\n";

    for ( vtkstd::map<int,int>::iterator it = histoMetric[i].begin();
          it != histoMetric[i].end(); ++ it )
      {
      cpt[i] += it->second;
      cout << "    "
           << it->first
           << " |-> "
           << it->second
           << "\n";
      }

    if ( cpt[i] != outputData->GetNumberOfRows() )
      {
      vtkGenericWarningMacro("Incorrect histogram count: " << cpt[i] << " != " << outputData->GetNumberOfRows() << ".");
      testStatus = 1;
      }
    }

  // Test Learn option for deciles with InverseCDF quantile definition (as with Octave)
  os->SetQuantileDefinition( 0 ); // 0: vtkOrderStatistics::InverseCDF
  os->SetNumberOfIntervals( 10 );
  os->SetAssessOption( false );
  os->Update();

  // Get calculated model
  outputMetaDS = vtkMultiBlockDataSet::SafeDownCast( os->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
  outputPrimary = vtkTable::SafeDownCast( outputMetaDS->GetBlock( 0 ) );

  cout << "## Calculated the following deciles with InverseCDF quantile definition:\n";
  for ( vtkIdType r = 0; r < outputPrimary->GetNumberOfRows(); ++ r )
    {
    cout << "   ";
    for ( int i = 0; i < outputPrimary->GetNumberOfColumns(); ++ i )
      {
      cout << outputPrimary->GetColumnName( i )
           << "="
           << outputPrimary->GetValue( r, i ).ToString()
           << "  ";
      }
    cout << "\n";
    }

  // Test Learn option for quartiles with non-numeric ordinal data
  vtkStdString text[] = {
    "an",
    "ordinal",
    "scale",
    "defines",
    "a",
    "total",
    "preorder",
    "of",
    "objects",
    "the",
    "scale",
    "values",
    "themselves",
    "have",
    "a",
    "total",
    "order",
    "names",
    "may",
    "be",
    "used",
    "like",
    "bad",
    "medium",
    "good",
    "if",
    "numbers",
    "are",
    "used",
    "they",
    "are",
    "only",
    "relevant",
    "up",
    "to",
    "strictly",
    "monotonically",
    "increasing",
    "transformations",
    "order",
    "isomorphism"
  };
  int textLength = 41;

  vtkStringArray* textArr = vtkStringArray::New();
  textArr->SetNumberOfComponents( 1 );
  textArr->SetName( "Text" );

  for ( int i = 0; i < textLength; ++ i )
    {
    textArr->InsertNextValue( text[i] );
    }

  vtkTable* textTable = vtkTable::New();
  textTable->AddColumn( textArr );
  textArr->Delete();

  os->SetInput( vtkStatisticsAlgorithm::INPUT_DATA, textTable );
  textTable->Delete();
  os->ResetAllColumnStates(); // Clear list of columns of interest
  os->AddColumn( "Text" ); // Add column of interest

  // Test Learn and Assess with 4 intervals (use SetParameter method for Learn parameters)
  os->SetParameter( "QuantileDefinition", 0, 0 ); // Does not matter and should be ignored by the engine as the column contains strings
  os->SetParameter( "NumberOfIntervals", 0, 4 );
  os->SetLearnOption( true );
  os->SetAssessOption( true );
  os->Update();

  // Get calculated model
  outputMetaDS = vtkMultiBlockDataSet::SafeDownCast( os->GetOutputDataObject( vtkStatisticsAlgorithm::OUTPUT_MODEL ) );
  outputPrimary = vtkTable::SafeDownCast( outputMetaDS->GetBlock( 0 ) );

  cout << "## Calculated the following 5-points statistics with non-numerical ordinal data (letters):\n";
  for ( vtkIdType r = 0; r < outputPrimary->GetNumberOfRows(); ++ r )
    {
    cout << "   ";
    for ( int i = 0; i < outputPrimary->GetNumberOfColumns(); ++ i )
      {
      cout << outputPrimary->GetColumnName( i )
           << "="
           << outputPrimary->GetValue( r, i ).ToString()
           << "  ";
      }
    cout << "\n";
    }

  vtkstd::map<int,int> histoText;
  for ( vtkIdType r = 0; r < outputData->GetNumberOfRows(); ++ r )
    {
    ++ histoText[outputData->GetValueByName( r, "Quantile(Text)" ).ToInt()];
    }

  int sum = 0;
  cout << "## Calculated the following histogram:\n";
  cout << "   "
       << outputData->GetColumnName( 0 )
       << ":\n";

  for ( vtkstd::map<int,int>::iterator it = histoText.begin(); it != histoText.end(); ++ it )
    {
    sum += it->second;
    cout << "    "
         << it->first
         << " |-> "
         << it->second
         << "\n";
    }

  if ( sum != outputData->GetNumberOfRows() )
    {
    vtkGenericWarningMacro("Incorrect histogram count: " << sum << " != " << outputData->GetNumberOfRows() << ".");
    testStatus = 1;
    }

  os->Delete();

  return testStatus;
}
<|endoftext|>


<commit_before>#include "Sink.hpp"

#include <iostream>

#include <ocl/Component.hpp>
#include <rtt/Service.hpp>

#include "boost/tuple/tuple.hpp"
#include <boost/algorithm/string.hpp>

#include "DTFactory.hpp"

using namespace RTT;

namespace DataTracer
{
  Sink::Sink(string const& name) :
      TaskContext(name), m_ports()
  {
    m_policy.type = ConnPolicy::DATA;
    m_policy.init = true;
    m_policy.lock_policy = ConnPolicy::LOCK_FREE;

    setupComponentInterface();
  }

  Sink::~Sink() {}

  void Sink::setupComponentInterface()
  {
        this->addOperation("addTrace",&Sink::addTrace,this);

        this->addPort("buffer", buffer).doc("Connect to FileWriter");
  }

  base::PortInterface* Sink::find_foreign_port(std::string foreign_port)
  {
    // Check if the port exists
    base::PortInterface* port(NULL);
    std::vector<std::string> address;
    boost::split(address, foreign_port, boost::is_any_of("."));
    if(address.size() != 2 && address.size() != 3)
    {
      log(Error) << "Cannot use the supplied string to find the foreign_port: "<< foreign_port << endlog();
      log(Info) << "Use: component.port or component.service.port" << endlog();
      return false;
    }

    TaskContext* task_ptr(getPeer(address[0]));
    if(task_ptr == NULL)
    {
      log(Error) << "Cannot find the peer component (" << address[0] << ")." << endlog();
      return NULL;
    }

    if(address.size() == 2)
    {
      port = task_ptr->getPort(address[1]);
    }
    else if(address.size() == 3)
    {
      Service::shared_ptr service( task_ptr->provides(address[1]) );
      if(service == NULL)
      {
        log(Error) << "Cannot find the service (" << address[1] << ") in peer component (" << address[0] << ")." << endlog();
        return NULL;
      }

      port = service->getPort(address[2]);
    }

    if(port == NULL)
    {
      if(address.size () == 2)
        log(Error) << "Cannot find port (" << address[1] << ") in peer component (" << address[0] << ")." << endlog();
      else
        log(Error) << "Cannot find port (" << address[2] << ") in service (" << address[1] << ") of peer component (" << address[0] << ")." << endlog();
      return NULL;
    }

    return port;
  }

  bool Sink::addTrace(std::string foreign_port)
  {
    if(this->getTaskState() == RTT::base::TaskCore::Stopped)
    {
      // check if it is not already traced
      for(unsigned int i = 0; i < m_ports.size(); ++i)
      {
        if( !foreign_port.compare( *(m_ports[i]->port_name) ) )
        {
          log(Error) << "Port (" << foreign_port << ") already traced." << endlog();
          return false;
        }
      }

      // Find the output port
      base::PortInterface* port(NULL);
      if( (port = find_foreign_port(foreign_port)) == NULL)
      {
        return false;
      }

      // check if it is an output port
      base::OutputPortInterface* outp_port(NULL);
      outp_port = dynamic_cast<base::OutputPortInterface*>(port);
      if(outp_port == NULL)
      {
        log(Error) << "Cannot trace an input port, please use the corresponding output port." << endlog();
        return false;
      }

      // create antiClone -> InputPortInterface
      base::PortInterface* tptr(outp_port->antiClone());

      base::InputPortInterface* inp_port(dynamic_cast<base::InputPortInterface*>(tptr));
      if(inp_port == NULL)
      {
        log(Error) << "Could not convert the antiClone" << endlog(); // this should not happen
        return false;
      }

      // Change all '.' into '_' -> generates 'unique' ports
      std::string tmp(foreign_port);
      boost::replace_all(tmp, ".", "_");
      std::string* port_name_ptr(new std::string(tmp));// create permanent string

      // Set name to port_name
      inp_port->setName(*port_name_ptr);

      // create variable for intermediate storage
      ITraceTuple* tuple = DTFactory::Instance()->CreateObject(inp_port->getTypeInfo()->getTypeName());

      if(tuple == NULL)
      {
        log(Info) << "DTFactory failed, type unknown." << endlog();
        return false;
      }

      // add port to interface
      std::stringstream doc;
      this->addPort(*port_name_ptr, *inp_port).doc(doc.str());

      // Create stream
      outp_port->connectTo(inp_port, m_policy); // connection policy

      // Store in port database
      tuple->port_name.reset(port_name_ptr);
      tuple->port.reset(inp_port);
      m_ports.push_back(boost::shared_ptr<ITraceTuple>(tuple));

      log(Info) << "Added trace: " << *port_name_ptr << endlog();
      return true;
    }
    else
    {
      log(Info) << "Can only add trace in STOPPED state." << endlog();
      return false;
    }
  }

  bool Sink::startHook()
  {
    unsigned int buffer_space(1); // 0 == base time (backup, for other messages that do not have time stamps)
    std::stringstream column_buffer;
    column_buffer << "time, ";

    for(unsigned int i = 0; i < m_ports.size(); ++i)
    {
      if(!m_ports[i]->configure())// Determine amongst others the number of data elements of each port
      {
        log(Error) << "Could not configure port: " << *(m_ports[i]->port_name) << endlog();
        return false;
      }
      buffer_space += m_ports[i]->nr_of_elements;

      if(!m_ports[i]->getElementNames(column_buffer))
      {
        log(Error) << "Could not get the column names for port: " << *(m_ports[i]->port_name) << endlog();
        return false;
      }
    }

    // Create the write buffer
    m_buffer.data.resize(buffer_space, 0.0);
    buffer.setDataSample(m_buffer);

    // Setup buffer refs
    unsigned int elems = 1;
    for(unsigned int i = 0; i < m_ports.size(); ++i)
    {
      m_ports[i]->buffer = m_buffer.data.begin()+elems;
      elems += m_ports[i]->nr_of_elements;
    }

    // store column names in file writer
    OperationCaller<void(std::string) > op_setColumnNames;
    TaskContext* task_ptr = getPeer("FileWriter");
    if(task_ptr == NULL)
    {
      log(Error) << "Could not find peer FileWriter" << endlog();
      return false;
    }
    op_setColumnNames = task_ptr->getOperation("writeLine");

    if(!op_setColumnNames.ready())
    {
      log(Error) << "Could not connect to FileWriter.writeLine" << endlog();
      return false;
    }
    op_setColumnNames(column_buffer.str());

    m_start_time = ros::Time::now();

    return TaskContext::startHook();
  }

  void Sink::updateHook()
  {
    TaskContext::updateHook();

    m_buffer.data[0] = (ros::Time::now() - m_start_time).toSec();

    for(unsigned int i = 0; i < m_ports.size(); ++i)
    {
      m_ports[i]->readAndConvert();
    }

    buffer.write(m_buffer);
  }
}

ORO_CREATE_COMPONENT( DataTracer::Sink )
<commit_msg>Fixed bug for column names.<commit_after>#include "Sink.hpp"

#include <iostream>

#include <ocl/Component.hpp>
#include <rtt/Service.hpp>

#include "boost/tuple/tuple.hpp"
#include <boost/algorithm/string.hpp>

#include "DTFactory.hpp"

using namespace RTT;

namespace DataTracer
{
  Sink::Sink(string const& name) :
      TaskContext(name), m_ports()
  {
    m_policy.type = ConnPolicy::DATA;
    m_policy.init = true;
    m_policy.lock_policy = ConnPolicy::LOCK_FREE;

    setupComponentInterface();
  }

  Sink::~Sink() {}

  void Sink::setupComponentInterface()
  {
        this->addOperation("addTrace",&Sink::addTrace,this);

        this->addPort("buffer", buffer).doc("Connect to FileWriter");
  }

  base::PortInterface* Sink::find_foreign_port(std::string foreign_port)
  {
    // Check if the port exists
    base::PortInterface* port(NULL);
    std::vector<std::string> address;
    boost::split(address, foreign_port, boost::is_any_of("."));
    if(address.size() != 2 && address.size() != 3)
    {
      log(Error) << "Cannot use the supplied string to find the foreign_port: "<< foreign_port << endlog();
      log(Info) << "Use: component.port or component.service.port" << endlog();
      return false;
    }

    TaskContext* task_ptr(getPeer(address[0]));
    if(task_ptr == NULL)
    {
      log(Error) << "Cannot find the peer component (" << address[0] << ")." << endlog();
      return NULL;
    }

    if(address.size() == 2)
    {
      port = task_ptr->getPort(address[1]);
    }
    else if(address.size() == 3)
    {
      Service::shared_ptr service( task_ptr->provides(address[1]) );
      if(service == NULL)
      {
        log(Error) << "Cannot find the service (" << address[1] << ") in peer component (" << address[0] << ")." << endlog();
        return NULL;
      }

      port = service->getPort(address[2]);
    }

    if(port == NULL)
    {
      if(address.size () == 2)
        log(Error) << "Cannot find port (" << address[1] << ") in peer component (" << address[0] << ")." << endlog();
      else
        log(Error) << "Cannot find port (" << address[2] << ") in service (" << address[1] << ") of peer component (" << address[0] << ")." << endlog();
      return NULL;
    }

    return port;
  }

  bool Sink::addTrace(std::string foreign_port)
  {
    if(this->getTaskState() == RTT::base::TaskCore::Stopped)
    {
      // check if it is not already traced
      for(unsigned int i = 0; i < m_ports.size(); ++i)
      {
        if( !foreign_port.compare( *(m_ports[i]->port_name) ) )
        {
          log(Error) << "Port (" << foreign_port << ") already traced." << endlog();
          return false;
        }
      }

      // Find the output port
      base::PortInterface* port(NULL);
      if( (port = find_foreign_port(foreign_port)) == NULL)
      {
        return false;
      }

      // check if it is an output port
      base::OutputPortInterface* outp_port(NULL);
      outp_port = dynamic_cast<base::OutputPortInterface*>(port);
      if(outp_port == NULL)
      {
        log(Error) << "Cannot trace an input port, please use the corresponding output port." << endlog();
        return false;
      }

      // create antiClone -> InputPortInterface
      base::PortInterface* tptr(outp_port->antiClone());

      base::InputPortInterface* inp_port(dynamic_cast<base::InputPortInterface*>(tptr));
      if(inp_port == NULL)
      {
        log(Error) << "Could not convert the antiClone" << endlog(); // this should not happen
        return false;
      }

      // Change all '.' into '_' -> generates 'unique' ports
      std::string tmp(foreign_port);
      boost::replace_all(tmp, ".", "_");
      std::string* port_name_ptr(new std::string(tmp));// create permanent string

      // Set name to port_name
      inp_port->setName(*port_name_ptr);

      // create variable for intermediate storage
      ITraceTuple* tuple = DTFactory::Instance()->CreateObject(inp_port->getTypeInfo()->getTypeName());

      if(tuple == NULL)
      {
        log(Info) << "DTFactory failed, type unknown." << endlog();
        return false;
      }

      // add port to interface
      std::stringstream doc;
      this->addPort(*port_name_ptr, *inp_port).doc(doc.str());

      // Create stream
      outp_port->connectTo(inp_port, m_policy); // connection policy

      // Store in port database
      tuple->port_name.reset(port_name_ptr);
      tuple->port.reset(inp_port);
      m_ports.push_back(boost::shared_ptr<ITraceTuple>(tuple));

      log(Info) << "Added trace: " << *port_name_ptr << endlog();
      return true;
    }
    else
    {
      log(Info) << "Can only add trace in STOPPED state." << endlog();
      return false;
    }
  }

  bool Sink::startHook()
  {
    unsigned int buffer_space(1); // 0 == base time (backup, for other messages that do not have time stamps)
    std::stringstream column_buffer;
    column_buffer << "time, ";

    for(unsigned int i = 0; i < m_ports.size(); ++i)
    {
      if(!m_ports[i]->configure())// Determine amongst others the number of data elements of each port
      {
        log(Error) << "Could not configure port: " << *(m_ports[i]->port_name) << endlog();
        return false;
      }
      buffer_space += m_ports[i]->nr_of_elements;

      if(i != 0)
      {
        column_buffer << ", ";
      }

      if(!m_ports[i]->getElementNames(column_buffer))
      {
        log(Error) << "Could not get the column names for port: " << *(m_ports[i]->port_name) << endlog();
        return false;
      }
    }

    // Create the write buffer
    m_buffer.data.resize(buffer_space, 0.0);
    buffer.setDataSample(m_buffer);

    // Setup buffer refs
    unsigned int elems = 1;
    for(unsigned int i = 0; i < m_ports.size(); ++i)
    {
      m_ports[i]->buffer = m_buffer.data.begin()+elems;
      elems += m_ports[i]->nr_of_elements;
    }

    // store column names in file writer
    OperationCaller<void(std::string) > op_setColumnNames;
    TaskContext* task_ptr = getPeer("FileWriter");
    if(task_ptr == NULL)
    {
      log(Error) << "Could not find peer FileWriter" << endlog();
      return false;
    }
    op_setColumnNames = task_ptr->getOperation("writeLine");

    if(!op_setColumnNames.ready())
    {
      log(Error) << "Could not connect to FileWriter.writeLine" << endlog();
      return false;
    }
    op_setColumnNames(column_buffer.str());

    m_start_time = ros::Time::now();

    return TaskContext::startHook();
  }

  void Sink::updateHook()
  {
    TaskContext::updateHook();

    m_buffer.data[0] = (ros::Time::now() - m_start_time).toSec();

    for(unsigned int i = 0; i < m_ports.size(); ++i)
    {
      m_ports[i]->readAndConvert();
    }

    buffer.write(m_buffer);
  }
}

ORO_CREATE_COMPONENT( DataTracer::Sink )
<|endoftext|>


<commit_before>/*=========================================================================
  Author: $Author: krm15 $  // Author of last commit
  Version: $Rev: 667 $  // Revision of last commit
  Date: $Date: 2009-09-16 13:12:21 -0400 (Wed, 16 Sep 2009) $  // Date of last commit
=========================================================================*/

/*=========================================================================
 Authors: The GoFigure Dev. Team.
 at Megason Lab, Systems biology, Harvard Medical school, 2009

 Copyright (c) 2009, President and Fellows of Harvard College.
 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 the name of the  President and Fellows of Harvard College
 nor the names of its contributors may be used to endorse or promote
 products derived from this software without specific prior written
 permission.

 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 COPYRIGHT OWNER 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 "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkImageRegionIterator.h"
#include "itkRegionOfInterestImageFilter.h"

int main ( int argc, char* argv[] )
  {
  if ( argc < 3 )
    {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << " input output <startX> <startY> <startZ> <endX> <endY> <endZ>" << std::endl;
    return EXIT_FAILURE;
    }

  const unsigned int Dimension = 3;
  typedef itk::Image< unsigned char, Dimension > InputImageType;
  typedef itk::ImageFileReader< InputImageType > ReaderType;
  typedef itk::ImageFileWriter< InputImageType > WriterType;
  typedef itk::ImageRegionIterator< InputImageType > IteratorType;
  typedef itk::RegionOfInterestImageFilter< InputImageType,
    InputImageType > ROIFilterType;
  typedef typename InputImageType::RegionType RegionType;
  typedef typename InputImageType::IndexType IndexType;
  typedef typename IndexType::IndexValueType IndexValueType;
  typedef typename InputImageType::SizeType SizeType;
  typedef typename SizeType::SizeValueType SizeValueType;

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName ( argv[1] );
  reader->Update();

  RegionType region = reader->GetOutput()->GetLargestPossibleRegion();
  SizeType size = region.GetSize();

  IndexType start, end;
  start = region.GetIndex();

  if (argc > 3)
    {
    start[0] = static_cast<IndexValueType>( atoi( argv[3] ) );
    start[1] = static_cast<IndexValueType>( atoi( argv[4] ) );
    start[2] = static_cast<IndexValueType>( atoi( argv[5] ) );

    end[0] = static_cast<IndexValueType>( atoi( argv[6] ) );
    end[1] = static_cast<IndexValueType>( atoi( argv[7] ) );
    end[2] = static_cast<IndexValueType>( atoi( argv[8] ) );

    for(unsigned int i=0; i<Dimension; i++)
      {
      size[i] = end[i]-start[i]+1;
      }
    }
  std::cout << size << std::endl;

  InputImageType::RegionType subRegion;
  subRegion.SetIndex( start );
  subRegion.SetSize( size );

  ROIFilterType::Pointer roi = ROIFilterType::New();
  roi->SetInput( reader->GetOutput() );
  roi->SetRegionOfInterest( subRegion );
  roi->Update();

  WriterType::Pointer writer = WriterType::New();
  writer->SetInput ( roi->GetOutput() );
  writer->SetFileName ( argv[2] );

  try
    {
    writer->Update();
    }
  catch ( itk::ExceptionObject e )
    {
    std::cerr << "Error: " << e << std::endl;
    }

  return EXIT_SUCCESS;
  }
<commit_msg>BUG: Typename eliminated<commit_after>/*=========================================================================
  Author: $Author: krm15 $  // Author of last commit
  Version: $Rev: 667 $  // Revision of last commit
  Date: $Date: 2009-09-16 13:12:21 -0400 (Wed, 16 Sep 2009) $  // Date of last commit
=========================================================================*/

/*=========================================================================
 Authors: The GoFigure Dev. Team.
 at Megason Lab, Systems biology, Harvard Medical school, 2009

 Copyright (c) 2009, President and Fellows of Harvard College.
 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 the name of the  President and Fellows of Harvard College
 nor the names of its contributors may be used to endorse or promote
 products derived from this software without specific prior written
 permission.

 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 COPYRIGHT OWNER 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 "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkImageRegionIterator.h"
#include "itkRegionOfInterestImageFilter.h"

int main ( int argc, char* argv[] )
  {
  if ( argc < 3 )
    {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] << " input output <startX> <startY> <startZ> <endX> <endY> <endZ>" << std::endl;
    return EXIT_FAILURE;
    }

  const unsigned int Dimension = 3;
  typedef itk::Image< unsigned char, Dimension > InputImageType;
  typedef itk::ImageFileReader< InputImageType > ReaderType;
  typedef itk::ImageFileWriter< InputImageType > WriterType;
  typedef itk::ImageRegionIterator< InputImageType > IteratorType;
  typedef itk::RegionOfInterestImageFilter< InputImageType,
    InputImageType > ROIFilterType;
  typedef InputImageType::RegionType RegionType;
  typedef InputImageType::IndexType IndexType;
  typedef IndexType::IndexValueType IndexValueType;
  typedef InputImageType::SizeType SizeType;
  typedef SizeType::SizeValueType SizeValueType;

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName ( argv[1] );
  reader->Update();

  RegionType region = reader->GetOutput()->GetLargestPossibleRegion();
  SizeType size = region.GetSize();

  IndexType start, end;
  start = region.GetIndex();

  if (argc > 3)
    {
    start[0] = static_cast<IndexValueType>( atoi( argv[3] ) );
    start[1] = static_cast<IndexValueType>( atoi( argv[4] ) );
    start[2] = static_cast<IndexValueType>( atoi( argv[5] ) );

    end[0] = static_cast<IndexValueType>( atoi( argv[6] ) );
    end[1] = static_cast<IndexValueType>( atoi( argv[7] ) );
    end[2] = static_cast<IndexValueType>( atoi( argv[8] ) );

    for(unsigned int i=0; i<Dimension; i++)
      {
      size[i] = end[i]-start[i]+1;
      }
    }
  std::cout << size << std::endl;

  InputImageType::RegionType subRegion;
  subRegion.SetIndex( start );
  subRegion.SetSize( size );

  ROIFilterType::Pointer roi = ROIFilterType::New();
  roi->SetInput( reader->GetOutput() );
  roi->SetRegionOfInterest( subRegion );
  roi->Update();

  WriterType::Pointer writer = WriterType::New();
  writer->SetInput ( roi->GetOutput() );
  writer->SetFileName ( argv[2] );

  try
    {
    writer->Update();
    }
  catch ( itk::ExceptionObject e )
    {
    std::cerr << "Error: " << e << std::endl;
    }

  return EXIT_SUCCESS;
  }
<|endoftext|>


<commit_before>//C++ 11ʵֵlexical_castΪ˰boost
//: https://github.com/qicosmos/cosmos

#ifndef CPP_11_LEXICAL_CAST_HPP
#define CPP_11_LEXICAL_CAST_HPP

#include <type_traits>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <stdexcept>
#include <cctype>
#include <cstring>
using namespace std;

namespace detail
{
static const char* strue = "true";
static const char* sfalse = "false";

template <typename To, typename From>
struct Converter
{
};

//to numeric
template <typename From>
struct Converter<int, From>
{
    static int convert(const string& from)
    {
        return std::atoi(from.c_str());
    }

    static int convert(const char* from)
    {
        return std::atoi(from);
    }
};

template <typename From>
struct Converter<long, From>
{
    static long convert(const string& from)
    {
        return std::atol(from.c_str());
    }

    static long convert(const char* from)
    {
        return std::atol(from);
    }
};

template <typename From>
struct Converter<long long, From>
{
    static long long convert(const string& from)
    {
        return std::atoll(from.c_str());
    }

    static long long convert(const char* from)
    {
        return std::atoll(from);
    }
};

template <typename From>
struct Converter<double, From>
{
    static double convert(const string& from)
    {
        return std::atof(from.c_str());
    }

    static double convert(const char* from)
    {
        return std::atof(from);
    }
};

template <typename From>
struct Converter<float, From>
{
    static float convert(const string& from)
    {
        return (float)std::atof(from.c_str());
    }

    static float convert(const char* from)
    {
        return (float)std::atof(from);
    }
};

//to bool
template <typename From>
struct Converter<bool, From>
{
    static typename std::enable_if<std::is_integral<From>::value, bool>::type convert(From from)
    {
        return !!from;
    }
};

static bool checkbool(const char* from, const size_t len, const char* s)
{
    for(size_t i = 0; i < len; i++)
    {
        if(from[i] != s[i])
        {
            return false;
        }
    }

    return true;
}

static bool convert(const char* from)
{
    const unsigned int len = strlen(from);
    if(len != 4 && len != 5)
        throw std::invalid_argument("argument is invalid");

    bool r = true;
    if(len == 4)
    {
        r = checkbool(from, len, strue);

        if(r)
            return true;
    }
    else
    {
        r = checkbool(from, len, sfalse);

        if(r)
            return false;
    }

    throw std::invalid_argument("argument is invalid");
}

template <>
struct Converter<bool, string>
{
    static bool convert(const string& from)
    {
        return detail::convert(from.c_str());
    }
};

template <>
struct Converter<bool, const char*>
{
    static bool convert(const char* from)
    {
        return detail::convert(from);
    }
};

template <>
struct Converter<bool, char*>
{
    static bool convert(char* from)
    {
        return detail::convert(from);
    }
};

template <unsigned N>
struct Converter<bool, const char[N]>
{
    static bool convert(const char(&from)[N])
    {
        return detail::convert(from);
    }
};

template <unsigned N>
struct Converter<bool, char[N]>
{
    static bool convert(const char(&from)[N])
    {
        return detail::convert(from);
    }
};

//to string
template <typename From>
struct Converter<string, From>
{
    static string convert(const From& from)
    {
        return std::to_string(from);
    }
};
}

template <typename To, typename From>
typename std::enable_if < !std::is_same<To, From>::value, To >::type lexical_cast(const From& from)
{
    return detail::Converter<To, From>::convert(from);
}

template <typename To, typename From>
typename std::enable_if<std::is_same<To, From>::value, To>::type lexical_cast(const From& from)
{
    return from;
}

template<typename ValueTYPE>
bool ValueFromString(const std::string& strValue, ValueTYPE& nValue)
{
    try
    {
        nValue = lexical_cast<ValueTYPE>(strValue);
        return true;
    }
    catch(...)
    {
        return false;
    }

    return false;
}

template<typename ValueTYPE>
bool ValueToString(const ValueTYPE& nValue, std::string& strData)
{
    try
    {
        strData = lexical_cast<std::string>(nValue);
        return true;
    }
    catch(...)
    {
        return false;
    }

    return false;
}
#endif //!CPP_11_LEXICAL_CAST_HPP<commit_msg>fix the bug of converting number string to Boolean(lexical_cast)<commit_after>//C++ 11ʵֵlexical_castΪ˰boost
//: https://github.com/qicosmos/cosmos

#ifndef CPP_11_LEXICAL_CAST_HPP
#define CPP_11_LEXICAL_CAST_HPP

#include <type_traits>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <stdexcept>
#include <cctype>
#include <cstring>
using namespace std;

namespace detail
{
static const char* strue = "true";
static const char* sfalse = "false";

template <typename To, typename From>
struct Converter
{
};

//to numeric
template <typename From>
struct Converter<int, From>
{
    static int convert(const string& from)
    {
        return std::atoi(from.c_str());
    }

    static int convert(const char* from)
    {
        return std::atoi(from);
    }
};

template <typename From>
struct Converter<long, From>
{
    static long convert(const string& from)
    {
        return std::atol(from.c_str());
    }

    static long convert(const char* from)
    {
        return std::atol(from);
    }
};

template <typename From>
struct Converter<long long, From>
{
    static long long convert(const string& from)
    {
        return std::atoll(from.c_str());
    }

    static long long convert(const char* from)
    {
        return std::atoll(from);
    }
};

template <typename From>
struct Converter<double, From>
{
    static double convert(const string& from)
    {
        return std::atof(from.c_str());
    }

    static double convert(const char* from)
    {
        return std::atof(from);
    }
};

template <typename From>
struct Converter<float, From>
{
    static float convert(const string& from)
    {
        return (float)std::atof(from.c_str());
    }

    static float convert(const char* from)
    {
        return (float)std::atof(from);
    }
};

//to bool
template <typename From>
struct Converter<bool, From>
{
    static typename std::enable_if<std::is_integral<From>::value, bool>::type convert(From from)
    {
        return !!from;
    }
};

static bool checkbool(const char* from, const size_t len, const char* s)
{
    for(size_t i = 0; i < len; i++)
    {
        if(from[i] != s[i])
        {
            return false;
        }
    }

    return true;
}

static bool convert(const char* from)
{
    const unsigned int len = strlen(from);
    if(len != 4 && len != 5)
        throw std::invalid_argument("argument is invalid");

    bool r = true;
    if(len == 4)
    {
        //"true"
        r = checkbool(from, len, strue);

        if(r)
            return true;
    }
    else if(len == 5)
    {
        //"false"
        r = checkbool(from, len, sfalse);

        if(r)
            return false;
    }
    else
    {
        // תΪbool
        int value = Converter<int, const char*>::convert(from);
        return (value > 0);
    }

    throw std::invalid_argument("argument is invalid");
}

template <>
struct Converter<bool, string>
{
    static bool convert(const string& from)
    {
        return detail::convert(from.c_str());
    }
};

template <>
struct Converter<bool, const char*>
{
    static bool convert(const char* from)
    {
        return detail::convert(from);
    }
};

template <>
struct Converter<bool, char*>
{
    static bool convert(char* from)
    {
        return detail::convert(from);
    }
};

template <unsigned N>
struct Converter<bool, const char[N]>
{
    static bool convert(const char(&from)[N])
    {
        return detail::convert(from);
    }
};

template <unsigned N>
struct Converter<bool, char[N]>
{
    static bool convert(const char(&from)[N])
    {
        return detail::convert(from);
    }
};

//to string
template <typename From>
struct Converter<string, From>
{
    static string convert(const From& from)
    {
        return std::to_string(from);
    }
};
}

template <typename To, typename From>
typename std::enable_if < !std::is_same<To, From>::value, To >::type lexical_cast(const From& from)
{
    return detail::Converter<To, From>::convert(from);
}

template <typename To, typename From>
typename std::enable_if<std::is_same<To, From>::value, To>::type lexical_cast(const From& from)
{
    return from;
}

template<typename ValueTYPE>
bool ValueFromString(const std::string& strValue, ValueTYPE& nValue)
{
    try
    {
        nValue = lexical_cast<ValueTYPE>(strValue);
        return true;
    }
    catch(...)
    {
        return false;
    }

    return false;
}

template<typename ValueTYPE>
bool ValueToString(const ValueTYPE& nValue, std::string& strData)
{
    try
    {
        strData = lexical_cast<std::string>(nValue);
        return true;
    }
    catch(...)
    {
        return false;
    }

    return false;
}
#endif //!CPP_11_LEXICAL_CAST_HPP<|endoftext|>


<commit_before>#include "stdafx.h"
#include "UserTask.h"
#include "UserSessionManager.h"
#include "GameManager.h"
#include "Communication.h"
#include "role\QiDao.h"
#include <boost/algorithm/string.hpp>

uint32_t UserTask::m_sIDSeq = 10000;
using namespace network;

void UserTask::Start()
{
	zTCPTask::Start();
	m_iTmpId = ++m_sIDSeq;

	UserSessionManager::getInstance().AddUserById(m_iTmpId, this);
	//FIXME temporarily disable login
	m_bAuthen = true;
	// TODO : check username & password here
	m_userId = TOQSTR(m_iTmpId);
	m_nickname = m_userId;
	UserSessionManager::getInstance().AddUser(m_userId, this);
}

void UserTask::OnQuit()
{
	zTCPTask::OnQuit();
	ztLoggerWrite(ZONE, e_Debug, "UserTask::OnQuit [%s] ",m_userId.c_str());
	GameGrail* game = getGame();
	if(game){
		game->onUserLeave(m_userId);
	}
	UserSessionManager::getInstance().RemoveUser(m_userId, m_iTmpId);
}

void UserTask::OnCheck()
{
	/*if (!m_bAuthen)
	{
		ztLoggerWrite(ZONE,e_Debug, "OnCheck[%s]: don't authen, kicked off ", m_userId.c_str());
		SetQuit();
		return;
	}*/

	time_t tmNow  = time(NULL);
	int temp = ServerConfig::getInstance().m_iCheckTime;
	if (tmNow - m_activeTime > ServerConfig::getInstance().m_iCheckTime)
	{
		ztLoggerWrite(ZONE,e_Debug, "OnCheck[%s]: heartbeat timeout,be kicked off ", m_userId.c_str());
		UserSessionManager::getInstance().RemoveUser(m_userId, m_iTmpId);
		SetQuit();
		return;
	}
}

GameGrail* UserTask::getGame()
{
	Game *game;
	if(m_tableId < 0){
		return NULL;
	}
	if(0 != GameManager::getInstance().getGame(GAME_TYPE_GRAIL, m_tableId, &game)){
		ztLoggerWrite(ZONE,e_Warning, "UserTask::getGame() failed. TableId: %d", m_tableId);
		return NULL;
	}
	return (GameGrail*)game;
}

bool UserTask::tryNotify(int id, int state, int step, void* reply)
{
	GameGrail*game = getGame();
	if(!game){
		if (reply != NULL)
			delete reply;  // ҪϢͷŵҪʱ棬ֱһɹsetȥReply
		return false;
	}
	bool try_notify_success = game->tryNotify(id, state, step, reply);
	if (!try_notify_success)
		if (reply != NULL)
			delete reply;  // ҪϢͷŵҪʱ棬ֱһɹsetȥReply
	return try_notify_success;
}

// Ϣ
bool UserTask::cmdMsgParse(const char *pstrMsg, const uint32_t nCmdLen)
{
	try
	{
		uint16_t type;
		::google::protobuf::Message *proto = (::google::protobuf::Message*) proto_decoder(pstrMsg, type);
		uint16_t* size = (uint16_t*)pstrMsg;
#ifdef Debug
		ztLoggerWrite(ZONE, e_Debug, "[%s]Receive: %s,\n size:%d, type:%d,\n To proto: %s", m_userId.c_str(), pstrMsg, *size, type, proto->DebugString().c_str());
#endif

		int ret;
		int tableID;
		m_activeTime = time(NULL);

		switch(type)
		{
		case MSG_LOGIN_REQ:
			{
				//FIXME temporarily disable login
				m_bAuthen = true;
				// TODO : check username & password here
				m_userId = TOQSTR(m_iTmpId);
				UserSessionManager::getInstance().AddUser(m_userId, this);
				delete proto;
				break;
			}
		//
		case MSG_CREATE_ROOM_REQ:
			{
				handleCreateRoom(GAME_TYPE_GRAIL, proto);
				delete proto;
				break;
			}
		//뷿
		case MSG_ENTER_ROOM_REQ:
			{
				handleEnterRoom(GAME_TYPE_GRAIL, proto);
				delete proto;    // ҪtryNotifytryNotifyreplyĻͷmessageһ൱Ҫ
				break;
			}
		case MSG_LEAVE_ROOM_REQ:
			{
				handleLeaveRoom(GAME_TYPE_GRAIL, proto);
				delete proto;
				break;
			}
		case MSG_ROOMLIST_REQ:
			{
				handleRoomList(GAME_TYPE_GRAIL, proto);
				delete proto;    // ҪtryNotifytryNotifyreplyĻͷmessageһ൱Ҫ
				break;
			}
		case MSG_JOIN_TEAM_REQ:
			{
				handleJoinTeam(GAME_TYPE_GRAIL, proto);
				delete proto;
				break;
			}
		case MSG_READY_GAME_REQ:
			{
				handleReadyGame(GAME_TYPE_GRAIL, proto);
				delete proto;    // ҪtryNotifytryNotifyreplyĻͷmessageһ൱Ҫ
				break;
			}
		case MSG_PICK_BAN:
			{
				PickBan* pick = (PickBan*)proto;
				GameGrail* game = getGame();
				if(!game){
					delete proto;
					break;
				}
				if(game->m_roleStrategy == ROLE_STRATEGY_31 && pick->is_pick()){
					tryNotify(m_playerId, STATE_ROLE_STRATEGY_31, 0, pick);
				}
				else if(game->m_roleStrategy == ROLE_STRATEGY_ANY && pick->is_pick()){
					tryNotify(m_playerId, STATE_ROLE_STRATEGY_ANY, 0, pick);
				}
				break;
			}
		case MSG_ACTION:
			{
				Action *action = (Action*)proto;
				// ж
				tryNotify(m_playerId, STATE_ACTION_PHASE, 0, action);
				break;
			}
		case MSG_RESPOND:
			{
				Respond* respond = (Respond*)proto;
				switch(respond->respond_id())
				{
				case RESPOND_REPLY_ATTACK:
					tryNotify(m_playerId, STATE_ATTACKED, 0, respond);
					break;
				case RESPOND_DISCARD:
					tryNotify(m_playerId, STATE_REQUEST_HAND, 0, respond);
					break;
				case RESPOND_DISCARD_COVER:
					tryNotify(m_playerId, STATE_REQUEST_COVER, 0, respond);
					break;
				case RESPOND_BULLET:
					tryNotify(m_playerId, STATE_MISSILED, 0, respond);
					break;
				case RESPOND_WEAKEN:
					tryNotify(m_playerId, STATE_WEAKEN, 0, respond);
					break;
				case RESPOND_ADDITIONAL_ACTION:
					tryNotify(m_playerId, STATE_ADDITIONAL_ACTION, 0, respond);
					break;
				case RESPOND_HEAL:
					tryNotify(m_playerId, STATE_ASK_FOR_CROSS, 0, respond);
					break;
				case WEI_LI_CI_FU:
					QiDao::WeiLiCiFuParse(this, m_playerId, proto);
					break;
				default:
					//ԴӽɫcmdMsgParseƥ
					GameGrail* game = getGame();
					if(!game || getGame()->getPlayerEntity(m_playerId)->cmdMsgParse(this, type, proto) == false){
						ztLoggerWrite(ZONE, e_Error, "[%s]Received undefine MSG_RESPOND: %s,\n size:%d, type:%d,\n To proto: %s", m_userId.c_str(), pstrMsg, *size, type, proto->DebugString().c_str());
						delete proto;
					}
				}
				break;
			}
		case MSG_TALK:
			{
				Talk* talk = (Talk*) proto;
				player_talk(getGame(), m_playerId, talk);
				delete proto;
				break;
			}
		default:
			ztLoggerWrite(ZONE, e_Error, "[%s]Received undefine MSG_TYPE: %s,\n size:%d, type:%d,\n To proto: %s", m_userId.c_str(), pstrMsg, *size, type, proto->DebugString().c_str());
			delete proto;
		}
		return true;
	}catch(GrailError e){
		ztLoggerWrite(ZONE, e_Error, "[%s]UserTask throws error: %d, Received Message: %s", m_userId.c_str(), e, pstrMsg);
		return false;
	}catch(std::exception const& e) {
		ztLoggerWrite(ZONE, e_Error, "[%s]UserTask throws error: %s, Received Message: %s",	m_userId.c_str(), e.what(), pstrMsg);
	}
}

void UserTask::handleCreateRoom(int game_type, void* req)
{
	CreateRoomRequest* create_room = (CreateRoomRequest*)req;
	GameConfig *config = new GameGrailConfig(create_room->max_player(), create_room->role_strategy());
	GameManager::getInstance().createGame(GAME_TYPE_GRAIL, config);
	EnterRoomRequest enter_room;
	enter_room.set_room_id(config->getTableId());
	handleEnterRoom(GAME_TYPE_GRAIL, &enter_room);
	delete config;
}

void UserTask::handleEnterRoom(int game_type, void* req)
{
	GameManager::getInstance().enterRoom(GAME_TYPE_GRAIL, m_userId, req);
}

void UserTask::handleLeaveRoom(int game_type, void* request)
{
	GameGrail* game = getGame();
	if(game){
		game->onUserLeave(m_userId);
	}
	else{
		ztLoggerWrite(ZONE, e_Warning, "UserTask::cmdMsgParse() userId [%s] cannot leave Table %d.",
			m_userId.c_str(), m_tableId);
	}
}

void UserTask::handleRoomList(int game_type, void* req)
{
	RoomListRequest* request = (RoomListRequest*)req;
	RoomListResponse response;
	int ret = GameManager::getInstance().getGameList(GAME_TYPE_GRAIL, req, &response);
	if (ret == GE_SUCCESS){
		sendProto(MSG_ROOMLIST_REP, response);
	}
	else{
		ztLoggerWrite(ZONE, e_Error, "UserTask::cmdMsgParse() userId [%s] cannot retrieve TableList. Ret: %d",
			m_userId.c_str(), ret);
	}
}

void UserTask::handleReadyGame(int game_type, void* req)
{
	ReadyForGameRequest* request = (ReadyForGameRequest*)req;
	switch(request->type())
	{
	case ReadyForGameRequest_Type_START_READY:
	case ReadyForGameRequest_Type_CANCEL_START_REDAY:
		{
			int ret = GameManager::getInstance().setPlayerReady(GAME_TYPE_GRAIL, m_tableId, m_playerId, req);
			if (ret != GE_SUCCESS){
				ztLoggerWrite(ZONE, e_Error, "UserTask::cmdMsgParse() userId [%s] cannot get ready. Table %d. Ret: %d",
					m_userId.c_str(), m_tableId, ret);
			}
		}
		break;
	case ReadyForGameRequest_Type_SEAT_READY:
		tryNotify(m_playerId, STATE_SEAT_ARRANGE);
		break;
	}
}

void UserTask::handleJoinTeam(int game_type, void* req)
{
	JoinTeamRequest* request = (JoinTeamRequest*)req;
	GameGrail* game = getGame();
	if(game){
		game->setTeam(m_playerId, request->team());
	}
	else
		ztLoggerWrite(ZONE, e_Warning, "UserTask::cmdMsgParse() userId [%s] cannot join team. Table %d.",
					m_userId.c_str(), m_tableId);
}

bool UserTask::msgParse(const void *pstrMsg, const uint32_t nCmdLen)
{
	return MessageQueue::msgParse((const char *)pstrMsg, nCmdLen);
}

void UserTask::sendProto(uint16_t proto_type, google::protobuf::Message& proto)
{
	string msg;
	proto_encoder(proto_type, proto, msg);
	SendCmd(msg.c_str(), msg.size());
}
<commit_msg>修正超时被踢的没有退出房间<commit_after>#include "stdafx.h"
#include "UserTask.h"
#include "UserSessionManager.h"
#include "GameManager.h"
#include "Communication.h"
#include "role\QiDao.h"
#include <boost/algorithm/string.hpp>

uint32_t UserTask::m_sIDSeq = 10000;
using namespace network;

void UserTask::Start()
{
	zTCPTask::Start();
	m_iTmpId = ++m_sIDSeq;

	UserSessionManager::getInstance().AddUserById(m_iTmpId, this);
	//FIXME temporarily disable login
	m_bAuthen = true;
	// TODO : check username & password here
	m_userId = TOQSTR(m_iTmpId);
	m_nickname = m_userId;
	UserSessionManager::getInstance().AddUser(m_userId, this);
}

void UserTask::OnQuit()
{
	zTCPTask::OnQuit();
	ztLoggerWrite(ZONE, e_Debug, "UserTask::OnQuit [%s] ",m_userId.c_str());
	GameGrail* game = getGame();
	if(game){
		game->onUserLeave(m_userId);
	}
	UserSessionManager::getInstance().RemoveUser(m_userId, m_iTmpId);
}

void UserTask::OnCheck()
{
	/*if (!m_bAuthen)
	{
		ztLoggerWrite(ZONE,e_Debug, "OnCheck[%s]: don't authen, kicked off ", m_userId.c_str());
		SetQuit();
		return;
	}*/

	time_t tmNow  = time(NULL);
	int temp = ServerConfig::getInstance().m_iCheckTime;
	if (tmNow - m_activeTime > ServerConfig::getInstance().m_iCheckTime)
	{
		ztLoggerWrite(ZONE,e_Debug, "OnCheck[%s]: heartbeat timeout,be kicked off ", m_userId.c_str());
		GameGrail* game = getGame();
		if(game){
			game->onUserLeave(m_userId);
		}
		UserSessionManager::getInstance().RemoveUser(m_userId, m_iTmpId);
		SetQuit();
		return;
	}
}

GameGrail* UserTask::getGame()
{
	Game *game;
	if(m_tableId < 0){
		return NULL;
	}
	if(0 != GameManager::getInstance().getGame(GAME_TYPE_GRAIL, m_tableId, &game)){
		ztLoggerWrite(ZONE,e_Warning, "UserTask::getGame() failed. TableId: %d", m_tableId);
		return NULL;
	}
	return (GameGrail*)game;
}

bool UserTask::tryNotify(int id, int state, int step, void* reply)
{
	GameGrail*game = getGame();
	if(!game){
		if (reply != NULL)
			delete reply;  // ҪϢͷŵҪʱ棬ֱһɹsetȥReply
		return false;
	}
	bool try_notify_success = game->tryNotify(id, state, step, reply);
	if (!try_notify_success)
		if (reply != NULL)
			delete reply;  // ҪϢͷŵҪʱ棬ֱһɹsetȥReply
	return try_notify_success;
}

// Ϣ
bool UserTask::cmdMsgParse(const char *pstrMsg, const uint32_t nCmdLen)
{
	try
	{
		uint16_t type;
		::google::protobuf::Message *proto = (::google::protobuf::Message*) proto_decoder(pstrMsg, type);
		uint16_t* size = (uint16_t*)pstrMsg;
#ifdef Debug
		ztLoggerWrite(ZONE, e_Debug, "[%s]Receive: %s,\n size:%d, type:%d,\n To proto: %s", m_userId.c_str(), pstrMsg, *size, type, proto->DebugString().c_str());
#endif

		int ret;
		int tableID;
		m_activeTime = time(NULL);

		switch(type)
		{
		case MSG_LOGIN_REQ:
			{
				//FIXME temporarily disable login
				m_bAuthen = true;
				// TODO : check username & password here
				m_userId = TOQSTR(m_iTmpId);
				UserSessionManager::getInstance().AddUser(m_userId, this);
				delete proto;
				break;
			}
		//
		case MSG_CREATE_ROOM_REQ:
			{
				handleCreateRoom(GAME_TYPE_GRAIL, proto);
				delete proto;
				break;
			}
		//뷿
		case MSG_ENTER_ROOM_REQ:
			{
				handleEnterRoom(GAME_TYPE_GRAIL, proto);
				delete proto;    // ҪtryNotifytryNotifyreplyĻͷmessageһ൱Ҫ
				break;
			}
		case MSG_LEAVE_ROOM_REQ:
			{
				handleLeaveRoom(GAME_TYPE_GRAIL, proto);
				delete proto;
				break;
			}
		case MSG_ROOMLIST_REQ:
			{
				handleRoomList(GAME_TYPE_GRAIL, proto);
				delete proto;    // ҪtryNotifytryNotifyreplyĻͷmessageһ൱Ҫ
				break;
			}
		case MSG_JOIN_TEAM_REQ:
			{
				handleJoinTeam(GAME_TYPE_GRAIL, proto);
				delete proto;
				break;
			}
		case MSG_READY_GAME_REQ:
			{
				handleReadyGame(GAME_TYPE_GRAIL, proto);
				delete proto;    // ҪtryNotifytryNotifyreplyĻͷmessageһ൱Ҫ
				break;
			}
		case MSG_PICK_BAN:
			{
				PickBan* pick = (PickBan*)proto;
				GameGrail* game = getGame();
				if(!game){
					delete proto;
					break;
				}
				if(game->m_roleStrategy == ROLE_STRATEGY_31 && pick->is_pick()){
					tryNotify(m_playerId, STATE_ROLE_STRATEGY_31, 0, pick);
				}
				else if(game->m_roleStrategy == ROLE_STRATEGY_ANY && pick->is_pick()){
					tryNotify(m_playerId, STATE_ROLE_STRATEGY_ANY, 0, pick);
				}
				break;
			}
		case MSG_ACTION:
			{
				Action *action = (Action*)proto;
				// ж
				tryNotify(m_playerId, STATE_ACTION_PHASE, 0, action);
				break;
			}
		case MSG_RESPOND:
			{
				Respond* respond = (Respond*)proto;
				switch(respond->respond_id())
				{
				case RESPOND_REPLY_ATTACK:
					tryNotify(m_playerId, STATE_ATTACKED, 0, respond);
					break;
				case RESPOND_DISCARD:
					tryNotify(m_playerId, STATE_REQUEST_HAND, 0, respond);
					break;
				case RESPOND_DISCARD_COVER:
					tryNotify(m_playerId, STATE_REQUEST_COVER, 0, respond);
					break;
				case RESPOND_BULLET:
					tryNotify(m_playerId, STATE_MISSILED, 0, respond);
					break;
				case RESPOND_WEAKEN:
					tryNotify(m_playerId, STATE_WEAKEN, 0, respond);
					break;
				case RESPOND_ADDITIONAL_ACTION:
					tryNotify(m_playerId, STATE_ADDITIONAL_ACTION, 0, respond);
					break;
				case RESPOND_HEAL:
					tryNotify(m_playerId, STATE_ASK_FOR_CROSS, 0, respond);
					break;
				case WEI_LI_CI_FU:
					QiDao::WeiLiCiFuParse(this, m_playerId, proto);
					break;
				default:
					//ԴӽɫcmdMsgParseƥ
					GameGrail* game = getGame();
					if(!game || getGame()->getPlayerEntity(m_playerId)->cmdMsgParse(this, type, proto) == false){
						ztLoggerWrite(ZONE, e_Error, "[%s]Received undefine MSG_RESPOND: %s,\n size:%d, type:%d,\n To proto: %s", m_userId.c_str(), pstrMsg, *size, type, proto->DebugString().c_str());
						delete proto;
					}
				}
				break;
			}
		case MSG_TALK:
			{
				Talk* talk = (Talk*) proto;
				player_talk(getGame(), m_playerId, talk);
				delete proto;
				break;
			}
		default:
			ztLoggerWrite(ZONE, e_Error, "[%s]Received undefine MSG_TYPE: %s,\n size:%d, type:%d,\n To proto: %s", m_userId.c_str(), pstrMsg, *size, type, proto->DebugString().c_str());
			delete proto;
		}
		return true;
	}catch(GrailError e){
		ztLoggerWrite(ZONE, e_Error, "[%s]UserTask throws error: %d, Received Message: %s", m_userId.c_str(), e, pstrMsg);
		return false;
	}catch(std::exception const& e) {
		ztLoggerWrite(ZONE, e_Error, "[%s]UserTask throws error: %s, Received Message: %s",	m_userId.c_str(), e.what(), pstrMsg);
	}
}

void UserTask::handleCreateRoom(int game_type, void* req)
{
	CreateRoomRequest* create_room = (CreateRoomRequest*)req;
	GameConfig *config = new GameGrailConfig(create_room->max_player(), create_room->role_strategy());
	GameManager::getInstance().createGame(GAME_TYPE_GRAIL, config);
	EnterRoomRequest enter_room;
	enter_room.set_room_id(config->getTableId());
	handleEnterRoom(GAME_TYPE_GRAIL, &enter_room);
	delete config;
}

void UserTask::handleEnterRoom(int game_type, void* req)
{
	GameManager::getInstance().enterRoom(GAME_TYPE_GRAIL, m_userId, req);
}

void UserTask::handleLeaveRoom(int game_type, void* request)
{
	GameGrail* game = getGame();
	if(game){
		game->onUserLeave(m_userId);
	}
	else{
		ztLoggerWrite(ZONE, e_Warning, "UserTask::cmdMsgParse() userId [%s] cannot leave Table %d.",
			m_userId.c_str(), m_tableId);
	}
}

void UserTask::handleRoomList(int game_type, void* req)
{
	RoomListRequest* request = (RoomListRequest*)req;
	RoomListResponse response;
	int ret = GameManager::getInstance().getGameList(GAME_TYPE_GRAIL, req, &response);
	if (ret == GE_SUCCESS){
		sendProto(MSG_ROOMLIST_REP, response);
	}
	else{
		ztLoggerWrite(ZONE, e_Error, "UserTask::cmdMsgParse() userId [%s] cannot retrieve TableList. Ret: %d",
			m_userId.c_str(), ret);
	}
}

void UserTask::handleReadyGame(int game_type, void* req)
{
	ReadyForGameRequest* request = (ReadyForGameRequest*)req;
	switch(request->type())
	{
	case ReadyForGameRequest_Type_START_READY:
	case ReadyForGameRequest_Type_CANCEL_START_REDAY:
		{
			int ret = GameManager::getInstance().setPlayerReady(GAME_TYPE_GRAIL, m_tableId, m_playerId, req);
			if (ret != GE_SUCCESS){
				ztLoggerWrite(ZONE, e_Error, "UserTask::cmdMsgParse() userId [%s] cannot get ready. Table %d. Ret: %d",
					m_userId.c_str(), m_tableId, ret);
			}
		}
		break;
	case ReadyForGameRequest_Type_SEAT_READY:
		tryNotify(m_playerId, STATE_SEAT_ARRANGE);
		break;
	}
}

void UserTask::handleJoinTeam(int game_type, void* req)
{
	JoinTeamRequest* request = (JoinTeamRequest*)req;
	GameGrail* game = getGame();
	if(game){
		game->setTeam(m_playerId, request->team());
	}
	else
		ztLoggerWrite(ZONE, e_Warning, "UserTask::cmdMsgParse() userId [%s] cannot join team. Table %d.",
					m_userId.c_str(), m_tableId);
}

bool UserTask::msgParse(const void *pstrMsg, const uint32_t nCmdLen)
{
	return MessageQueue::msgParse((const char *)pstrMsg, nCmdLen);
}

void UserTask::sendProto(uint16_t proto_type, google::protobuf::Message& proto)
{
	string msg;
	proto_encoder(proto_type, proto, msg);
	SendCmd(msg.c_str(), msg.size());
}
<|endoftext|>


<commit_before>#include "Resources.h"
#include "ModelResource.h"
#include "TextureResource.h"
#include "SceneResource.h"
#include "util.h"

Resources::Resources() {
	models = new std::map<std::string, ModelResource*>();
	textures = new std::map<std::string, TextureResource*>();
	scenes = new std::map<std::string, SceneResource*>();
}

Resources::~Resources() {
	for (auto model : *models) {
		delete model.second;
	}
	delete models;

	for (auto texture : *textures) {
		delete texture.second;
	}
	delete textures;

	for (auto scene : *scenes) {
		delete scene.second;
	}
	delete scenes;
}

void Resources::save(std::ofstream &file, std::string directory) {
	// Textures
	util::createDirectory((directory + "/Textures").c_str());

	std::map<std::string, TextureResource*>::size_type texturesSize = textures->size();
	file.write(reinterpret_cast<const char*>(&texturesSize), sizeof(texturesSize));

	for (auto texture : *textures) {
		texture.second->save(file);
	}

	// Models
	util::createDirectory((directory + "/Models").c_str());

	std::map<std::string, ModelResource*>::size_type modelsSize = models->size();
	file.write(reinterpret_cast<const char*>(&modelsSize), sizeof(modelsSize));

	for (auto model : *models) {
		model.second->save(file, directory + "/Models");
	}

	// Scenes
	util::createDirectory((directory + "/Scenes").c_str());

	std::map<std::string, SceneResource*>::size_type scenesSize = scenes->size();
	file.write(reinterpret_cast<const char*>(&scenesSize), sizeof(scenesSize));

	for (auto scene : *scenes) {
		scene.second->save(file, directory + "/Scenes");
	}
}

void Resources::load(std::ifstream &file, std::string directory) {
	// Textures
	std::map<std::string, TextureResource*>::size_type texturesSize;
	file.read(reinterpret_cast<char*>(&texturesSize), sizeof(texturesSize));

	for (auto i = 0; i < texturesSize; i++) {
		TextureResource* texture = new TextureResource(file, directory + "/Textures");
		(*textures)[texture->name] = texture;
	}

	// Models
	std::map<std::string, ModelResource*>::size_type modelsSize;
	file.read(reinterpret_cast<char*>(&modelsSize), sizeof(modelsSize));

	for (auto i = 0; i < modelsSize; i++) {
		ModelResource* model = new ModelResource(file, directory + "/Models");
		(*models)[model->name] = model;
	}

	// Scenes
	std::map<std::string, SceneResource*>::size_type scenesSize;
	file.read(reinterpret_cast<char*>(&scenesSize), sizeof(scenesSize));

	for (auto i = 0; i < scenesSize; i++) {
		SceneResource* scene = new SceneResource(file, directory + "/Scenes");
		(*scenes)[scene->name] = scene;
	}
}

std::map<std::string, ModelResource*>* Resources::modelResources() const {
	return models;
}

std::map<std::string, TextureResource*>* Resources::textureResources() const {
	return textures;
}

std::map<std::string, SceneResource*>* Resources::sceneResources() const {
	return scenes;
}<commit_msg>Fix signed/unsigned mismatch.<commit_after>#include "Resources.h"
#include "ModelResource.h"
#include "TextureResource.h"
#include "SceneResource.h"
#include "util.h"

Resources::Resources() {
	models = new std::map<std::string, ModelResource*>();
	textures = new std::map<std::string, TextureResource*>();
	scenes = new std::map<std::string, SceneResource*>();
}

Resources::~Resources() {
	for (auto model : *models) {
		delete model.second;
	}
	delete models;

	for (auto texture : *textures) {
		delete texture.second;
	}
	delete textures;

	for (auto scene : *scenes) {
		delete scene.second;
	}
	delete scenes;
}

void Resources::save(std::ofstream &file, std::string directory) {
	// Textures
	util::createDirectory((directory + "/Textures").c_str());

	std::map<std::string, TextureResource*>::size_type texturesSize = textures->size();
	file.write(reinterpret_cast<const char*>(&texturesSize), sizeof(texturesSize));

	for (auto texture : *textures) {
		texture.second->save(file);
	}

	// Models
	util::createDirectory((directory + "/Models").c_str());

	std::map<std::string, ModelResource*>::size_type modelsSize = models->size();
	file.write(reinterpret_cast<const char*>(&modelsSize), sizeof(modelsSize));

	for (auto model : *models) {
		model.second->save(file, directory + "/Models");
	}

	// Scenes
	util::createDirectory((directory + "/Scenes").c_str());

	std::map<std::string, SceneResource*>::size_type scenesSize = scenes->size();
	file.write(reinterpret_cast<const char*>(&scenesSize), sizeof(scenesSize));

	for (auto scene : *scenes) {
		scene.second->save(file, directory + "/Scenes");
	}
}

void Resources::load(std::ifstream &file, std::string directory) {
	// Textures
	std::map<std::string, TextureResource*>::size_type texturesSize;
	file.read(reinterpret_cast<char*>(&texturesSize), sizeof(texturesSize));

	for (std::map<std::string, TextureResource*>::size_type i = 0; i < texturesSize; i++) {
		TextureResource* texture = new TextureResource(file, directory + "/Textures");
		(*textures)[texture->name] = texture;
	}

	// Models
	std::map<std::string, ModelResource*>::size_type modelsSize;
	file.read(reinterpret_cast<char*>(&modelsSize), sizeof(modelsSize));

	for (std::map<std::string, ModelResource*>::size_type i = 0; i < modelsSize; i++) {
		ModelResource* model = new ModelResource(file, directory + "/Models");
		(*models)[model->name] = model;
	}

	// Scenes
	std::map<std::string, SceneResource*>::size_type scenesSize;
	file.read(reinterpret_cast<char*>(&scenesSize), sizeof(scenesSize));

	for (std::map<std::string, SceneResource*>::size_type i = 0; i < scenesSize; i++) {
		SceneResource* scene = new SceneResource(file, directory + "/Scenes");
		(*scenes)[scene->name] = scene;
	}
}

std::map<std::string, ModelResource*>* Resources::modelResources() const {
	return models;
}

std::map<std::string, TextureResource*>* Resources::textureResources() const {
	return textures;
}

std::map<std::string, SceneResource*>* Resources::sceneResources() const {
	return scenes;
}<|endoftext|>


<commit_before>#include "CPU.h"

short CPU::opcode0x07() {
	byte significantBit = AF.hi & 0x80;
	AF.hi <<= 1;

	if (checkFlag(Flag::CARRY_FLAG)) {
		setBit(&AF.hi, 0);
	}
	else {
		clearBit(&AF.hi, 0);
	}

	clearFlags();
	if (significantBit != 0) {
		raiseFlag(Flag::CARRY_FLAG);
	}

    return 4;
}

short CPU::opcode0x0F() {
	byte bitZero = AF.hi & 0x01;
	AF.hi >>= 1;

	clearFlags();
	if (bitZero == 0x01) {
		raiseFlag(Flag::CARRY_FLAG);
	}
	if (AF.hi == 0x00) {
		raiseFlag(Flag::ZERO_FLAG);
	}

    return 4;
}

short CPU::opcode0x17() {
	byte lastBit = AF.hi & 0x80;
	AF.hi <<= 1;

	if (checkFlag(Flag::CARRY_FLAG)) {
		setBit(&AF.hi, 0);
	} else {
		clearBit(&AF.hi, 0);
	}

	clearFlags();
	if (lastBit == 0x01) {
		raiseFlag(Flag::CARRY_FLAG);
	}
	if (AF.hi == 0) {
		raiseFlag(ZERO_FLAG);
	}
    return 4;
}// RLA

short CPU::opcode0x1F() {
	byte firstBit = AF.hi & 0x01;
	AF.hi >>= 1;

	if (checkFlag(Flag::CARRY_FLAG)) {
		setBit(&AF.hi, 7);
	} else {
		clearBit(&AF.hi, 7);
	}

	clearFlags();
	if (firstBit == 0x01) {
		raiseFlag(Flag::CARRY_FLAG);
	}
	return 4;
}// RR A

void CPU::rlc8bitRegister(byte * reg) {
	byte bit= *reg & 0x80;
	*reg <<= 1;

	clearFlags();
	if (bit == 0x01) {
		raiseFlag(Flag::CARRY_FLAG);
	}
	if (*reg == 0x00) {
		raiseFlag(ZERO_FLAG);
	}
}

short CPU::extendedOpcode0x00() {
    rlc8bitRegister(&BC.hi);
    return 8;
}// RLC B

short CPU::extendedOpcode0x01() {
    rlc8bitRegister(&BC.low);
    return 8;
}// RLC C

short CPU::extendedOpcode0x02() {
    rlc8bitRegister(&DE.hi);
    return 8;
}// RLC D

short CPU::extendedOpcode0x03() {
    rlc8bitRegister(&DE.low);
    return 8;
}// RLC E

short CPU::extendedOpcode0x04() {
    rlc8bitRegister(&HL.hi);
    return 8;
}// RLC H

short CPU::extendedOpcode0x05() {
    rlc8bitRegister(&HL.low);
    return 8;
}// RLC L

short CPU::extendedOpcode0x06() {
	byte reg = memory->read(HL.value) ;
	rlc8bitRegister(&reg);
	memory->write(HL.value, reg);

	return 16;
}// RLC (HL)

short CPU::extendedOpcode0x07() {
	byte significantBit = AF.hi & 0x80;
	AF.hi <<= 1;

	if (checkFlag(Flag::CARRY_FLAG)) {
		setBit(&AF.hi, 0);
	} else {
		clearBit(&AF.hi, 0);
	}

	clearFlags();
	if (significantBit != 0) {
		raiseFlag(Flag::CARRY_FLAG);
	}

	if (AF.hi == 0x00) {
		raiseFlag(Flag::ZERO_FLAG);
	}

    return 8;
}// RLC A

void CPU::rrc8bitRegister(byte *reg) {
	byte zeroBit = *reg & 0x01;
	*reg = *reg >> 1;

	clearFlags();
	if (zeroBit == 0x01) {
		raiseFlag(CARRY_FLAG);
	}
	if (*reg == 0) {
		raiseFlag(ZERO_FLAG);
    }
}

short CPU::extendedOpcode0x08() {
    rrc8bitRegister(&BC.hi);
    return 8;
}// RRC B

short CPU::extendedOpcode0x09() {
    rrc8bitRegister(&BC.low);
    return 8;
}// RRC C

short CPU::extendedOpcode0x0A() {
    rrc8bitRegister(&DE.hi);
    return 8;
}// RRC D

short CPU::extendedOpcode0x0B() {
    rrc8bitRegister(&DE.low);
    return 8;
}// RRC E

short CPU::extendedOpcode0x0C() {
    rrc8bitRegister(&HL.hi);
    return 8;
}// RRC H

short CPU::extendedOpcode0x0D() {
    rrc8bitRegister(&HL.low);
    return 8;
}// RRC L

short CPU::extendedOpcode0x0E() {
	byte reg = memory->read(HL.value) ;
	rrc8bitRegister(&reg);
	memory->write(HL.value, reg);
    return 16;
}// RRC (HL)

short CPU::extendedOpcode0x0F() {
	byte bit = AF.hi & 0x01;
	AF.hi >>= 1;

	clearFlags();
	if (bit == 0x01) {
		raiseFlag(Flag::CARRY_FLAG);
	}

	if (AF.hi == 0x00) {
		raiseFlag(Flag::ZERO_FLAG);
	}

    return 8;
}// RRC A

void CPU::rl8bitRegister(byte *reg) {
	byte significantBit = *reg & 0x80;
	*reg = *reg << 1;

	if (checkFlag(Flag::CARRY_FLAG)) {
		setBit(reg, 0);
	}
	else {
		clearBit(reg, 0);
	}

	clearFlags();
	if (significantBit != 0x00) {
		raiseFlag(Flag::CARRY_FLAG);
	}
	if (*reg == 0x00) {
		raiseFlag(Flag::ZERO_FLAG);
	}
}

short CPU::extendedOpcode0x10() {
    rl8bitRegister(&BC.hi);
    return 8;
}// rl B

short CPU::extendedOpcode0x11() {
    rl8bitRegister(&BC.low);
    return 8;
}// rl C

short CPU::extendedOpcode0x12() {
    rl8bitRegister(&DE.hi);
    return 8;
}// rl D

short CPU::extendedOpcode0x13() {
    rl8bitRegister(&DE.low);
    return 8;
}// rl E

short CPU::extendedOpcode0x14() {
    rl8bitRegister(&HL.hi);
    return 8;
}// rl H

short CPU::extendedOpcode0x15() {
    rl8bitRegister(&HL.low);
    return 8;
}// rl L

short CPU::extendedOpcode0x16() {
	byte reg = memory->read(HL.value);
	rl8bitRegister(&reg);
	memory->write(HL.value, reg);
    return 16;
}// rl (HL)

short CPU::extendedOpcode0x17() {
	rl8bitRegister(&AF.hi);
	return 8;
}

void CPU::rr8bitRegister(byte *reg) {
	byte zeroBit = *reg & 0x01;
	*reg = *reg >> 1;

	if (checkFlag(Flag::CARRY_FLAG)) {
		setBit(reg, 7);
	} else {
		clearBit(reg, 7);
	}

	clearFlags();
	if (zeroBit == 0x01) {
		raiseFlag(Flag::CARRY_FLAG);
	}
	if (*reg == 0x00) {
		raiseFlag(Flag::ZERO_FLAG);
	}
}

short CPU::extendedOpcode0x18() {
    rr8bitRegister(&BC.hi);
    return 8;
}// rr B

short CPU::extendedOpcode0x19() {
    rr8bitRegister(&BC.low);
    return 8;
}// rr C

short CPU::extendedOpcode0x1A() {
    rr8bitRegister(&DE.hi);
    return 8;
}// rr D

short CPU::extendedOpcode0x1B() {
    rr8bitRegister(&DE.low);
    return 8;
}// rr E

short CPU::extendedOpcode0x1C() {
    rr8bitRegister(&HL.hi);
    return 8;
}// rr H

short CPU::extendedOpcode0x1D() {
    rr8bitRegister(&HL.low);
    return 8;
}// rr L

short CPU::extendedOpcode0x1E() {
	byte reg = memory->read(HL.value);
	rr8bitRegister(&reg);
    memory->write(HL.value, reg);
    return 16;
}// rr (HL)

short CPU::extendedOpcode0x1F() {
    rr8bitRegister(&AF.hi);
    return 8;
}// rr A

void CPU::sla8bitRegister(byte *reg) {
	byte lastBit = *reg & 0x80;
	*reg <<= 1;

	clearFlags();
	if (lastBit != 0x00) {
		raiseFlag(Flag::CARRY_FLAG);
	}
    if ( *reg == 0 ) {
        raiseFlag(ZERO_FLAG);
    }
}

short CPU::extendedOpcode0x20() {
    sla8bitRegister(&BC.hi);
    return 8;
}// sla B

short CPU::extendedOpcode0x21() {
    sla8bitRegister(&BC.low);
    return 8;
}// sla C

short CPU::extendedOpcode0x22() {
    sla8bitRegister(&DE.hi);
    return 8;
}// sla D

short CPU::extendedOpcode0x23() {
    sla8bitRegister(&DE.low);
    return 8;
}// sla E

short CPU::extendedOpcode0x24() {
    sla8bitRegister(&HL.hi);
    return 8;
}// sla H

short CPU::extendedOpcode0x25() {
    sla8bitRegister(&HL.low);
    return 8;
}// sla L

short CPU::extendedOpcode0x26() {
    byte reg = memory->read(HL.value);
	sla8bitRegister(&reg);
    memory->write(HL.value, reg);
    return 16;
}// sla (HL)

short CPU::extendedOpcode0x27() {
    sla8bitRegister(&AF.hi);
    return 8;
}// sla A

void CPU::sra8bitRegister(byte * reg) {
	byte firstBit = *reg & 0x01;
	byte lastBit = *reg & 0x80;

	*reg >>= 1;

	if (lastBit != 0x00) {
		setBit(reg, 7);
	} else {
		clearBit(reg, 7);
	}

	clearFlags();
	if (firstBit == 0x01) {
		raiseFlag(Flag::CARRY_FLAG);
	}
	if (*reg == 0x00) {
		raiseFlag(Flag::ZERO_FLAG);
	}
}

short CPU::extendedOpcode0x28() {
    sra8bitRegister(&BC.hi);
    return 8;
}// sra B

short CPU::extendedOpcode0x29() {
    sra8bitRegister(&BC.low);
    return 8;
}// sra C

short CPU::extendedOpcode0x2A() {
    sra8bitRegister(&DE.hi);
    return 8;
}// sra D

short CPU::extendedOpcode0x2B() {
    sra8bitRegister(&DE.low);
    return 8;
}// sra E

short CPU::extendedOpcode0x2C() {
    sra8bitRegister(&HL.hi);
    return 8;
}// sra H

short CPU::extendedOpcode0x2D(){
    sra8bitRegister(&HL.low);
    return 8;
}// sra L

short CPU::extendedOpcode0x2E() {
    byte data = memory->read(HL.value);
	sra8bitRegister(&data);
	memory->write(HL.value, data);
    return 16;
}// sra (HL)

short CPU::extendedOpcode0x2F() {
    sra8bitRegister(&AF.hi);
    return 8;
}// sra A

void CPU::swap8bitRegister(byte * reg) {
	clearFlags();

	*reg = (((*reg & 0xF0) >> 4) | ((*reg & 0x0F) << 4));

	if ( *reg == 0 ) {
        raiseFlag(ZERO_FLAG);
    }
}

short CPU::extendedOpcode0x30() {
    swap8bitRegister(&BC.hi);
    return 8;
}// swap B

short CPU::extendedOpcode0x31() {
    swap8bitRegister(&BC.low);
    return 8;
}// swap C

short CPU::extendedOpcode0x32() {
    swap8bitRegister(&DE.hi);
    return 8;
}// swap D

short CPU::extendedOpcode0x33() {
    swap8bitRegister(&DE.low);
    return 8;
}// swap E

short CPU::extendedOpcode0x34() {
    swap8bitRegister(&HL.hi);
    return 8;
}// swap H

short CPU::extendedOpcode0x35() {
    swap8bitRegister(&HL.low);
    return 8;
}// swap L

short CPU::extendedOpcode0x36() {
	clearFlags();
    byte data = memory->read(HL.value);
	data = (((data & 0xF0) >> 4) | ((data & 0x0F) << 4));

	if ( data == 0 ) {
        raiseFlag(ZERO_FLAG);
    }

    memory->write(HL.value, data);
    return 16;
}// swap (HL)

short CPU::extendedOpcode0x37() {
    swap8bitRegister(&AF.hi);
    return 8;
}// swap A

void CPU::srl8bitRegister(byte *reg) {
	byte firstBit = *reg & 0x01;
	*reg >>= 1;

	clearBit(reg, 7);

	clearFlags();
	if (firstBit == 0x01) {
        raiseFlag(CARRY_FLAG);
    }
	if (*reg == 0) {
        raiseFlag(ZERO_FLAG);
    }
}

short CPU::extendedOpcode0x38() {
    srl8bitRegister(&BC.hi);
    return 8;
}// SRL B

short CPU::extendedOpcode0x39() {
    srl8bitRegister(&BC.low);
    return 8;
}// SRL C

short CPU::extendedOpcode0x3A() {
    srl8bitRegister(&DE.hi);
    return 8;
}// SRL D

short CPU::extendedOpcode0x3B() {
    srl8bitRegister(&DE.low);
    return 8;
}// SRL E

short CPU::extendedOpcode0x3C() {
    srl8bitRegister(&HL.hi);
    return 8;
}// SRL H

short CPU::extendedOpcode0x3D() {
    srl8bitRegister(&HL.low);
    return 8;
}// SRL L

short CPU::extendedOpcode0x3E() {
    byte data = memory->read(HL.value);
	srl8bitRegister(&data);
	memory->write(HL.value, data);
    return 16;
}// SRL (HL)

short CPU::extendedOpcode0x3F() {
    srl8bitRegister(&AF.hi);
    return 8;
}// SRL A
<commit_msg>Fix RLC A, RRC A, RLA, RLC n, RRC n<commit_after>#include "CPU.h"

short CPU::opcode0x07() {
	byte bit = AF.hi & 0x80;
	AF.hi <<= 1;

	clearFlags();
	if (bit != 0x00) {
		raiseFlag(Flag::CARRY_FLAG);
		setBit(&AF.hi, 0);
	}
	else {
		clearBit(&AF.hi, 0);
	}

    return 4;
}

short CPU::opcode0x0F() {
	byte zeroBit = AF.hi & 0x01;
	AF.hi = AF.hi >> 1;

	clearFlags();
	if (zeroBit != 0x00) {
		raiseFlag(CARRY_FLAG);
		setBit(&AF.hi, 7);
	} else {
		clearBit(&AF.hi, 7);
	}

    return 4;
} // RRC A

short CPU::opcode0x17() {
	byte significantBit = AF.hi & 0x80;
	AF.hi = AF.hi << 1;

	if (checkFlag(Flag::CARRY_FLAG)) {
		setBit(&AF.hi, 0);
	} else {
		clearBit(&AF.hi, 0);
	}

	clearFlags();
	if (significantBit != 0x00) {
		raiseFlag(Flag::CARRY_FLAG);
	}

    return 4;
}// RLA

short CPU::opcode0x1F() {
	byte firstBit = AF.hi & 0x01;
	AF.hi >>= 1;

	if (checkFlag(Flag::CARRY_FLAG)) {
		setBit(&AF.hi, 7);
	} else {
		clearBit(&AF.hi, 7);
	}

	clearFlags();
	if (firstBit == 0x01) {
		raiseFlag(Flag::CARRY_FLAG);
	}
	return 4;
}// RR A

void CPU::rlc8bitRegister(byte * reg) {
	byte bit= *reg & 0x80;
	*reg <<= 1;

	clearFlags();
	if (bit != 0x00) {
		raiseFlag(Flag::CARRY_FLAG);
		setBit(reg, 0);
	} else {
		clearBit(reg, 0);
	}

	if (*reg == 0x00) {
		raiseFlag(ZERO_FLAG);
	}
}

short CPU::extendedOpcode0x00() {
    rlc8bitRegister(&BC.hi);
    return 8;
}// RLC B

short CPU::extendedOpcode0x01() {
    rlc8bitRegister(&BC.low);
    return 8;
}// RLC C

short CPU::extendedOpcode0x02() {
    rlc8bitRegister(&DE.hi);
    return 8;
}// RLC D

short CPU::extendedOpcode0x03() {
    rlc8bitRegister(&DE.low);
    return 8;
}// RLC E

short CPU::extendedOpcode0x04() {
    rlc8bitRegister(&HL.hi);
    return 8;
}// RLC H

short CPU::extendedOpcode0x05() {
    rlc8bitRegister(&HL.low);
    return 8;
}// RLC L

short CPU::extendedOpcode0x06() {
	byte reg = memory->read(HL.value) ;
	rlc8bitRegister(&reg);
	memory->write(HL.value, reg);

	return 16;
}// RLC (HL)

short CPU::extendedOpcode0x07() {
	rlc8bitRegister(&AF.hi);
    return 8;
}// RLC A

void CPU::rrc8bitRegister(byte *reg) {
	byte zeroBit = *reg & 0x01;
	*reg = *reg >> 1;

	clearFlags();
	if (zeroBit != 0x00) {
		raiseFlag(CARRY_FLAG);
		setBit(reg, 7);
	} else {
		clearBit(reg, 7);
	}

	if (*reg == 0) {
		raiseFlag(ZERO_FLAG);
    }
}

short CPU::extendedOpcode0x08() {
    rrc8bitRegister(&BC.hi);
    return 8;
}// RRC B

short CPU::extendedOpcode0x09() {
    rrc8bitRegister(&BC.low);
    return 8;
}// RRC C

short CPU::extendedOpcode0x0A() {
    rrc8bitRegister(&DE.hi);
    return 8;
}// RRC D

short CPU::extendedOpcode0x0B() {
    rrc8bitRegister(&DE.low);
    return 8;
}// RRC E

short CPU::extendedOpcode0x0C() {
    rrc8bitRegister(&HL.hi);
    return 8;
}// RRC H

short CPU::extendedOpcode0x0D() {
    rrc8bitRegister(&HL.low);
    return 8;
}// RRC L

short CPU::extendedOpcode0x0E() {
	byte reg = memory->read(HL.value) ;
	rrc8bitRegister(&reg);
	memory->write(HL.value, reg);
    return 16;
}// RRC (HL)

short CPU::extendedOpcode0x0F() {
	rrc8bitRegister(&AF.hi);
    return 8;
}// RRC A

void CPU::rl8bitRegister(byte *reg) {
	byte significantBit = *reg & 0x80;
	*reg = *reg << 1;

	if (checkFlag(Flag::CARRY_FLAG)) {
		setBit(reg, 0);
	}
	else {
		clearBit(reg, 0);
	}

	clearFlags();
	if (significantBit != 0x00) {
		raiseFlag(Flag::CARRY_FLAG);
	}
	if (*reg == 0x00) {
		raiseFlag(Flag::ZERO_FLAG);
	}
}

short CPU::extendedOpcode0x10() {
    rl8bitRegister(&BC.hi);
    return 8;
}// rl B

short CPU::extendedOpcode0x11() {
    rl8bitRegister(&BC.low);
    return 8;
}// rl C

short CPU::extendedOpcode0x12() {
    rl8bitRegister(&DE.hi);
    return 8;
}// rl D

short CPU::extendedOpcode0x13() {
    rl8bitRegister(&DE.low);
    return 8;
}// rl E

short CPU::extendedOpcode0x14() {
    rl8bitRegister(&HL.hi);
    return 8;
}// rl H

short CPU::extendedOpcode0x15() {
    rl8bitRegister(&HL.low);
    return 8;
}// rl L

short CPU::extendedOpcode0x16() {
	byte reg = memory->read(HL.value);
	rl8bitRegister(&reg);
	memory->write(HL.value, reg);
    return 16;
}// rl (HL)

short CPU::extendedOpcode0x17() {
	rl8bitRegister(&AF.hi);
	return 8;
}

void CPU::rr8bitRegister(byte *reg) {
	byte zeroBit = *reg & 0x01;
	*reg = *reg >> 1;

	if (checkFlag(Flag::CARRY_FLAG)) {
		setBit(reg, 7);
	} else {
		clearBit(reg, 7);
	}

	clearFlags();
	if (zeroBit == 0x01) {
		raiseFlag(Flag::CARRY_FLAG);
	}
	if (*reg == 0x00) {
		raiseFlag(Flag::ZERO_FLAG);
	}
}

short CPU::extendedOpcode0x18() {
    rr8bitRegister(&BC.hi);
    return 8;
}// rr B

short CPU::extendedOpcode0x19() {
    rr8bitRegister(&BC.low);
    return 8;
}// rr C

short CPU::extendedOpcode0x1A() {
    rr8bitRegister(&DE.hi);
    return 8;
}// rr D

short CPU::extendedOpcode0x1B() {
    rr8bitRegister(&DE.low);
    return 8;
}// rr E

short CPU::extendedOpcode0x1C() {
    rr8bitRegister(&HL.hi);
    return 8;
}// rr H

short CPU::extendedOpcode0x1D() {
    rr8bitRegister(&HL.low);
    return 8;
}// rr L

short CPU::extendedOpcode0x1E() {
	byte reg = memory->read(HL.value);
	rr8bitRegister(&reg);
    memory->write(HL.value, reg);
    return 16;
}// rr (HL)

short CPU::extendedOpcode0x1F() {
    rr8bitRegister(&AF.hi);
    return 8;
}// rr A

void CPU::sla8bitRegister(byte *reg) {
	byte lastBit = *reg & 0x80;
	*reg <<= 1;

	clearFlags();
	if (lastBit != 0x00) {
		raiseFlag(Flag::CARRY_FLAG);
	}
    if ( *reg == 0 ) {
        raiseFlag(ZERO_FLAG);
    }
}

short CPU::extendedOpcode0x20() {
    sla8bitRegister(&BC.hi);
    return 8;
}// sla B

short CPU::extendedOpcode0x21() {
    sla8bitRegister(&BC.low);
    return 8;
}// sla C

short CPU::extendedOpcode0x22() {
    sla8bitRegister(&DE.hi);
    return 8;
}// sla D

short CPU::extendedOpcode0x23() {
    sla8bitRegister(&DE.low);
    return 8;
}// sla E

short CPU::extendedOpcode0x24() {
    sla8bitRegister(&HL.hi);
    return 8;
}// sla H

short CPU::extendedOpcode0x25() {
    sla8bitRegister(&HL.low);
    return 8;
}// sla L

short CPU::extendedOpcode0x26() {
    byte reg = memory->read(HL.value);
	sla8bitRegister(&reg);
    memory->write(HL.value, reg);
    return 16;
}// sla (HL)

short CPU::extendedOpcode0x27() {
    sla8bitRegister(&AF.hi);
    return 8;
}// sla A

void CPU::sra8bitRegister(byte * reg) {
	byte firstBit = *reg & 0x01;
	byte lastBit = *reg & 0x80;

	*reg >>= 1;

	if (lastBit != 0x00) {
		setBit(reg, 7);
	} else {
		clearBit(reg, 7);
	}

	clearFlags();
	if (firstBit == 0x01) {
		raiseFlag(Flag::CARRY_FLAG);
	}
	if (*reg == 0x00) {
		raiseFlag(Flag::ZERO_FLAG);
	}
}

short CPU::extendedOpcode0x28() {
    sra8bitRegister(&BC.hi);
    return 8;
}// sra B

short CPU::extendedOpcode0x29() {
    sra8bitRegister(&BC.low);
    return 8;
}// sra C

short CPU::extendedOpcode0x2A() {
    sra8bitRegister(&DE.hi);
    return 8;
}// sra D

short CPU::extendedOpcode0x2B() {
    sra8bitRegister(&DE.low);
    return 8;
}// sra E

short CPU::extendedOpcode0x2C() {
    sra8bitRegister(&HL.hi);
    return 8;
}// sra H

short CPU::extendedOpcode0x2D(){
    sra8bitRegister(&HL.low);
    return 8;
}// sra L

short CPU::extendedOpcode0x2E() {
    byte data = memory->read(HL.value);
	sra8bitRegister(&data);
	memory->write(HL.value, data);
    return 16;
}// sra (HL)

short CPU::extendedOpcode0x2F() {
    sra8bitRegister(&AF.hi);
    return 8;
}// sra A

void CPU::swap8bitRegister(byte * reg) {
	clearFlags();

	*reg = (((*reg & 0xF0) >> 4) | ((*reg & 0x0F) << 4));

	if ( *reg == 0 ) {
        raiseFlag(ZERO_FLAG);
    }
}

short CPU::extendedOpcode0x30() {
    swap8bitRegister(&BC.hi);
    return 8;
}// swap B

short CPU::extendedOpcode0x31() {
    swap8bitRegister(&BC.low);
    return 8;
}// swap C

short CPU::extendedOpcode0x32() {
    swap8bitRegister(&DE.hi);
    return 8;
}// swap D

short CPU::extendedOpcode0x33() {
    swap8bitRegister(&DE.low);
    return 8;
}// swap E

short CPU::extendedOpcode0x34() {
    swap8bitRegister(&HL.hi);
    return 8;
}// swap H

short CPU::extendedOpcode0x35() {
    swap8bitRegister(&HL.low);
    return 8;
}// swap L

short CPU::extendedOpcode0x36() {
	clearFlags();
    byte data = memory->read(HL.value);
	data = (((data & 0xF0) >> 4) | ((data & 0x0F) << 4));

	if ( data == 0 ) {
        raiseFlag(ZERO_FLAG);
    }

    memory->write(HL.value, data);
    return 16;
}// swap (HL)

short CPU::extendedOpcode0x37() {
    swap8bitRegister(&AF.hi);
    return 8;
}// swap A

void CPU::srl8bitRegister(byte *reg) {
	byte firstBit = *reg & 0x01;
	*reg >>= 1;

	clearBit(reg, 7);

	clearFlags();
	if (firstBit == 0x01) {
        raiseFlag(CARRY_FLAG);
    }
	if (*reg == 0) {
        raiseFlag(ZERO_FLAG);
    }
}

short CPU::extendedOpcode0x38() {
    srl8bitRegister(&BC.hi);
    return 8;
}// SRL B

short CPU::extendedOpcode0x39() {
    srl8bitRegister(&BC.low);
    return 8;
}// SRL C

short CPU::extendedOpcode0x3A() {
    srl8bitRegister(&DE.hi);
    return 8;
}// SRL D

short CPU::extendedOpcode0x3B() {
    srl8bitRegister(&DE.low);
    return 8;
}// SRL E

short CPU::extendedOpcode0x3C() {
    srl8bitRegister(&HL.hi);
    return 8;
}// SRL H

short CPU::extendedOpcode0x3D() {
    srl8bitRegister(&HL.low);
    return 8;
}// SRL L

short CPU::extendedOpcode0x3E() {
    byte data = memory->read(HL.value);
	srl8bitRegister(&data);
	memory->write(HL.value, data);
    return 16;
}// SRL (HL)

short CPU::extendedOpcode0x3F() {
    srl8bitRegister(&AF.hi);
    return 8;
}// SRL A
<|endoftext|>


<commit_before><commit_msg>Add a factory for Loop and refactor Parser class<commit_after><|endoftext|>


<commit_before>//first main function

void main() {

 }<commit_msg>헤더 추가<commit_after>//first main function
#include <stdio.h>
void main() {
	printf("Hello, world!");
 }<|endoftext|>


<commit_before>/*
 * GenesisGamepad.cpp
 *
 * Copyright (c) 2014 Ucodia, Lionel Ringenbach
 *
 * Project URL: https://github.com/Ucodia/ArduinoGenesis
 *
 */

#include "Arduino.h"
#include "GenesisGamepad.h"

// Button pins
#define UP_UP_PIN 2
#define DOWN_DOWN_PIN 3
#define GND_LEFT_PIN 4
#define GND_RIGHT_PIN 5
#define A_B_PIN 6
#define START_C_PIN 7

// Select switch pin
#define SELECT_PIN 8

void GenesisGamepad::init()
{
  // Initialize button pins as input
  pinMode(UP_UP_PIN, INPUT);
  pinMode(DOWN_DOWN_PIN, INPUT);
  pinMode(GND_LEFT_PIN, INPUT);
  pinMode(GND_RIGHT_PIN, INPUT);
  pinMode(A_B_PIN, INPUT);
  pinMode(START_C_PIN, INPUT);

  // Initialize select switch as output
  pinMode(SELECT_PIN, OUTPUT);
}

void GenesisGamepad::update()
{
  // Set select switch to low
  digitalWrite(SELECT_PIN, LOW);

  // Read inputs with select switch on low
  upButton = digitalRead(UP_UP_PIN) == LOW;
  downButton = digitalRead(DOWN_DOWN_PIN) == LOW;
  aButton = digitalRead(A_B_PIN) == LOW;
  startButton = digitalRead(START_C_PIN) == LOW;

  // Set select switch to high
  digitalWrite(SELECT_PIN, HIGH);

  // Read inputs with select switch on high
  leftButton = digitalRead(GND_LEFT_PIN) == LOW;
  rightButton = digitalRead(GND_RIGHT_PIN) == LOW;
  bButton = digitalRead(A_B_PIN) == LOW;
  cButton = digitalRead(START_C_PIN) == LOW;
}
<commit_msg>Replaced pin macros by constants<commit_after>/*
 * GenesisGamepad.cpp
 *
 * Copyright (c) 2014 Ucodia, Lionel Ringenbach
 *
 * Project URL: https://github.com/Ucodia/ArduinoGenesis
 *
 */

#include "Arduino.h"
#include "GenesisGamepad.h"

// Button pins
const int UP_UP_PIN = 2;
const int DOWN_DOWN_PIN = 3;
const int GND_LEFT_PIN = 4;
const int GND_RIGHT_PIN = 5;
const int A_B_PIN = 6;
const int START_C_PIN = 7;

// Select switch pin
const int SELECT_PIN = 8;

void GenesisGamepad::init()
{
  // Initialize button pins as input
  pinMode(UP_UP_PIN, INPUT);
  pinMode(DOWN_DOWN_PIN, INPUT);
  pinMode(GND_LEFT_PIN, INPUT);
  pinMode(GND_RIGHT_PIN, INPUT);
  pinMode(A_B_PIN, INPUT);
  pinMode(START_C_PIN, INPUT);

  // Initialize select switch as output
  pinMode(SELECT_PIN, OUTPUT);
}

void GenesisGamepad::update()
{
  // Set select switch to low
  digitalWrite(SELECT_PIN, LOW);

  // Read inputs with select switch on low
  upButton = digitalRead(UP_UP_PIN) == LOW;
  downButton = digitalRead(DOWN_DOWN_PIN) == LOW;
  aButton = digitalRead(A_B_PIN) == LOW;
  startButton = digitalRead(START_C_PIN) == LOW;

  // Set select switch to high
  digitalWrite(SELECT_PIN, HIGH);

  // Read inputs with select switch on high
  leftButton = digitalRead(GND_LEFT_PIN) == LOW;
  rightButton = digitalRead(GND_RIGHT_PIN) == LOW;
  bButton = digitalRead(A_B_PIN) == LOW;
  cButton = digitalRead(START_C_PIN) == LOW;
}<|endoftext|>