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

 Program:   Visualization Toolkit
 Module:    vtkConvexHull2D.cxx

 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
 All rights reserved.
 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notice for more information.

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

#include "vtkConvexHull2D.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkCoordinate.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointsProjectedHull.h"
#include "vtkPolygon.h"
#include "vtkPolyLine.h"
#include "vtkRenderer.h"
#include "vtkSmartPointer.h"
#include "vtkTransform.h"
#include "vtkTransformPolyDataFilter.h"

vtkStandardNewMacro(vtkConvexHull2D);

//-----------------------------------------------------------------------------
vtkConvexHull2D::vtkConvexHull2D()
{
  this->SetNumberOfOutputPorts(2);
  this->ScaleFactor = 1.0;
  this->Outline = false;
  this->MinHullSizeInWorld = 1.0;
  this->MinHullSizeInDisplay = 10;
  this->HullShape = vtkConvexHull2D::ConvexHull;

  this->Coordinate = vtkSmartPointer<vtkCoordinate>::New();
  this->Transform = vtkSmartPointer<vtkTransform>::New();
  this->OutputTransform = vtkSmartPointer<vtkTransform>::New();
  this->OutputTransformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
  this->OutputTransformFilter->SetTransform(this->OutputTransform);
  this->OutlineSource = vtkSmartPointer<vtkPolyLine>::New();
  this->HullSource = vtkSmartPointer<vtkPolygon>::New();
}

//-----------------------------------------------------------------------------
vtkConvexHull2D::~vtkConvexHull2D()
{
  this->SetRenderer(0);
}

//-----------------------------------------------------------------------------
void vtkConvexHull2D::CalculateBoundingRectangle(vtkPoints* inPoints,
  vtkPoints* outPoints, double minimumHullSize)
{
  minimumHullSize /= 2.0;
  inPoints->ComputeBounds();
  double bounds[6];
  inPoints->GetBounds(bounds);

  double xDeficit = minimumHullSize - (bounds[1] - bounds[0]);
  if (xDeficit > 0.0)
    {
    bounds[0] -= xDeficit;
    bounds[1] += xDeficit;
    }

  double yDeficit = minimumHullSize - (bounds[3] - bounds[2]);
  if (yDeficit > 0.0)
    {
    bounds[2] -= yDeficit;
    bounds[3] += yDeficit;
    }

  outPoints->SetNumberOfPoints(4);
  outPoints->SetPoint(0, bounds[0], bounds[2], 0.0);
  outPoints->SetPoint(1, bounds[1], bounds[2], 0.0);
  outPoints->SetPoint(2, bounds[1], bounds[3], 0.0);
  outPoints->SetPoint(3, bounds[0], bounds[3], 0.0);
}

//-----------------------------------------------------------------------------
void vtkConvexHull2D::CalculateConvexHull(vtkPoints* inPoints,
  vtkPoints* outPoints, double minimumHullSize)
{
  if (inPoints->GetNumberOfPoints() == 1 ||
    inPoints->GetNumberOfPoints() == 2)
    {
    vtkConvexHull2D::CalculateBoundingRectangle(inPoints, outPoints,
     minimumHullSize);
    }
  else if (inPoints->GetNumberOfPoints() >= 3)
    {
    vtkPointsProjectedHull* ppHull = vtkPointsProjectedHull::New();
    ppHull->ShallowCopy(inPoints);
    int numHullPoints = ppHull->GetSizeCCWHullZ();
    double* pts = new double[2 * numHullPoints];
    ppHull->GetCCWHullZ(pts, numHullPoints);

    vtkPoints* hullPoints = vtkPoints::New();
    hullPoints->SetNumberOfPoints(numHullPoints);
    for (vtkIdType i = 0; i < numHullPoints; ++i)
      {
      hullPoints->SetPoint(i, pts[2 * i], pts[2 * i + 1], 0.0);
      }
    ppHull->Delete();
    delete[] pts;

    if (numHullPoints < 3)
      {
      vtkConvexHull2D::CalculateBoundingRectangle(hullPoints, outPoints,
        minimumHullSize);
      return;
      }

    double bounds[6];
    hullPoints->GetBounds(bounds);
    double xScale = std::max(1.0, minimumHullSize / (bounds[1] - bounds[0]));
    double yScale = std::max(1.0, minimumHullSize / (bounds[3] - bounds[2]));
    if (xScale > 1.0 || yScale > 1.0)
      {
      double scale[3] = {xScale, yScale, 1.0};
      double translate[3] = {
        (bounds[0] + (bounds[1] - bounds[0]) / 2.0),
        (bounds[2] + (bounds[3] - bounds[2]) / 2.0), 0.0};

      vtkTransform* transform = vtkTransform::New();
      transform->Translate(translate);
      transform->Scale(scale);
      transform->Translate(-translate[0], -translate[1], -translate[2]);
      transform->TransformPoints(hullPoints, outPoints);
      transform->Delete();
      }
    else
      {
      outPoints->ShallowCopy(hullPoints);
      }
    hullPoints->Delete();
    }
}

//-----------------------------------------------------------------------------
void vtkConvexHull2D::ResizeHullToMinimumInDisplay(vtkPolyData* hullPolyData)
{
  if (this->Renderer && this->Renderer->IsActiveCameraCreated())
      {
      double bounds[6];
      hullPolyData->ComputeBounds();
      hullPolyData->GetBounds(bounds);

      double leftBottom[2];
      double rightTop[2];
      double* coord;
      this->Coordinate->SetCoordinateSystemToWorld();
      this->Coordinate->SetValue(bounds[0], bounds[2], 0.0);
      coord = this->Coordinate->GetComputedDoubleDisplayValue(this->Renderer);
      leftBottom[0] = coord[0];
      leftBottom[1] = coord[1];
      this->Coordinate->SetValue(bounds[1], bounds[3], 0.0);
      coord = this->Coordinate->GetComputedDoubleDisplayValue(this->Renderer);
      rightTop[0] = coord[0];
      rightTop[1] = coord[1];
      double currentDisplaySize[2] = {rightTop[0] - leftBottom[0],
        rightTop[1] - leftBottom[1]};

      if (currentDisplaySize[0] == 0.0 || currentDisplaySize[1] == 0.0)
        {
        vtkWarningMacro(<< "Can not scale a hull with zero display area.")
        return;
        }

      if (currentDisplaySize[0] < this->MinHullSizeInDisplay ||
        currentDisplaySize[1] < this->MinHullSizeInDisplay)
        {
        double scaleFx = std::max(1.0, this->MinHullSizeInDisplay
          / currentDisplaySize[0]);
        double scaleFy = std::max(1.0, this->MinHullSizeInDisplay
          / currentDisplaySize[1]);
        double scale[3] = {scaleFx, scaleFy, 1.0};
        double translate[3] = {
          (bounds[0] + (bounds[1] - bounds[0]) / 2.0),
          (bounds[2] + (bounds[3] - bounds[2]) / 2.0), 0.0};

        this->Transform->Identity();
        this->Transform->Translate(translate);
        this->Transform->Scale(scale);
        this->Transform->Translate(-translate[0], -translate[1], -translate[2]);

        vtkPoints* outPoints = vtkPoints::New();
        this->Transform->TransformPoints(hullPolyData->GetPoints(), outPoints);
        hullPolyData->SetPoints(outPoints);
        outPoints->Delete();
        }
      }
}

//-----------------------------------------------------------------------------
void vtkConvexHull2D::SetRenderer(vtkRenderer* renderer)
{
  this->Renderer = renderer;
  this->Modified();
}

//-----------------------------------------------------------------------------
vtkRenderer* vtkConvexHull2D::GetRenderer()
{
  return this->Renderer;
}

//-----------------------------------------------------------------------------
unsigned long vtkConvexHull2D::GetMTime()
{
  if (this->Renderer)
    {
    return this->Renderer->GetMTime();
    }
  else
    {
    return this->MTime;
    }
}

//-----------------------------------------------------------------------------
int vtkConvexHull2D::RequestData(vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector, vtkInformationVector *outputVector)
{
  // Get the input and output.
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);

  vtkPolyData* input = vtkPolyData::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPoints* inputPoints = input->GetPoints();

  vtkInformation *outInfo0 = outputVector->GetInformationObject(0);
  vtkInformation *outInfo1 = outputVector->GetInformationObject(1);

  vtkPolyData *outputHull = vtkPolyData::SafeDownCast(outInfo0->Get(
    vtkDataObject::DATA_OBJECT()));
  vtkPolyData *outputOutline = vtkPolyData::SafeDownCast(outInfo1->Get(
    vtkDataObject::DATA_OBJECT()));

  // Create filled polygon
  vtkPoints* hullPoints = vtkPoints::New();
  switch (this->HullShape)
  {
    case vtkConvexHull2D::BoundingRectangle:
      this->CalculateBoundingRectangle(inputPoints, hullPoints,
        this->MinHullSizeInWorld);
      break;
    default: // vtkConvexHull2D::ConvexHull
      this->CalculateConvexHull(inputPoints, hullPoints,
        this->MinHullSizeInWorld);
      break;
  }

  vtkIdType numHullPoints = hullPoints->GetNumberOfPoints();
  vtkIdType* hullPts = new vtkIdType[numHullPoints];
  for (int i = 0; i < numHullPoints; ++i)
    {
    hullPts[i] = i;
    }
  this->HullSource->Initialize(numHullPoints, hullPts, hullPoints);
  delete [] hullPts;

  vtkCellArray* hullCells = vtkCellArray::New();
  hullCells->InsertNextCell(this->HullSource);
  vtkSmartPointer<vtkPolyData> hullPolyData = vtkSmartPointer<vtkPolyData>::New();
  hullPolyData->SetPoints(hullPoints);
  hullPolyData->SetPolys(hullCells);
  hullPoints->Delete();
  hullCells->Delete();

  // Adjust for the scale-factor
  double* centre = hullPolyData->GetCenter();
  this->OutputTransform->Identity();
  this->OutputTransform->Translate(centre);
  this->OutputTransform->Scale(this->ScaleFactor, this->ScaleFactor, this->ScaleFactor);
  this->OutputTransform->Translate(-centre[0], -centre[1], -centre[2]);
  this->OutputTransformFilter->SetInput(hullPolyData);
  this->OutputTransformFilter->Update();
  hullPolyData = this->OutputTransformFilter->GetOutput();

  // Account for current camera zoom level
  this->ResizeHullToMinimumInDisplay(hullPolyData);

  // Copy hull to output
  outputHull->ShallowCopy(hullPolyData);

  if (this->Outline)
    {
    vtkIdType numOutlinePoints = outputHull->GetNumberOfPoints();
    vtkIdType* outlinePts = new vtkIdType[numOutlinePoints + 1];
    for (int i = 0; i < numOutlinePoints; ++i)
      {
      outlinePts[i] = i;
      }
    outlinePts[numOutlinePoints] = outlinePts[0];

    this->OutlineSource->Initialize(numOutlinePoints + 1, outlinePts, outputHull->GetPoints());

    vtkSmartPointer<vtkPolyData> outlinePolyData =
      vtkSmartPointer<vtkPolyData>::New();
    vtkCellArray* outlineCells = vtkCellArray::New();
    outlineCells->InsertNextCell(this->OutlineSource);
    outlinePolyData->SetPoints(outputHull->GetPoints());
    outlinePolyData->SetLines(outlineCells);
    outlineCells->Delete();
    delete[] outlinePts;

    // Copy outline to output
    outputOutline->ShallowCopy(outlinePolyData);
    }
  return 1;
}

//-----------------------------------------------------------------------------
void vtkConvexHull2D::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "ScaleFactor: " << this->ScaleFactor << "\n";
  os << indent << "Outline: " << (this->Outline ? "On" : "Off") << "\n";
  os << indent << "HullShape: ";
  switch (this->HullShape)
    {
    case ConvexHull:
      os << "ConvexHull\n";
      break;
    case BoundingRectangle:
      os << "BoundingRectangle\n";
      break;
    default:
      os << "Unknown\n";
      break;
    }
  os << indent << "MinHullSizeInDisplay: " << this->MinHullSizeInDisplay << "\n";
  os << indent << "MinHullSizeInWorld: " << this->MinHullSizeInWorld << "\n";
  os << indent << "Renderer: ";
  if (this->Renderer)
    {
    os << endl;
    this->Renderer->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(none)" << endl;
    }
}
<commit_msg>BUG: Need to initialize renderer ivar<commit_after>/*=========================================================================

 Program:   Visualization Toolkit
 Module:    vtkConvexHull2D.cxx

 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
 All rights reserved.
 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notice for more information.

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

#include "vtkConvexHull2D.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkCoordinate.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointsProjectedHull.h"
#include "vtkPolygon.h"
#include "vtkPolyLine.h"
#include "vtkRenderer.h"
#include "vtkSmartPointer.h"
#include "vtkTransform.h"
#include "vtkTransformPolyDataFilter.h"

vtkStandardNewMacro(vtkConvexHull2D);

//-----------------------------------------------------------------------------
vtkConvexHull2D::vtkConvexHull2D()
{
  this->SetNumberOfOutputPorts(2);
  this->ScaleFactor = 1.0;
  this->Outline = false;
  this->MinHullSizeInWorld = 1.0;
  this->MinHullSizeInDisplay = 10;
  this->HullShape = vtkConvexHull2D::ConvexHull;
  this->Renderer = NULL;

  this->Coordinate = vtkSmartPointer<vtkCoordinate>::New();
  this->Transform = vtkSmartPointer<vtkTransform>::New();
  this->OutputTransform = vtkSmartPointer<vtkTransform>::New();
  this->OutputTransformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
  this->OutputTransformFilter->SetTransform(this->OutputTransform);
  this->OutlineSource = vtkSmartPointer<vtkPolyLine>::New();
  this->HullSource = vtkSmartPointer<vtkPolygon>::New();
}

//-----------------------------------------------------------------------------
vtkConvexHull2D::~vtkConvexHull2D()
{
  this->SetRenderer(0);
}

//-----------------------------------------------------------------------------
void vtkConvexHull2D::CalculateBoundingRectangle(vtkPoints* inPoints,
  vtkPoints* outPoints, double minimumHullSize)
{
  minimumHullSize /= 2.0;
  inPoints->ComputeBounds();
  double bounds[6];
  inPoints->GetBounds(bounds);

  double xDeficit = minimumHullSize - (bounds[1] - bounds[0]);
  if (xDeficit > 0.0)
    {
    bounds[0] -= xDeficit;
    bounds[1] += xDeficit;
    }

  double yDeficit = minimumHullSize - (bounds[3] - bounds[2]);
  if (yDeficit > 0.0)
    {
    bounds[2] -= yDeficit;
    bounds[3] += yDeficit;
    }

  outPoints->SetNumberOfPoints(4);
  outPoints->SetPoint(0, bounds[0], bounds[2], 0.0);
  outPoints->SetPoint(1, bounds[1], bounds[2], 0.0);
  outPoints->SetPoint(2, bounds[1], bounds[3], 0.0);
  outPoints->SetPoint(3, bounds[0], bounds[3], 0.0);
}

//-----------------------------------------------------------------------------
void vtkConvexHull2D::CalculateConvexHull(vtkPoints* inPoints,
  vtkPoints* outPoints, double minimumHullSize)
{
  if (inPoints->GetNumberOfPoints() == 1 ||
    inPoints->GetNumberOfPoints() == 2)
    {
    vtkConvexHull2D::CalculateBoundingRectangle(inPoints, outPoints,
     minimumHullSize);
    }
  else if (inPoints->GetNumberOfPoints() >= 3)
    {
    vtkPointsProjectedHull* ppHull = vtkPointsProjectedHull::New();
    ppHull->ShallowCopy(inPoints);
    int numHullPoints = ppHull->GetSizeCCWHullZ();
    double* pts = new double[2 * numHullPoints];
    ppHull->GetCCWHullZ(pts, numHullPoints);

    vtkPoints* hullPoints = vtkPoints::New();
    hullPoints->SetNumberOfPoints(numHullPoints);
    for (vtkIdType i = 0; i < numHullPoints; ++i)
      {
      hullPoints->SetPoint(i, pts[2 * i], pts[2 * i + 1], 0.0);
      }
    ppHull->Delete();
    delete[] pts;

    if (numHullPoints < 3)
      {
      vtkConvexHull2D::CalculateBoundingRectangle(hullPoints, outPoints,
        minimumHullSize);
      return;
      }

    double bounds[6];
    hullPoints->GetBounds(bounds);
    double xScale = std::max(1.0, minimumHullSize / (bounds[1] - bounds[0]));
    double yScale = std::max(1.0, minimumHullSize / (bounds[3] - bounds[2]));
    if (xScale > 1.0 || yScale > 1.0)
      {
      double scale[3] = {xScale, yScale, 1.0};
      double translate[3] = {
        (bounds[0] + (bounds[1] - bounds[0]) / 2.0),
        (bounds[2] + (bounds[3] - bounds[2]) / 2.0), 0.0};

      vtkTransform* transform = vtkTransform::New();
      transform->Translate(translate);
      transform->Scale(scale);
      transform->Translate(-translate[0], -translate[1], -translate[2]);
      transform->TransformPoints(hullPoints, outPoints);
      transform->Delete();
      }
    else
      {
      outPoints->ShallowCopy(hullPoints);
      }
    hullPoints->Delete();
    }
}

//-----------------------------------------------------------------------------
void vtkConvexHull2D::ResizeHullToMinimumInDisplay(vtkPolyData* hullPolyData)
{
  if (this->Renderer && this->Renderer->IsActiveCameraCreated())
      {
      double bounds[6];
      hullPolyData->ComputeBounds();
      hullPolyData->GetBounds(bounds);

      double leftBottom[2];
      double rightTop[2];
      double* coord;
      this->Coordinate->SetCoordinateSystemToWorld();
      this->Coordinate->SetValue(bounds[0], bounds[2], 0.0);
      coord = this->Coordinate->GetComputedDoubleDisplayValue(this->Renderer);
      leftBottom[0] = coord[0];
      leftBottom[1] = coord[1];
      this->Coordinate->SetValue(bounds[1], bounds[3], 0.0);
      coord = this->Coordinate->GetComputedDoubleDisplayValue(this->Renderer);
      rightTop[0] = coord[0];
      rightTop[1] = coord[1];
      double currentDisplaySize[2] = {rightTop[0] - leftBottom[0],
        rightTop[1] - leftBottom[1]};

      if (currentDisplaySize[0] == 0.0 || currentDisplaySize[1] == 0.0)
        {
        vtkWarningMacro(<< "Can not scale a hull with zero display area.")
        return;
        }

      if (currentDisplaySize[0] < this->MinHullSizeInDisplay ||
        currentDisplaySize[1] < this->MinHullSizeInDisplay)
        {
        double scaleFx = std::max(1.0, this->MinHullSizeInDisplay
          / currentDisplaySize[0]);
        double scaleFy = std::max(1.0, this->MinHullSizeInDisplay
          / currentDisplaySize[1]);
        double scale[3] = {scaleFx, scaleFy, 1.0};
        double translate[3] = {
          (bounds[0] + (bounds[1] - bounds[0]) / 2.0),
          (bounds[2] + (bounds[3] - bounds[2]) / 2.0), 0.0};

        this->Transform->Identity();
        this->Transform->Translate(translate);
        this->Transform->Scale(scale);
        this->Transform->Translate(-translate[0], -translate[1], -translate[2]);

        vtkPoints* outPoints = vtkPoints::New();
        this->Transform->TransformPoints(hullPolyData->GetPoints(), outPoints);
        hullPolyData->SetPoints(outPoints);
        outPoints->Delete();
        }
      }
}

//-----------------------------------------------------------------------------
void vtkConvexHull2D::SetRenderer(vtkRenderer* renderer)
{
  this->Renderer = renderer;
  this->Modified();
}

//-----------------------------------------------------------------------------
vtkRenderer* vtkConvexHull2D::GetRenderer()
{
  return this->Renderer;
}

//-----------------------------------------------------------------------------
unsigned long vtkConvexHull2D::GetMTime()
{
  if (this->Renderer)
    {
    return this->Renderer->GetMTime();
    }
  else
    {
    return this->MTime;
    }
}

//-----------------------------------------------------------------------------
int vtkConvexHull2D::RequestData(vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector, vtkInformationVector *outputVector)
{
  // Get the input and output.
  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);

  vtkPolyData* input = vtkPolyData::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPoints* inputPoints = input->GetPoints();

  vtkInformation *outInfo0 = outputVector->GetInformationObject(0);
  vtkInformation *outInfo1 = outputVector->GetInformationObject(1);

  vtkPolyData *outputHull = vtkPolyData::SafeDownCast(outInfo0->Get(
    vtkDataObject::DATA_OBJECT()));
  vtkPolyData *outputOutline = vtkPolyData::SafeDownCast(outInfo1->Get(
    vtkDataObject::DATA_OBJECT()));

  // Create filled polygon
  vtkPoints* hullPoints = vtkPoints::New();
  switch (this->HullShape)
  {
    case vtkConvexHull2D::BoundingRectangle:
      this->CalculateBoundingRectangle(inputPoints, hullPoints,
        this->MinHullSizeInWorld);
      break;
    default: // vtkConvexHull2D::ConvexHull
      this->CalculateConvexHull(inputPoints, hullPoints,
        this->MinHullSizeInWorld);
      break;
  }

  vtkIdType numHullPoints = hullPoints->GetNumberOfPoints();
  vtkIdType* hullPts = new vtkIdType[numHullPoints];
  for (int i = 0; i < numHullPoints; ++i)
    {
    hullPts[i] = i;
    }
  this->HullSource->Initialize(numHullPoints, hullPts, hullPoints);
  delete [] hullPts;

  vtkCellArray* hullCells = vtkCellArray::New();
  hullCells->InsertNextCell(this->HullSource);
  vtkSmartPointer<vtkPolyData> hullPolyData = vtkSmartPointer<vtkPolyData>::New();
  hullPolyData->SetPoints(hullPoints);
  hullPolyData->SetPolys(hullCells);
  hullPoints->Delete();
  hullCells->Delete();

  // Adjust for the scale-factor
  double* centre = hullPolyData->GetCenter();
  this->OutputTransform->Identity();
  this->OutputTransform->Translate(centre);
  this->OutputTransform->Scale(this->ScaleFactor, this->ScaleFactor, this->ScaleFactor);
  this->OutputTransform->Translate(-centre[0], -centre[1], -centre[2]);
  this->OutputTransformFilter->SetInput(hullPolyData);
  this->OutputTransformFilter->Update();
  hullPolyData = this->OutputTransformFilter->GetOutput();

  // Account for current camera zoom level
  this->ResizeHullToMinimumInDisplay(hullPolyData);

  // Copy hull to output
  outputHull->ShallowCopy(hullPolyData);

  if (this->Outline)
    {
    vtkIdType numOutlinePoints = outputHull->GetNumberOfPoints();
    vtkIdType* outlinePts = new vtkIdType[numOutlinePoints + 1];
    for (int i = 0; i < numOutlinePoints; ++i)
      {
      outlinePts[i] = i;
      }
    outlinePts[numOutlinePoints] = outlinePts[0];

    this->OutlineSource->Initialize(numOutlinePoints + 1, outlinePts, outputHull->GetPoints());

    vtkSmartPointer<vtkPolyData> outlinePolyData =
      vtkSmartPointer<vtkPolyData>::New();
    vtkCellArray* outlineCells = vtkCellArray::New();
    outlineCells->InsertNextCell(this->OutlineSource);
    outlinePolyData->SetPoints(outputHull->GetPoints());
    outlinePolyData->SetLines(outlineCells);
    outlineCells->Delete();
    delete[] outlinePts;

    // Copy outline to output
    outputOutline->ShallowCopy(outlinePolyData);
    }
  return 1;
}

//-----------------------------------------------------------------------------
void vtkConvexHull2D::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "ScaleFactor: " << this->ScaleFactor << "\n";
  os << indent << "Outline: " << (this->Outline ? "On" : "Off") << "\n";
  os << indent << "HullShape: ";
  switch (this->HullShape)
    {
    case ConvexHull:
      os << "ConvexHull\n";
      break;
    case BoundingRectangle:
      os << "BoundingRectangle\n";
      break;
    default:
      os << "Unknown\n";
      break;
    }
  os << indent << "MinHullSizeInDisplay: " << this->MinHullSizeInDisplay << "\n";
  os << indent << "MinHullSizeInWorld: " << this->MinHullSizeInWorld << "\n";
  os << indent << "Renderer: ";
  if (this->Renderer)
    {
    os << endl;
    this->Renderer->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(none)" << endl;
    }
}
<|endoftext|>


<commit_before>/**************************************************************************************/
/*                                                                                */
/*  Visualization Library                                                             */
/*  http://www.visualizationlibrary.com                                               */
/*                                                                                */
/*  Copyright (c) 2005-2010, Michele Bosi                                             */
/*  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.                                   */
/*                                                                                */
/*  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 HOLDER 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.                      */
/*                                                                                */
/**************************************************************************************/

#ifndef CameraReadPixels_INCLUDE_ONCE
#define CameraReadPixels_INCLUDE_ONCE

#include <vlGraphics/Camera.hpp>
#include <vlCore/Say.hpp>
#include <vlCore/Log.hpp>
#include <vlGraphics/RenderEventCallback.hpp>
#include <vlGraphics/vlTGA.hpp>
#include <vlGraphics/vlTIFF.hpp>
#include <vlGraphics/vlPNG.hpp>
#include <vlGraphics/vlJPG.hpp>
#include <vlCore/Image.hpp>

namespace vl
{
  //-----------------------------------------------------------------------------
  // ReadPixels
  //-----------------------------------------------------------------------------
  /**
   * A RenderEventCallback that copyes a rectangular pixel area from a source
   * buffer to an Image at the end of a rendering.
   *
   * The actual copy is performed using the function Image::readPixels().
   * Using the function setSavePath() the Image will be saved
   * on the specified location.
   *
   * \sa
   * - Image
   * - Image::readPixels()
   * - RenderEventCallback
  */
  class ReadPixels: public RenderEventCallback
  {
  public:
    virtual const char* className() { return "ReadPixels"; }
    ReadPixels():
      mX ( 0 ),
      mY ( 0 ),
      mWidth ( 0 ),
      mHeight ( 0 ),
      mReadBuffer ( RDB_BACK_LEFT ),
      mStoreInPixelBufferObject(false)
    {
      #ifndef NDEBUG
        mObjectName = className();
      #endif
    }

    ReadPixels(int x, int y, int width, int height, EReadDrawBuffer read_buffer, Image* image, bool store_in_pbo):
      mX ( x ),
      mY ( y ),
      mWidth  ( width ),
      mHeight ( height ),
      mReadBuffer ( read_buffer ),
      mImage ( image ),
      mStoreInPixelBufferObject( store_in_pbo )
    {
      #ifndef NDEBUG
        mObjectName = className();
      #endif
    }

    virtual bool onRenderingStarted(const RenderingAbstract*)
    {
      readPixels();
      return true;
    }

    virtual bool onRenderingFinished(const RenderingAbstract*)
    {
      readPixels();
      return true;
    }

    virtual bool onRendererStarted(const RendererAbstract*)
    {
      readPixels();
      return true;
    }

    virtual bool onRendererFinished(const RendererAbstract*)
    {
      readPixels();
      return true;
    }

    void setup(int x, int y, int width, int height, EReadDrawBuffer read_buffer, bool store_in_pbo)
    {
      mX = x;
      mY = y;
      mWidth  = width;
      mHeight = height;
      mReadBuffer = read_buffer;
      mStoreInPixelBufferObject = store_in_pbo;
    }

    void setX(int x) { mX = x; }
    void setY(int y) { mY = y; }
    void setWidth(int width) { mWidth = width; }
    void setHeight(int height) { mHeight = height; }
    void setReadBuffer(EReadDrawBuffer buffer) { mReadBuffer = buffer; }
    void setImage(Image* image) { mImage = image; }
    void setSavePath(const String& path) { mSavePath = path; }

    int x() const { return mX; }
    int y() const { return mY; }
    int width() const { return mWidth; }
    int height() const { return mHeight; }
    EReadDrawBuffer readBuffer() const { return mReadBuffer; }
    Image* image() { return mImage.get(); }
    const Image* image() const { return mImage.get(); }
    const String& savePath() const { return mSavePath; }

    void setStoreInPixelBufferObject( bool use_pbo ) { mStoreInPixelBufferObject = use_pbo; }
    bool storeInPixelBufferObject() const { return mStoreInPixelBufferObject; }

  protected:
    void readPixels()
    {
      if (mImage.get() == NULL)
        mImage = new Image;
      mImage->readPixels(mX, mY, mWidth, mHeight, mReadBuffer, storeInPixelBufferObject() );
      if ( savePath().length() )
      {
        if (!saveImage(mImage.get(), savePath()))
          Log::error( Say("ReadPixels: unknown format for file: '%s'\n") << savePath() );
      }
    }

  protected:
    int mX;
    int mY;
    int mWidth;
    int mHeight;
    EReadDrawBuffer mReadBuffer;
    ref<Image> mImage;
    String mSavePath;
    bool mStoreInPixelBufferObject;
  };
}

#endif
<commit_msg>readPixels() function moved to ReadPixels.hpp file temporarily.<commit_after>/**************************************************************************************/
/*                                                                                */
/*  Visualization Library                                                             */
/*  http://www.visualizationlibrary.com                                               */
/*                                                                                */
/*  Copyright (c) 2005-2010, Michele Bosi                                             */
/*  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.                                   */
/*                                                                                */
/*  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 HOLDER 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.                      */
/*                                                                                */
/**************************************************************************************/

#ifndef CameraReadPixels_INCLUDE_ONCE
#define CameraReadPixels_INCLUDE_ONCE

#include <vlGraphics/Camera.hpp>
#include <vlCore/Say.hpp>
#include <vlCore/Log.hpp>
#include <vlGraphics/RenderEventCallback.hpp>
#include <vlGraphics/GLBufferObject.hpp>
#include <vlGraphics/vlTGA.hpp>
#include <vlGraphics/vlTIFF.hpp>
#include <vlGraphics/vlPNG.hpp>
#include <vlGraphics/vlJPG.hpp>
#include <vlCore/Image.hpp>

namespace vl
{
  //-----------------------------------------------------------------------------
  // vl::readPixels()
  //-----------------------------------------------------------------------------
  /** Reads a rectangular pixel area from the specified read buffer and stores it in an Image.
   *
   * If 'store_in_pixel_buffer_object' is true the data will be copied in the GPU memory using the GL_EXT_pixel_buffer_object
   * extension, while the local buffer will be deallocated.
   *
   * \note
   * The image returned by this function might seem flipped upside down. */
  inline void readPixels(Image* image, int x, int y, int w, int h, EReadDrawBuffer read_buffer, bool store_in_pixel_buffer_object)
  {
    // clears OpenGL errors
    glGetError();

    glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);

    glPixelStorei( GL_PACK_ALIGNMENT,   1);
    glPixelStorei( GL_PACK_ROW_LENGTH,  w);
    glPixelStorei( GL_PACK_SKIP_PIXELS, 0);
    glPixelStorei( GL_PACK_SKIP_ROWS,   0);
    glPixelStorei( GL_PACK_SWAP_BYTES,  0);
    glPixelStorei( GL_PACK_LSB_FIRST,   0);
    if (GLEW_VERSION_1_2)
    {
      glPixelStorei( GL_PACK_IMAGE_HEIGHT, 0 );
      glPixelStorei( GL_PACK_SKIP_IMAGES,  0 );
    }

    int prev = 0;
    glGetIntegerv( GL_READ_BUFFER, &prev ); VL_CHECK_OGL()
    glReadBuffer( read_buffer );
    #ifndef NDEBUG
      if (glGetError() != GL_NO_ERROR)
      {
        Log::print(Say("Image::readPixels() error: %s:%n\n"
          "You seem to have specified a wrong read buffer for the bound render target,\n"
          "for example you might have specified a RDB_BACK_LEFT but the active camera\n"
          "is bound to a FBO (Framebuffer Object) render target or the selected\n"
          "read buffer is FBO-specific (like RDB_COLOR_ATTACHMENT0_EXT) but the active\n"
          "camera is not bound to a FBO render target. \n") << __FILE__ << __LINE__
        );
        VL_TRAP()
      }
    #endif

    bool supports_pbo = GLEW_ARB_pixel_buffer_object||GLEW_EXT_pixel_buffer_object||GLEW_VERSION_2_1;
    GLBufferObject* glbuf = dynamic_cast<GLBufferObject*>(image->imageBuffer());

    if (store_in_pixel_buffer_object && supports_pbo)
    {
      int bytes = image->requiredMemory2D(w, h, 1, image->format(), image->type());
      // allocates the PBO
      glbuf->setBufferData( bytes, NULL, glbuf->usage() );
      // bind the pbo
      VL_glBindBuffer( GL_PIXEL_PACK_BUFFER, glbuf->handle() );
      // read pixels into the pbo
      glReadPixels( x, y, w, h, image->format(), image->type(), 0);
      // unbind the pbo
      VL_glBindBuffer( GL_PIXEL_PACK_BUFFER, 0 );

      // deallocates the local storage and sets up the image configuration
      image->reset(w, h, 0, 1, image->format(), image->type(), false);

      // test GPU -> local copy
      //if (w != image->width() || h != image->height() || image->dimension() != ID_2D || image->pixels() == NULL)
      //  image->allocate2D( w, h, 1, image->format(), image->type() );
      //glbuf->downloadGLBufferObject();
    }
    else
    {
      if (w != image->width() || h != image->height() || image->dimension() != ID_2D || image->pixels() == NULL)
        image->allocate2D( w, h, 1, image->format(), image->type() );
      glReadPixels( x, y, w, h, image->format(), image->type(), image->pixels() );
    }

    // restore read buffer
    glReadBuffer( prev );
    glPopClientAttrib();

    VL_CHECK_OGL()
  }
  //-----------------------------------------------------------------------------
  // ReadPixels
  //-----------------------------------------------------------------------------
  /**
   * A RenderEventCallback that copyes a rectangular pixel area from a source
   * buffer to an Image at the end of a rendering.
   *
   * The actual copy is performed using the function Image::readPixels().
   * Using the function setSavePath() the Image will be saved
   * on the specified location.
   *
   * \sa
   * - Image
   * - Image::readPixels()
   * - RenderEventCallback
  */
  class ReadPixels: public RenderEventCallback
  {
  public:
    virtual const char* className() { return "ReadPixels"; }
    ReadPixels():
      mX ( 0 ),
      mY ( 0 ),
      mWidth ( 0 ),
      mHeight ( 0 ),
      mReadBuffer ( RDB_BACK_LEFT ),
      mStoreInPixelBufferObject(false)
    {
      #ifndef NDEBUG
        mObjectName = className();
      #endif
    }

    ReadPixels(int x, int y, int width, int height, EReadDrawBuffer read_buffer, Image* image, bool store_in_pbo):
      mX ( x ),
      mY ( y ),
      mWidth  ( width ),
      mHeight ( height ),
      mReadBuffer ( read_buffer ),
      mImage ( image ),
      mStoreInPixelBufferObject( store_in_pbo )
    {
      #ifndef NDEBUG
        mObjectName = className();
      #endif
    }

    virtual bool onRenderingStarted(const RenderingAbstract*)
    {
      readPixels();
      return true;
    }

    virtual bool onRenderingFinished(const RenderingAbstract*)
    {
      readPixels();
      return true;
    }

    virtual bool onRendererStarted(const RendererAbstract*)
    {
      readPixels();
      return true;
    }

    virtual bool onRendererFinished(const RendererAbstract*)
    {
      readPixels();
      return true;
    }

    void setup(int x, int y, int width, int height, EReadDrawBuffer read_buffer, bool store_in_pbo)
    {
      mX = x;
      mY = y;
      mWidth  = width;
      mHeight = height;
      mReadBuffer = read_buffer;
      mStoreInPixelBufferObject = store_in_pbo;
    }

    void setX(int x) { mX = x; }
    void setY(int y) { mY = y; }
    void setWidth(int width) { mWidth = width; }
    void setHeight(int height) { mHeight = height; }
    void setReadBuffer(EReadDrawBuffer buffer) { mReadBuffer = buffer; }
    void setImage(Image* image) { mImage = image; }
    void setSavePath(const String& path) { mSavePath = path; }

    int x() const { return mX; }
    int y() const { return mY; }
    int width() const { return mWidth; }
    int height() const { return mHeight; }
    EReadDrawBuffer readBuffer() const { return mReadBuffer; }
    Image* image() { return mImage.get(); }
    const Image* image() const { return mImage.get(); }
    const String& savePath() const { return mSavePath; }

    void setStoreInPixelBufferObject( bool use_pbo ) { mStoreInPixelBufferObject = use_pbo; }
    bool storeInPixelBufferObject() const { return mStoreInPixelBufferObject; }

  protected:
    void readPixels()
    {
      if (mImage.get() == NULL)
        mImage = new Image;
      vl::readPixels(mImage.get(), mX, mY, mWidth, mHeight, mReadBuffer, storeInPixelBufferObject() );
      if ( savePath().length() )
      {
        if (!saveImage(mImage.get(), savePath()))
          Log::error( Say("ReadPixels: unknown format for file: '%s'\n") << savePath() );
      }
    }

  protected:
    int mX;
    int mY;
    int mWidth;
    int mHeight;
    EReadDrawBuffer mReadBuffer;
    ref<Image> mImage;
    String mSavePath;
    bool mStoreInPixelBufferObject;
  };
}

#endif
<|endoftext|>


<commit_before>/*
 * logger.cpp
 *
 */

#include "logger.h"

namespace himan
{
HPDebugState logger::MainDebugState = himan::kInfoMsg;

logger::logger() : itsDebugState(kInfoMsg), itsUserName("HimanDefaultLogger")
{
}
logger::logger(const std::string& theUserName) : itsDebugState(MainDebugState), itsUserName(theUserName)
{
}
logger::logger(const std::string& theUserName, HPDebugState theDebugState)
    : itsDebugState(theDebugState), itsUserName(theUserName)
{
}

}  // namespace himan
<commit_msg>Change default logging level to debug (was previously set in himan.cpp)<commit_after>/*
 * logger.cpp
 *
 */

#include "logger.h"

namespace himan
{
HPDebugState logger::MainDebugState = himan::kDebugMsg;

logger::logger() : itsDebugState(kInfoMsg), itsUserName("HimanDefaultLogger")
{
}
logger::logger(const std::string& theUserName) : itsDebugState(MainDebugState), itsUserName(theUserName)
{
}
logger::logger(const std::string& theUserName, HPDebugState theDebugState)
    : itsDebugState(theDebugState), itsUserName(theUserName)
{
}

}  // namespace himan
<|endoftext|>


<commit_before>// LineCounter.cpp : Defines the entry point for the console application.

#include "stdafx.h"
using namespace std;

#pragma comment(lib, "User32.lib")

int linesInFile(WIN32_FIND_DATA); // Returns the number of lines in the file to which the argument is a handle
int linesInDirectory(string); // Returns if an error occurred, exactly like main
int linesInDirectoryRecursive(string); // Returns the number of lines in the directory tree with root directory given, or -1 if an error occurred

void help(const char*); // Prints the help message to cout
bool isHelpFlag(const char*); // Returns whether the passed string is a recognized help flag

int main(int argc, char* argv[])
{
	string dir;
	bool recursive(false); // Whether to use a recursive count
	if (argc == 1) // No arguments: Print warning and help message, then flat-count files in current working directory.
	{
		dir = _getcwd(nullptr, 0);
		fprintf(stderr, "Warning: No directory given, assuming %s\n", dir.c_str());
		help(argv[0]);
		cout << endl;
	}
	else if (argc == 2) // Only one argument given
	{
		if (isHelpFlag(argv[1])) // If its a help flag, print the help message and return
		{
			help(argv[0]);
			return 0;
		}
		else if (!strcmp(argv[1], "/r")) // If its the recursive flag, print warning and help message, then recursive-count files in current working directory.
		{
			dir = _getcwd(nullptr, 0);
			recursive = true;
			fprintf(stderr, "Warning: No directory given, assuming %s\n", dir.c_str());
			help(argv[0]);
			cout << endl;
		}
		dir = argv[1]; // Else, assume that the argument is the directory to count
	}
	else if (argc==3) // Two arguments given
	{
		size_t dirpos(1);
		recursive = true; // If the program proceeds, it will be in recursive mode
		if (!strcmp(argv[dirpos], "/r")) // If the first argument is the recursive flag
			dirpos = 2; // The path will be in the second argument
		else if (strcmp(argv[2], "/r")) // If the second argument isn't the recursive flag...
		{
			fprintf(stderr, "Invalid arguments \"%s\", \"%s\"\n", argv[1], argv[2]); // Generate an error,
			help(argv[0]); // Print the help message,
			return 127; // And exit with an error.
		}
		dir = argv[dirpos]; // If we haven't exited, this will set dir to contain the path
	}
	else // If there are more than two arguments, print an error message with all arguments, print the help message, and exit with an error
	{
		cerr << "Invalid arguments \"" << argv[1] << "\"";
		for (int i = 2; i < argc; ++i)
			cerr << ", \"" << argv[i] << "\"";
		help(argv[0]);
		return 127;
	}
	if (recursive)
		return linesInDirectoryRecursive(dir) == -1;
	else
		return linesInDirectory(dir);
}

int linesInDirectory(string dir)
{
	WIN32_FIND_DATA	ffd;

	cout << "Target directory is " << dir << endl;

	_chdir(dir.c_str());
	dir += "\\*";

	HANDLE find = INVALID_HANDLE_VALUE;
	find = FindFirstFile(dir.c_str(), &ffd);

	if (find == INVALID_HANDLE_VALUE)
	{
		cerr << "No files found!\n";
		return 1;
	}

	uintmax_t sum(0);
	size_t len(0);

	do
	{
		len = linesInFile(ffd);
		sum += len;
		cout << "\tFile " << ffd.cFileName << ": " << len << " lines.\n";
		cout << "\t\tRunning total: " << sum << endl << endl;
	} while (FindNextFile(find, &ffd));

	char msg[9001];
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | 80, NULL, GetLastError(), 0, msg, 9001, NULL);
	cout << "\n\n" << msg;

	cout << "\n\nTotal number of lines in files in the directory " << _getcwd(NULL, NULL) << ": " << sum << ".\n";
	return 0;
}

int linesInDirectoryRecursive(string dir)
{
	WIN32_FIND_DATA	ffd;

	cout << "Target directory is " << dir << endl;

	_chdir(dir.c_str());
	dir += "\\*";

	HANDLE find = INVALID_HANDLE_VALUE;
	find = FindFirstFile(dir.c_str(), &ffd);

	if (find == INVALID_HANDLE_VALUE)
	{
		cerr << "No files found!\n";
		return -1;
	}

	uintmax_t sum(0);
	size_t len(0);

	do
	{
		if (ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
		{
			cout << "\n\nFound directory " << ffd.cFileName << ".\n";
			cout << "Counting lines in directory...\n\n";
			len = linesInDirectoryRecursive(dir);
			if (len != -1)
				sum += len;
			cout << "Done with subdirectory " << ffd.cFileName << ".\n";
			cout << "\tRunning total of lines in " << dir << ": " << sum << ".\n\n";
		}
		else
		{
			len = linesInFile(ffd);
			sum += len;
			cout << "\tFile " << ffd.cFileName << ": " << len << " lines.\n";
			cout << "\t\tRunning total: " << sum << endl << endl;
		}
	} while (FindNextFile(find, &ffd));

	char msg[9001];
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | 80, NULL, GetLastError(), 0, msg, 9001, NULL);
	cout << "\n\n" << msg;

	cout << "\n\nTotal number of lines in files in the directory " << _getcwd(NULL, NULL) << ": " << sum << ".\n";
	return sum;
}

int linesInFile(WIN32_FIND_DATA ffd)
{
	ifstream in;

	if (ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
		return 0;

	in.open(ffd.cFileName, ios::in);
	size_t len(0);
	string line;
	while (in.good())
	{
		getline(in, line);
		++len;
	}
	in.clear();
	in.close();

	return len;
}

void help(const char* prog)
{
	cout << "LineCounter: Counts the number of lines in all files of the chosen directory.\n";
	cout << "Usage: " << prog << " [directory_path] [/r]\n";
	cout << "    directory_path: The path to the directory in which to count lines\n";
	cout << "        If omitted, will print a warning message and count files in the current\n";
	cout << "        working directory.\n";
	cout << "    /r: Recursive mode\n";
	cout << "        By default, LineCounter will only count files directly in the directory\n";
	cout << "        given: That is, it will produce a flat count.\n";
	cout << "        Passing this flag will instruct it to count files in all subdirectories\n";
	cout << "        as well: A recursive count.\n";
}

bool isHelpFlag(const char* arg)
{
	return !strcmp(arg, "/h") || !strcmp(arg, "/help") || !strcmp(arg, "/?") || !strcmp(arg, "-h") || !strcmp(arg, "--help");
}

<commit_msg>Skip special directories<commit_after>// LineCounter.cpp : Defines the entry point for the console application.

#include "stdafx.h"
using namespace std;

#pragma comment(lib, "User32.lib")

int linesInFile(WIN32_FIND_DATA); // Returns the number of lines in the file to which the argument is a handle
int linesInDirectory(string); // Returns if an error occurred, exactly like main
int linesInDirectoryRecursive(string); // Returns the number of lines in the directory tree with root directory given, or -1 if an error occurred

void help(const char*); // Prints the help message to cout
bool isHelpFlag(const char*); // Returns whether the passed string is a recognized help flag

int main(int argc, char* argv[])
{
	string dir;
	bool recursive(false); // Whether to use a recursive count
	if (argc == 1) // No arguments: Print warning and help message, then flat-count files in current working directory.
	{
		dir = _getcwd(nullptr, 0);
		fprintf(stderr, "Warning: No directory given, assuming %s\n", dir.c_str());
		help(argv[0]);
		cout << endl;
	}
	else if (argc == 2) // Only one argument given
	{
		if (isHelpFlag(argv[1])) // If its a help flag, print the help message and return
		{
			help(argv[0]);
			return 0;
		}
		else if (!strcmp(argv[1], "/r")) // If its the recursive flag, print warning and help message, then recursive-count files in current working directory.
		{
			dir = _getcwd(nullptr, 0);
			recursive = true;
			fprintf(stderr, "Warning: No directory given, assuming %s\n", dir.c_str());
			help(argv[0]);
			cout << endl;
		}
		dir = argv[1]; // Else, assume that the argument is the directory to count
	}
	else if (argc==3) // Two arguments given
	{
		size_t dirpos(1);
		recursive = true; // If the program proceeds, it will be in recursive mode
		if (!strcmp(argv[dirpos], "/r")) // If the first argument is the recursive flag
			dirpos = 2; // The path will be in the second argument
		else if (strcmp(argv[2], "/r")) // If the second argument isn't the recursive flag...
		{
			fprintf(stderr, "Invalid arguments \"%s\", \"%s\"\n", argv[1], argv[2]); // Generate an error,
			help(argv[0]); // Print the help message,
			return 127; // And exit with an error.
		}
		dir = argv[dirpos]; // If we haven't exited, this will set dir to contain the path
	}
	else // If there are more than two arguments, print an error message with all arguments, print the help message, and exit with an error
	{
		cerr << "Invalid arguments \"" << argv[1] << "\"";
		for (int i = 2; i < argc; ++i)
			cerr << ", \"" << argv[i] << "\"";
		help(argv[0]);
		return 127;
	}
	if (recursive)
		return linesInDirectoryRecursive(dir) == -1;
	else
		return linesInDirectory(dir);
}

int linesInDirectory(string dir)
{
	WIN32_FIND_DATA	ffd;

	cout << "Target directory is " << dir << endl;

	_chdir(dir.c_str());
	dir += "\\*";

	HANDLE find = INVALID_HANDLE_VALUE;
	find = FindFirstFile(dir.c_str(), &ffd);

	if (find == INVALID_HANDLE_VALUE)
	{
		cerr << "No files found!\n";
		return 1;
	}

	uintmax_t sum(0);
	size_t len(0);

	do
	{
		len = linesInFile(ffd);
		sum += len;
		cout << "\tFile " << ffd.cFileName << ": " << len << " lines.\n";
		cout << "\t\tRunning total: " << sum << endl << endl;
	} while (FindNextFile(find, &ffd));

	char msg[9001];
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | 80, NULL, GetLastError(), 0, msg, 9001, NULL);
	cout << "\n\n" << msg;

	cout << "\n\nTotal number of lines in files in the directory " << _getcwd(NULL, NULL) << ": " << sum << ".\n";
	return 0;
}

int linesInDirectoryRecursive(string dir)
{
	WIN32_FIND_DATA	ffd;

	cout << "Target directory is " << dir << endl;

	_chdir(dir.c_str());
	dir += "\\*";

	HANDLE find = INVALID_HANDLE_VALUE;
	find = FindFirstFile(dir.c_str(), &ffd);

	if (find == INVALID_HANDLE_VALUE)
	{
		cerr << "No files found!\n";
		return -1;
	}

	uintmax_t sum(0);
	size_t len(0);

	do
	{
		if (ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
		{
			if (!strcmp(ffd.cFileName, ".") || !stricmp(ffd.cFileName, ".."))
				continue;
			cout << "\n\nFound directory " << ffd.cFileName << ".\n";
			cout << "Counting lines in directory...\n\n";
			len = linesInDirectoryRecursive(dir);
			if (len != -1)
				sum += len;
			cout << "Done with subdirectory " << ffd.cFileName << ".\n";
			cout << "\tRunning total of lines in " << dir << ": " << sum << ".\n\n";
		}
		else
		{
			len = linesInFile(ffd);
			sum += len;
			cout << "\tFile " << ffd.cFileName << ": " << len << " lines.\n";
			cout << "\t\tRunning total: " << sum << endl << endl;
		}
	} while (FindNextFile(find, &ffd));

	char msg[9001];
	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | 80, NULL, GetLastError(), 0, msg, 9001, NULL);
	cout << "\n\n" << msg;

	cout << "\n\nTotal number of lines in files in the directory " << _getcwd(NULL, NULL) << ": " << sum << ".\n";
	return sum;
}

int linesInFile(WIN32_FIND_DATA ffd)
{
	ifstream in;

	if (ffd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
		return 0;

	in.open(ffd.cFileName, ios::in);
	size_t len(0);
	string line;
	while (in.good())
	{
		getline(in, line);
		++len;
	}
	in.clear();
	in.close();

	return len;
}

void help(const char* prog)
{
	cout << "LineCounter: Counts the number of lines in all files of the chosen directory.\n";
	cout << "Usage: " << prog << " [directory_path] [/r]\n";
	cout << "    directory_path: The path to the directory in which to count lines\n";
	cout << "        If omitted, will print a warning message and count files in the current\n";
	cout << "        working directory.\n";
	cout << "    /r: Recursive mode\n";
	cout << "        By default, LineCounter will only count files directly in the directory\n";
	cout << "        given: That is, it will produce a flat count.\n";
	cout << "        Passing this flag will instruct it to count files in all subdirectories\n";
	cout << "        as well: A recursive count.\n";
}

bool isHelpFlag(const char* arg)
{
	return !strcmp(arg, "/h") || !strcmp(arg, "/help") || !strcmp(arg, "/?") || !strcmp(arg, "-h") || !strcmp(arg, "--help");
}

<|endoftext|>


<commit_before>/*
 * HLLib
 * Copyright (C) 2006-2010 Ryan Gregg

 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later
 * version.
 */

#include "HLLib.h"
#include "NullStream.h"

using namespace HLLib;
using namespace HLLib::Streams;

CNullStream::CNullStream() : bOpened(hlFalse), uiMode(HL_MODE_INVALID)
{

}

CNullStream::~CNullStream()
{

}

HLStreamType CNullStream::GetType() const
{
	return HL_STREAM_NULL;
}

const hlChar *CNullStream::GetFileName() const
{
	return "";
}

hlBool CNullStream::GetOpened() const
{
	return this->bOpened;
}

hlUInt CNullStream::GetMode() const
{
	return this->uiMode;
}

hlBool CNullStream::Open(hlUInt uiMode)
{
	this->bOpened = hlTrue;
	this->uiMode = uiMode;

	return hlTrue;
}

hlVoid CNullStream::Close()
{
	this->bOpened = hlFalse;
	this->uiMode = HL_MODE_INVALID;
}

hlULongLong CNullStream::GetStreamSize() const
{
	return 0;
}

hlULongLong CNullStream::GetStreamPointer() const
{
	return 0;
}

hlULongLong CNullStream::Seek(hlLongLong iOffset, HLSeekMode eSeekMode)
{
	return 0;
}

hlBool CNullStream::Read(hlChar &cChar)
{
	return hlFalse;
}

hlUInt CNullStream::Read(hlVoid *lpData, hlUInt uiBytes)
{
	return 0;
}

hlBool CNullStream::Write(hlChar cChar)
{
	return hlFalse;
}

hlUInt CNullStream::Write(const hlVoid *lpData, hlUInt uiBytes)
{
	return 0;
}
<commit_msg>Delete NullStream.cpp<commit_after><|endoftext|>


<commit_before>//
// Created by Sam on 9/25/2017.
//

#include "../../../include/Game/Core/Mana.h"

bool Mana::operator == (const Mana &other) const
{
    return black == other.black
           && blue == other.blue
           && brown == other.brown
           && green == other.green
           && red == other.red
           && white == other.white;
}

void Mana::payMana(Mana mana)
{
    black -= mana.black;
    blue -= mana.blue;
    brown -= mana.brown;
    green -= mana.green;
    red -= mana.red;
    white -= mana.white;
}

Mana::Mana(int black, int blue, int brown, int green, int red, int white)
        : black(black), blue(blue), brown(brown), green(green), red(red), white(white)
{
}

json Mana::getJSON()
{
    json manaJSON;

    manaJSON["black"] = black;
    manaJSON["blue"] = blue;
    manaJSON["brown"] = brown;
    manaJSON["green"] = green;
    manaJSON["red"] = red;
    manaJSON["white"] = white;

    return manaJSON;
}

bool Mana::canPay(Mana mana)
{
    return (black > mana.black &&
            blue > mana.blue &&
            brown > mana.brown &&
            green > mana.green &&
            red > mana.red &&
            white > mana.white);
}

Mana::~Mana()
= default;
<commit_msg>When checking if a card is playable, check for more than or equal to for available mana<commit_after>//
// Created by Sam on 9/25/2017.
//

#include "../../../include/Game/Core/Mana.h"

bool Mana::operator == (const Mana &other) const
{
    return black == other.black
           && blue == other.blue
           && brown == other.brown
           && green == other.green
           && red == other.red
           && white == other.white;
}

void Mana::payMana(Mana mana)
{
    black -= mana.black;
    blue -= mana.blue;
    brown -= mana.brown;
    green -= mana.green;
    red -= mana.red;
    white -= mana.white;
}

Mana::Mana(int black, int blue, int brown, int green, int red, int white)
        : black(black), blue(blue), brown(brown), green(green), red(red), white(white)
{
}

json Mana::getJSON()
{
    json manaJSON;

    manaJSON["black"] = black;
    manaJSON["blue"] = blue;
    manaJSON["brown"] = brown;
    manaJSON["green"] = green;
    manaJSON["red"] = red;
    manaJSON["white"] = white;

    return manaJSON;
}

bool Mana::canPay(Mana mana)
{
    return (black   >= mana.black &&
            blue    >= mana.blue &&
            brown   >= mana.brown &&
            green   >= mana.green &&
            red     >= mana.red &&
            white   >= mana.white);
}

Mana::~Mana()
= default;
<|endoftext|>


<commit_before>{
  //load libraries
  gROOT->LoadMacro("AliGlauberNucleon.cxx+");
  gROOT->LoadMacro("AliGlauberNucleus.cxx+");
  gROOT->LoadMacro("AliGlauberMC.cxx+");

  Int_t nevents = 10000; // number of events to simulate
  // supported systems are e.g. "p", "d", "Si", "Au", "Pb", "U"
  Option_t *sysA="Pb";
  Option_t *sysB="Pb";
  Double_t signn=72; // inelastic nucleon nucleon cross section
  const char *fname="GlauberMC_PbPb_ntuple.root"; // name output file

  // run the code to produce an ntuple:
  //  AliGlauberMC::runAndSaveNucleons(10000,"Pb","Pb",72);
  Double_t mind=0.4;
  AliGlauberMC::runAndSaveNtuple(nevents,sysA,sysB,signn,mind,fname);

}
<commit_msg>Make it find libraries independently of location<commit_after>{
  //load libraries
  gSystem->SetBuildDir("/tmp");
  gROOT->LoadMacro("$ALICE_ROOT/PWG2/FLOW/AliFlowTools/glauberMC/AliGlauberNucleon.cxx+");
  gROOT->LoadMacro("$ALICE_ROOT/PWG2/FLOW/AliFlowTools/glauberMC/AliGlauberNucleus.cxx+");
  gROOT->LoadMacro("$ALICE_ROOT/PWG2/FLOW/AliFlowTools/glauberMC/AliGlauberMC.cxx+");

  Int_t nevents = 10000; // number of events to simulate
  // supported systems are e.g. "p", "d", "Si", "Au", "Pb", "U"
  Option_t *sysA="Pb";
  Option_t *sysB="Pb";
  Double_t signn=72; // inelastic nucleon nucleon cross section
  const char *fname="GlauberMC_PbPb_ntuple.root"; // name output file

  // run the code to produce an ntuple:
  //  AliGlauberMC::runAndSaveNucleons(10000,"Pb","Pb",72);
  Double_t mind=0.4;
  AliGlauberMC::runAndSaveNtuple(nevents,sysA,sysB,signn,mind,fname);

}
<|endoftext|>


<commit_before><commit_msg>PWGGA/GammaConv: Fixed filling of histo for true mesons as function of jet pt<commit_after><|endoftext|>


<commit_before>AliAnalysisTask *AddTask_sweber_JPsi_pPb_TRDtrigger(){
  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTask_sweber_JPsi_pPb_TRDtrigger", "No analysis manager found.");
    return 0;
  }

  //Do we have an MC handler?
  Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0);

  //Get the current train configuration
  TString trainConfig=gSystem->Getenv("CONFIG_FILE");

  //set config file name
  // TString configFile("$TRAIN_ROOT/mwinn_jpsiCorr/ConfigJpsi2eeData.C");
  TString configFile("$ALICE_ROOT/PWGDQ/dielectron/macrosJPSI/ConfigJpsi_sweber_pPb_TRDtrigger.C");
  //TString configFile("$TRAIN_ROOT/jpsi_JPSI/ConfigJpsiStandard.C");
  // if ( trainConfig.Contains("PbPb") ) configFile="$TRAIN_ROOT/jpsi_JPSI/ConfigJpsi2eePbPb.C";

  //if (mgr->GetInputEventHandler()->IsA()==AliAODInputHandler::Class()){
  //  ::Info("AddTaskJPSI", "Using AOD configuration");
  //  configFile="$TRAIN_ROOT/util/dielectron/dielectron/macros/ConfigJpsi2eeDataAOD.C";
  // }

  TString list=gSystem->Getenv("LIST");
  //create task and add it to the manager
  AliAnalysisTaskMultiDielectronTRDtrigger *task=new AliAnalysisTaskMultiDielectronTRDtrigger("MultiDieDataTRDtrigger");
  if (!hasMC ) task->UsePhysicsSelection();//taking out for testing
  task->SetTriggerMask(AliVEvent::kTRD);
  task->SetTRDtrigger(3);

  //   if (list.Contains("LHC11d")) task->SetTriggerMask(AliVEvent::kEMCEJE+AliVEvent::kEMC7+AliVEvent::kEMCEGA);
  //if (list.Contains("LHC12h")) task->SetTRDtrigger(1+2);
  mgr->AddTask(task);

  //load dielectron configuration file
  gROOT->LoadMacro(configFile.Data());

  //add dielectron analysis with different cuts to the task
  cout << "!!!!!!!!!!!! nDie = " << nDie << endl;
  for (Int_t i=0; i<nDie; ++i){ //nDie defined in config file
    AliDielectron *jpsi=ConfigJpsi_sweber_pPb_TRDtrigger(i);
    if (!jpsi) continue;
    task->AddDielectron(jpsi);
//    printf("add: %s\n",jpsi->GetName());
  }

  //Add event filter
  AliDielectronEventCuts *eventCuts=new AliDielectronEventCuts("eventCuts","Vertex Track && |vtxZ|<10 && ncontrib>0");
  eventCuts->SetRequireVertex();//NOTE: all of these cuts can for some reasons not be applied to self-filtered AODs by mwinn in
  //(list/hera/alice/mwinn/mwinn/train/lists/...)
  eventCuts->SetMinVtxContributors(1);
  eventCuts->SetVertexZ(-10.,10.);
//   eventCuts->SetVertexType(AliDielectronEventCuts::kVtxTracksOrSPD);
//   eventCuts->SetRequireV0and();
//   if ( trainConfig=="PbPb" ){
//     eventCuts->SetCutOnMultipicityITSTPC();
//   }
   task->SetEventFilter(eventCuts);

//   task->SetTriggerOnV0AND();
  if ( trainConfig=="pp" ) task->SetRejectPileup();

  //create output container
  TString containerName = "JPSI.root";
  AliAnalysisDataContainer *coutput1 =
    mgr->CreateContainer("sweber_tree",
                         TTree::Class(),
                         AliAnalysisManager::kExchangeContainer,
                         containerName.Data());

  AliAnalysisDataContainer *cOutputHist1 =
    mgr->CreateContainer("sweber_QA",
                         TList::Class(),
                         AliAnalysisManager::kOutputContainer,
                         containerName.Data());

  AliAnalysisDataContainer *cOutputHist2 =
    mgr->CreateContainer("sweber_CF",
                         TList::Class(),
                         AliAnalysisManager::kOutputContainer,
                         containerName.Data());

  AliAnalysisDataContainer *cOutputHist3 =
    mgr->CreateContainer("sweber_EventStat",
                         TH1D::Class(),
                         AliAnalysisManager::kOutputContainer,
                         containerName.Data());

  mgr->ConnectInput(task,  0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 0, coutput1 );
  mgr->ConnectOutput(task, 1, cOutputHist1);
  mgr->ConnectOutput(task, 2, cOutputHist2);
  mgr->ConnectOutput(task, 3, cOutputHist3);

  return task;
}
<commit_msg>-modifications by michael<commit_after>AliAnalysisTask *AddTask_sweber_JPsi_pPb_TRDtrigger(){
  //get the current analysis manager
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    Error("AddTask_sweber_JPsi_pPb_TRDtrigger", "No analysis manager found.");
    return 0;
  }

  //Do we have an MC handler?
  Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0);

  //Get the current train configuration
  TString trainConfig=gSystem->Getenv("CONFIG_FILE");

  //set config file name
  // TString configFile("$TRAIN_ROOT/mwinn_jpsiCorr/ConfigJpsi2eeData.C");
  TString configFile("$ALICE_ROOT/PWGDQ/dielectron/macrosJPSI/ConfigJpsi_sweber_pPb_TRDtrigger.C");
  //TString configFile("$TRAIN_ROOT/jpsi_JPSI/ConfigJpsiStandard.C");
  // if ( trainConfig.Contains("PbPb") ) configFile="$TRAIN_ROOT/jpsi_JPSI/ConfigJpsi2eePbPb.C";

  //if (mgr->GetInputEventHandler()->IsA()==AliAODInputHandler::Class()){
  //  ::Info("AddTaskJPSI", "Using AOD configuration");
  //  configFile="$TRAIN_ROOT/util/dielectron/dielectron/macros/ConfigJpsi2eeDataAOD.C";
  // }

  TString list=gSystem->Getenv("LIST");
  //create task and add it to the manager
  AliAnalysisTaskMultiDielectron *task=new AliAnalysisTaskMultiDielectron("MultiDieDataTRDtrigger");
  if (!hasMC ) task->UsePhysicsSelection();//taking out for testing
  task->SetTriggerMask(AliVEvent::kTRD);
  //task->SetTRDtrigger(3);
  task->SetFiredTriggerName("CINT7WUHJT-B-NOPF-CENT",kTRUE);//take not kTRUE in order not to get both triggers, exclude (since not yet otherwise possible)
  //
  //not yet implemented to get a logical or of 2 different trigger classes, therefore exclude HJT, not exactly what I want...
  //   if (list.Contains("LHC11d")) task->SetTriggerMask(AliVEvent::kEMCEJE+AliVEvent::kEMC7+AliVEvent::kEMCEGA);
  //if (list.Contains("LHC12h")) task->SetTRDtrigger(1+2);
  mgr->AddTask(task);

  //load dielectron configuration file
  gROOT->LoadMacro(configFile.Data());

  //add dielectron analysis with different cuts to the task
  cout << "!!!!!!!!!!!! nDie = " << nDie << endl;
  for (Int_t i=0; i<nDie; ++i){ //nDie defined in config file
    AliDielectron *jpsi=ConfigJpsi_sweber_pPb_TRDtrigger(i);
    if (!jpsi) continue;
    task->AddDielectron(jpsi);
//    printf("add: %s\n",jpsi->GetName());
  }

  //Add event filter
  AliDielectronEventCuts *eventCuts=new AliDielectronEventCuts("eventCuts","Vertex Track && |vtxZ|<10 && ncontrib>0");
  eventCuts->SetRequireVertex();//NOTE: all of these cuts can for some reasons not be applied to self-filtered AODs by mwinn in
  //(list/hera/alice/mwinn/mwinn/train/lists/...)
  eventCuts->SetMinVtxContributors(1);
  eventCuts->SetVertexZ(-10.,10.);
//   eventCuts->SetVertexType(AliDielectronEventCuts::kVtxTracksOrSPD);
//   eventCuts->SetRequireV0and();
//   if ( trainConfig=="PbPb" ){
//     eventCuts->SetCutOnMultipicityITSTPC();
//   }
   task->SetEventFilter(eventCuts);

//   task->SetTriggerOnV0AND();
  if ( trainConfig=="pp" ) task->SetRejectPileup();

  //create output container
  TString containerName = "JPSI.root";
  AliAnalysisDataContainer *coutput1 =
    mgr->CreateContainer("sweber_tree",
                         TTree::Class(),
                         AliAnalysisManager::kExchangeContainer,
                         containerName.Data());

  AliAnalysisDataContainer *cOutputHist1 =
    mgr->CreateContainer("sweber_QA",
                         TList::Class(),
                         AliAnalysisManager::kOutputContainer,
                         containerName.Data());

  AliAnalysisDataContainer *cOutputHist2 =
    mgr->CreateContainer("sweber_CF",
                         TList::Class(),
                         AliAnalysisManager::kOutputContainer,
                         containerName.Data());

  AliAnalysisDataContainer *cOutputHist3 =
    mgr->CreateContainer("sweber_EventStat",
                         TH1D::Class(),
                         AliAnalysisManager::kOutputContainer,
                         containerName.Data());

  mgr->ConnectInput(task,  0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task, 0, coutput1 );
  mgr->ConnectOutput(task, 1, cOutputHist1);
  mgr->ConnectOutput(task, 2, cOutputHist2);
  mgr->ConnectOutput(task, 3, cOutputHist3);

  return task;
}
<|endoftext|>


<commit_before>///
/// @file  test1.cpp
/// @brief Simple C++ test program for libpopcnt.h.
///        Generates an array with random data and computes the bit
///        population count using 2 different algorithms and checks
///        that the results match.
///
/// Usage: ./test1 [array bytes]
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the LICENSE
/// file in the top level directory.
///

#include <libpopcnt.h>

#include <iostream>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <stdint.h>

void test(std::vector<uint8_t>& data, int i)
{
  int size = data.size();
  double percent = (100.0 * i) / size;
  std::cout << "\rStatus: " << (int) percent << "%" << std::flush;

  uint64_t bits = popcnt(&data[i], size - i);
  uint64_t bits_verify = 0;

  for (int j = i; j < size; j++)
    bits_verify += popcount64(data[j]);

  if (bits != bits_verify)
  {
    std::cerr << std::endl;
    std::cerr << "libpopcnt test failed!" << std::endl;
    std::exit(1);
  }
}

int main(int argc, char* argv[])
{
  int size = 100000;

  if (argc > 1)
    size = std::atoi(argv[1]);

  // init array with only 1 bits
  std::vector<uint8_t> data(size, 0xff);
  srand((unsigned) time(0));

  if (size > 0)
    test(data, 0);

  // generate array with random data
  for (int i = 0; i < size; i++)
    data[i] = (uint8_t) rand();

  for (int i = 1; i < size; i++)
    test(data, i);

  std::cout << "\rStatus: 100%" << std::endl;
  std::cout << "libpopcnt tested successfully!" << std::endl;

  return 0;
}
<commit_msg>Refactor<commit_after>///
/// @file  test1.cpp
/// @brief Simple C++ test program for libpopcnt.h.
///        Generates an array with random data and computes the bit
///        population count using 2 different algorithms and checks
///        that the results match.
///
/// Usage: ./test1 [array bytes]
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the LICENSE
/// file in the top level directory.
///

#include <libpopcnt.h>

#include <iostream>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <stdint.h>

using namespace std;

/// Count 1 bits from &data[i] till &data[size].
/// @data: An array for testing
/// @i: Array start index
///
void test(vector<uint8_t>& data, size_t i)
{
  size_t size = data.size();

  uint64_t bits = popcnt(&data[i], size - i);
  uint64_t bits_verify = 0;

  for (; i < size; i++)
    bits_verify += popcount64(data[i]);

  if (bits != bits_verify)
  {
    cerr << endl;
    cerr << "libpopcnt test failed!" << endl;
    exit(1);
  }
}

int main(int argc, char* argv[])
{
  size_t size = 100000;

  if (argc > 1)
    size = atoi(argv[1]);

  // init array with only 1 bits
  vector<uint8_t> data(size, 0xff);

  if (!data.empty())
    test(data, 0);

  srand((unsigned) time(0));

  // generate array with random data
  for (size_t i = 0; i < size; i++)
    data[i] = (uint8_t) rand();

  for (size_t i = 0; i < size; i++)
  {
    test(data, i);
    double percent = (100.0 * i) / size;
    cout << "\rStatus: " << (int) percent << "%" << flush;
  }

  cout << "\rStatus: 100%" << endl;
  cout << "libpopcnt tested successfully!" << endl;

  return 0;
}
<|endoftext|>


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

#include <ChilliSource/UI/Base/WidgetTemplateProvider.h>

#include <ChilliSource/Core/Base/Application.h>
#include <ChilliSource/Core/Base/Utils.h>
#include <ChilliSource/Core/Resource/ResourcePool.h>
#include <ChilliSource/Core/String/StringParser.h>
#include <ChilliSource/Core/Threading/TaskScheduler.h>
#include <ChilliSource/UI/Base/PropertyMap.h>
#include <ChilliSource/UI/Base/PropertyType.h>
#include <ChilliSource/UI/Base/Widget.h>
#include <ChilliSource/UI/Base/WidgetFactory.h>
#include <ChilliSource/UI/Base/WidgetHierarchyDesc.h>
#include <ChilliSource/UI/Base/WidgetParserUtils.h>
#include <ChilliSource/UI/Base/WidgetTemplate.h>

#include <json/json.h>

namespace ChilliSource
{
    namespace UI
    {
        namespace
        {
            const std::string k_extension("csui");

            //-------------------------------------------------------
            /// Performs the heavy lifting for loading a UI
            /// widget description from file
            ///
            /// @author S Downie
            ///
            /// @param Storage location
            /// @param File path
            /// @param Async load delegate
            /// @param [Out] Resource
            //-------------------------------------------------------
            void LoadDesc(Core::StorageLocation in_storageLocation, const std::string& in_filepath, const Core::ResourceProvider::AsyncLoadDelegate& in_delegate, const Core::ResourceSPtr& out_resource)
            {
                Json::Value root;
                Core::Utils::ReadJson(in_storageLocation, in_filepath, &root);

                WidgetTemplate* widgetTemplate = (WidgetTemplate*)out_resource.get();

                WidgetHierarchyDesc hierarchyDesc;

                std::string definitionFileName;
                std::string pathToDefinition;
                Core::StringUtils::SplitFilename(in_filepath, definitionFileName, pathToDefinition);

                Json::Value hierarchy = root["Hierarchy"];
                Json::Value children = root["Children"];

                WidgetTemplateProvider::ParseTemplate(root, children, hierarchy, in_storageLocation, pathToDefinition, hierarchyDesc);

                widgetTemplate->Build(hierarchyDesc);

                out_resource->SetLoadState(CSCore::Resource::LoadState::k_loaded);
                if(in_delegate != nullptr)
                {
                    CSCore::Application::Get()->GetTaskScheduler()->ScheduleMainThreadTask(std::bind(in_delegate, out_resource));
                }
            }
            //-------------------------------------------------------
            /// Convenience method for setting a property in a prop
            /// map from JSON. This will handle the special cases
            /// of object types layout and drawable
            ///
            /// @author S Downie
            ///
            /// @param Property name
            /// @param JSON to parse and assign into map
            /// @param Location of file for relative pathing
            /// @param Base path of file for relative pathing
            /// @param [Out] Property map to assign to
            //-------------------------------------------------------
            void SetProperty(const std::string& in_propName, const Json::Value& in_json, Core::StorageLocation in_templateLocation, const std::string& in_templatePath, PropertyMap& in_propMap)
            {
                if(in_propName == "Drawable")
                {
                    //Special case for drawable
                    CS_ASSERT(in_json.isObject(), "Value can only be specified as object: " + in_propName);
                    in_propMap.SetProperty(in_propName, WidgetParserUtils::ParseDrawableValues(in_json, in_templateLocation, in_templatePath));
                }
                else if(in_propName == "Layout")
                {
                    //Special case for drawable
                    CS_ASSERT(in_json.isObject(), "Value can only be specified as object: " + in_propName);
                    in_propMap.SetProperty(in_propName, WidgetParserUtils::ParseLayoutValues(in_json));
                }
                else
                {
                    CS_ASSERT(in_json.isString(), "Value can only be specified as string: " + in_propName);
                    in_propMap.SetProperty(in_propMap.GetType(in_propName), in_propName, in_json.asString());
                }
            }
        }

        CS_DEFINE_NAMEDTYPE(WidgetTemplateProvider);
        //-------------------------------------------------------
        //-------------------------------------------------------
        WidgetTemplateProviderUPtr WidgetTemplateProvider::Create()
        {
            return WidgetTemplateProviderUPtr(new WidgetTemplateProvider());
        }
        //-------------------------------------------------------
        //-------------------------------------------------------
        bool WidgetTemplateProvider::IsA(Core::InterfaceIDType in_interfaceId) const
        {
            return (in_interfaceId == Core::ResourceProvider::InterfaceID || in_interfaceId == WidgetTemplateProvider::InterfaceID);
        }
        //-------------------------------------------------------
        //-------------------------------------------------------
        Core::InterfaceIDType WidgetTemplateProvider::GetResourceType() const
        {
            return WidgetTemplate::InterfaceID;
        }
        //-------------------------------------------------------
        //-------------------------------------------------------
        bool WidgetTemplateProvider::CanCreateResourceWithFileExtension(const std::string& in_extension) const
        {
            return (in_extension == k_extension);
        }
        //-------------------------------------------------------
        //-------------------------------------------------------
		void WidgetTemplateProvider::CreateResourceFromFile(Core::StorageLocation in_storageLocation, const std::string& in_filepath, const Core::IResourceOptionsBaseCSPtr& in_options, const Core::ResourceSPtr& out_resource)
        {
            LoadDesc(in_storageLocation, in_filepath, nullptr, out_resource);
        }
        //----------------------------------------------------
        //----------------------------------------------------
		void WidgetTemplateProvider::CreateResourceFromFileAsync(Core::StorageLocation in_storageLocation, const std::string& in_filepath, const Core::IResourceOptionsBaseCSPtr& in_options, const AsyncLoadDelegate& in_delegate, const Core::ResourceSPtr& out_resource)
        {
			auto task = std::bind(LoadDesc, in_storageLocation, in_filepath, in_delegate, out_resource);
            Core::Application::Get()->GetTaskScheduler()->ScheduleTask(task);
        }
        //-------------------------------------------------------
        //-------------------------------------------------------
        void WidgetTemplateProvider::ParseTemplate(const Json::Value& in_template, const Json::Value& in_children, const Json::Value& in_hierarchy, Core::StorageLocation in_templateLocation, const std::string& in_templatePath, WidgetHierarchyDesc& out_hierarchyDesc)
        {
            CS_ASSERT(in_template.isMember("Type") == true, "Widget template must have type");
            std::string type = in_template["Type"].asString();

            if(type == "Template")
            {
                //This type is a special case in which the property values are read from a separate template file
                CS_ASSERT(in_template.isMember("TemplatePath"), "Link to template file must have TemplatePath");

                bool relativePath = in_template.isMember("TemplateLocation") == false;
                Core::StorageLocation location = in_templateLocation;
                std::string path = in_template["TemplatePath"].asString();

                if(relativePath == false)
                {
                    location = Core::ParseStorageLocation(in_template["TemplateLocation"].asString());
                }
                else
                {
                    path = in_templatePath + path;
                }

                auto resPool = Core::Application::Get()->GetResourcePool();
                WidgetTemplateCSPtr widgetTemplate = resPool->LoadResource<WidgetTemplate>(location, path);
                out_hierarchyDesc = widgetTemplate->GetHierarchyDesc();
            }
            else
            {
                auto widgetFactory = Core::Application::Get()->GetWidgetFactory();
                WidgetDefCSPtr widgetDef = widgetFactory->GetDefinition(type);
                out_hierarchyDesc = widgetDef->GetHierarchyDesc();
            }

            for(auto it = in_template.begin(); it != in_template.end(); ++it)
            {
                std::string propertyName = it.memberName();

                if(propertyName == "Type")
                {
                    CS_ASSERT((*it).isString(), "Value can only be specified as string: " + std::string(it.memberName()));
                    if(type != "Template")
                    {
                        out_hierarchyDesc.m_type = (*it).asString();
                    }
                }
                else if(out_hierarchyDesc.m_defaultProperties.HasProperty(it.memberName()) == true)
                {
                    SetProperty(propertyName, *it, in_templateLocation, in_templatePath, out_hierarchyDesc.m_defaultProperties);
                }
                else if(out_hierarchyDesc.m_customProperties.HasProperty(it.memberName()) == true)
                {
                    SetProperty(propertyName, *it, in_templateLocation, in_templatePath, out_hierarchyDesc.m_customProperties);
                }
                else if(propertyName == "TemplateLocation" || propertyName == "TemplatePath" || propertyName == "Children" || propertyName == "Hierarchy")
                {
                    //Ignore these as they are handled elsewhere but we do not want them to be included
                    //in the custom properties list
                }
                else
                {
                    auto itLink = std::find_if(out_hierarchyDesc.m_links.begin(), out_hierarchyDesc.m_links.end(), [propertyName](const WidgetHierarchyDesc::WidgetPropertyLink& in_link)
                    {
                        return in_link.m_linkName == propertyName;
                    });

                    if(itLink != out_hierarchyDesc.m_links.end())
                    {
                        for(auto& child : out_hierarchyDesc.m_children)
                        {
                            if(child.m_defaultProperties.GetProperty<std::string>("Name") == itLink->m_widgetName)
                            {
                                if(child.m_defaultProperties.HasProperty(itLink->m_propertyName) == true)
                                {
                                    SetProperty(itLink->m_propertyName, *it, in_templateLocation, in_templatePath, child.m_defaultProperties);
                                    break;
                                }
                                if(child.m_customProperties.HasProperty(itLink->m_propertyName) == true)
                                {
                                    SetProperty(itLink->m_propertyName, *it, in_templateLocation, in_templatePath, child.m_customProperties);
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        CS_LOG_FATAL("Property with name does not exist: " + std::string(propertyName));
                    }
                }
            }

            out_hierarchyDesc.m_access = WidgetHierarchyDesc::Access::k_external;

            if(!in_hierarchy.isNull())
            {
                if(in_hierarchy.isNull() == false && in_hierarchy.isArray() == true && in_children.isNull() == false)
                {
                    for(u32 i=0; i<in_hierarchy.size(); ++i)
                    {
                        const Json::Value& hierarchyItem = in_hierarchy[i];
                        std::string name = hierarchyItem["Name"].asString();

                        const Json::Value& hierarchyChildren = hierarchyItem["Children"];
                        const Json::Value& widget = in_children[name];

                        WidgetHierarchyDesc childDesc;
                        ParseTemplate(widget, in_children, hierarchyChildren, in_templateLocation, in_templatePath, childDesc);
                        out_hierarchyDesc.m_children.push_back(childDesc);
                    }
                }
            }
        }
    }
}
<commit_msg>Changing how template references are handled for UI to mimic the UI tool. Templates are no longer directly inserted as a child widget but are added to a root widget as an internal child and this root widget is inserted as a child. This allows the template to be treated as a black box by adding children and not letting them be affected by the layout etc. This does mean that the template link now has to have associated size and position props as these are no longer taken from the template<commit_after>//
//  WidgetTemplateProvider.cpp
//  Chilli Source
//  Created by Scott Downie on 30/07/2014.
//
//  The MIT License (MIT)
//
//  Copyright (c) 2014 Tag Games Limited
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

#include <ChilliSource/UI/Base/WidgetTemplateProvider.h>

#include <ChilliSource/Core/Base/Application.h>
#include <ChilliSource/Core/Base/Utils.h>
#include <ChilliSource/Core/Resource/ResourcePool.h>
#include <ChilliSource/Core/String/StringParser.h>
#include <ChilliSource/Core/Threading/TaskScheduler.h>
#include <ChilliSource/UI/Base/PropertyMap.h>
#include <ChilliSource/UI/Base/PropertyType.h>
#include <ChilliSource/UI/Base/Widget.h>
#include <ChilliSource/UI/Base/WidgetFactory.h>
#include <ChilliSource/UI/Base/WidgetHierarchyDesc.h>
#include <ChilliSource/UI/Base/WidgetParserUtils.h>
#include <ChilliSource/UI/Base/WidgetTemplate.h>

#include <json/json.h>

namespace ChilliSource
{
    namespace UI
    {
        namespace
        {
            const std::string k_extension("csui");

            //-------------------------------------------------------
            /// Performs the heavy lifting for loading a UI
            /// widget description from file
            ///
            /// @author S Downie
            ///
            /// @param Storage location
            /// @param File path
            /// @param Async load delegate
            /// @param [Out] Resource
            //-------------------------------------------------------
            void LoadDesc(Core::StorageLocation in_storageLocation, const std::string& in_filepath, const Core::ResourceProvider::AsyncLoadDelegate& in_delegate, const Core::ResourceSPtr& out_resource)
            {
                Json::Value root;
                Core::Utils::ReadJson(in_storageLocation, in_filepath, &root);

                WidgetTemplate* widgetTemplate = (WidgetTemplate*)out_resource.get();

                WidgetHierarchyDesc hierarchyDesc;

                std::string definitionFileName;
                std::string pathToDefinition;
                Core::StringUtils::SplitFilename(in_filepath, definitionFileName, pathToDefinition);

                Json::Value hierarchy = root["Hierarchy"];
                Json::Value children = root["Children"];

                WidgetTemplateProvider::ParseTemplate(root, children, hierarchy, in_storageLocation, pathToDefinition, hierarchyDesc);

                widgetTemplate->Build(hierarchyDesc);

                out_resource->SetLoadState(CSCore::Resource::LoadState::k_loaded);
                if(in_delegate != nullptr)
                {
                    CSCore::Application::Get()->GetTaskScheduler()->ScheduleMainThreadTask(std::bind(in_delegate, out_resource));
                }
            }
            //-------------------------------------------------------
            /// Convenience method for setting a property in a prop
            /// map from JSON. This will handle the special cases
            /// of object types layout and drawable
            ///
            /// @author S Downie
            ///
            /// @param Property name
            /// @param JSON to parse and assign into map
            /// @param Location of file for relative pathing
            /// @param Base path of file for relative pathing
            /// @param [Out] Property map to assign to
            //-------------------------------------------------------
            void SetProperty(const std::string& in_propName, const Json::Value& in_json, Core::StorageLocation in_templateLocation, const std::string& in_templatePath, PropertyMap& in_propMap)
            {
                if(in_propName == "Drawable")
                {
                    //Special case for drawable
                    CS_ASSERT(in_json.isObject(), "Value can only be specified as object: " + in_propName);
                    in_propMap.SetProperty(in_propName, WidgetParserUtils::ParseDrawableValues(in_json, in_templateLocation, in_templatePath));
                }
                else if(in_propName == "Layout")
                {
                    //Special case for drawable
                    CS_ASSERT(in_json.isObject(), "Value can only be specified as object: " + in_propName);
                    in_propMap.SetProperty(in_propName, WidgetParserUtils::ParseLayoutValues(in_json));
                }
                else
                {
                    CS_ASSERT(in_json.isString(), "Value can only be specified as string: " + in_propName);
                    in_propMap.SetProperty(in_propMap.GetType(in_propName), in_propName, in_json.asString());
                }
            }
        }

        CS_DEFINE_NAMEDTYPE(WidgetTemplateProvider);
        //-------------------------------------------------------
        //-------------------------------------------------------
        WidgetTemplateProviderUPtr WidgetTemplateProvider::Create()
        {
            return WidgetTemplateProviderUPtr(new WidgetTemplateProvider());
        }
        //-------------------------------------------------------
        //-------------------------------------------------------
        bool WidgetTemplateProvider::IsA(Core::InterfaceIDType in_interfaceId) const
        {
            return (in_interfaceId == Core::ResourceProvider::InterfaceID || in_interfaceId == WidgetTemplateProvider::InterfaceID);
        }
        //-------------------------------------------------------
        //-------------------------------------------------------
        Core::InterfaceIDType WidgetTemplateProvider::GetResourceType() const
        {
            return WidgetTemplate::InterfaceID;
        }
        //-------------------------------------------------------
        //-------------------------------------------------------
        bool WidgetTemplateProvider::CanCreateResourceWithFileExtension(const std::string& in_extension) const
        {
            return (in_extension == k_extension);
        }
        //-------------------------------------------------------
        //-------------------------------------------------------
		void WidgetTemplateProvider::CreateResourceFromFile(Core::StorageLocation in_storageLocation, const std::string& in_filepath, const Core::IResourceOptionsBaseCSPtr& in_options, const Core::ResourceSPtr& out_resource)
        {
            LoadDesc(in_storageLocation, in_filepath, nullptr, out_resource);
        }
        //----------------------------------------------------
        //----------------------------------------------------
		void WidgetTemplateProvider::CreateResourceFromFileAsync(Core::StorageLocation in_storageLocation, const std::string& in_filepath, const Core::IResourceOptionsBaseCSPtr& in_options, const AsyncLoadDelegate& in_delegate, const Core::ResourceSPtr& out_resource)
        {
			auto task = std::bind(LoadDesc, in_storageLocation, in_filepath, in_delegate, out_resource);
            Core::Application::Get()->GetTaskScheduler()->ScheduleTask(task);
        }
        //-------------------------------------------------------
        //-------------------------------------------------------
        void WidgetTemplateProvider::ParseTemplate(const Json::Value& in_template, const Json::Value& in_children, const Json::Value& in_hierarchy, Core::StorageLocation in_templateLocation, const std::string& in_templatePath, WidgetHierarchyDesc& out_hierarchyDesc)
        {
            CS_ASSERT(in_template.isMember("Type") == true, "Widget template must have type");
            std::string type = in_template["Type"].asString();

            if(type == "Template")
            {
                //This type is a special case in which the property values are read from a separate template file
                CS_ASSERT(in_template.isMember("TemplatePath"), "Link to template file must have TemplatePath");

                bool relativePath = in_template.isMember("TemplateLocation") == false;
                Core::StorageLocation location = in_templateLocation;
                std::string path = in_template["TemplatePath"].asString();

                if(relativePath == false)
                {
                    location = Core::ParseStorageLocation(in_template["TemplateLocation"].asString());
                }
                else
                {
                    path = in_templatePath + path;
                }

                //Template widgets need to be created as a hierarchy so that we can set properties such as layout
                //on the widget without affecting the contents of the template and vice-versa.
                auto widgetFactory = Core::Application::Get()->GetWidgetFactory();
                WidgetDefCSPtr widgetDef = widgetFactory->GetDefinition("Widget");
                out_hierarchyDesc = widgetDef->GetHierarchyDesc();

                auto resPool = Core::Application::Get()->GetResourcePool();
                WidgetTemplateCSPtr widgetTemplate = resPool->LoadResource<WidgetTemplate>(location, path);
                out_hierarchyDesc.m_children.push_back(widgetTemplate->GetHierarchyDesc());
                out_hierarchyDesc.m_children.back().m_access = WidgetHierarchyDesc::Access::k_internal;
            }
            else
            {
                auto widgetFactory = Core::Application::Get()->GetWidgetFactory();
                WidgetDefCSPtr widgetDef = widgetFactory->GetDefinition(type);
                out_hierarchyDesc = widgetDef->GetHierarchyDesc();
            }

            for(auto it = in_template.begin(); it != in_template.end(); ++it)
            {
                std::string propertyName = it.memberName();

                if(propertyName == "Type")
                {
                    CS_ASSERT((*it).isString(), "Value can only be specified as string: " + std::string(it.memberName()));
                    if(type != "Template")
                    {
                        out_hierarchyDesc.m_type = (*it).asString();
                    }
                }
                else if(out_hierarchyDesc.m_defaultProperties.HasProperty(it.memberName()) == true)
                {
                    SetProperty(propertyName, *it, in_templateLocation, in_templatePath, out_hierarchyDesc.m_defaultProperties);
                }
                else if(out_hierarchyDesc.m_customProperties.HasProperty(it.memberName()) == true)
                {
                    SetProperty(propertyName, *it, in_templateLocation, in_templatePath, out_hierarchyDesc.m_customProperties);
                }
                else if(propertyName == "TemplateLocation" || propertyName == "TemplatePath" || propertyName == "Children" || propertyName == "Hierarchy")
                {
                    //Ignore these as they are handled elsewhere but we do not want them to be included
                    //in the custom properties list
                }
                else
                {
                    auto itLink = std::find_if(out_hierarchyDesc.m_links.begin(), out_hierarchyDesc.m_links.end(), [propertyName](const WidgetHierarchyDesc::WidgetPropertyLink& in_link)
                    {
                        return in_link.m_linkName == propertyName;
                    });

                    if(itLink != out_hierarchyDesc.m_links.end())
                    {
                        for(auto& child : out_hierarchyDesc.m_children)
                        {
                            if(child.m_defaultProperties.GetProperty<std::string>("Name") == itLink->m_widgetName)
                            {
                                if(child.m_defaultProperties.HasProperty(itLink->m_propertyName) == true)
                                {
                                    SetProperty(itLink->m_propertyName, *it, in_templateLocation, in_templatePath, child.m_defaultProperties);
                                    break;
                                }
                                if(child.m_customProperties.HasProperty(itLink->m_propertyName) == true)
                                {
                                    SetProperty(itLink->m_propertyName, *it, in_templateLocation, in_templatePath, child.m_customProperties);
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        CS_LOG_FATAL("Property with name does not exist: " + std::string(propertyName));
                    }
                }
            }

            out_hierarchyDesc.m_access = WidgetHierarchyDesc::Access::k_external;

            if(!in_hierarchy.isNull())
            {
                if(in_hierarchy.isNull() == false && in_hierarchy.isArray() == true && in_children.isNull() == false)
                {
                    for(u32 i=0; i<in_hierarchy.size(); ++i)
                    {
                        const Json::Value& hierarchyItem = in_hierarchy[i];
                        std::string name = hierarchyItem["Name"].asString();

                        const Json::Value& hierarchyChildren = hierarchyItem["Children"];
                        const Json::Value& widget = in_children[name];

                        WidgetHierarchyDesc childDesc;
                        ParseTemplate(widget, in_children, hierarchyChildren, in_templateLocation, in_templatePath, childDesc);
                        out_hierarchyDesc.m_children.push_back(childDesc);
                    }
                }
            }
        }
    }
}
<|endoftext|>