<commit_before>/*******************************************************************/
/*                               XDMF                              */
/*                   eXtensible Data Model and Format */
/*                                                                 */
/*  Id : Id  */
/*  Date : $Date$ */
/*  Version : $Revision$ */
/*                                                                 */
/*  Author:                                                        */
/*     Jerry A. Clarke                                             */
/*     clarke@arl.army.mil                                         */
/*     US Army Research Laboratory                                 */
/*     Aberdeen Proving Ground, MD                                 */
/*                                                                 */
/*     Copyright @ 2002 US Army Research Laboratory                */
/*     All Rights Reserved                                         */
/*     See Copyright.txt or http://www.arl.hpc.mil/ice 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 "XdmfObject.h"
#include "XdmfValuesHDF.h"
#include "XdmfHDF.h"
#include "XdmfDataStructure.h"
#include "XdmfArray.h"

XdmfValuesHDF::XdmfValuesHDF() {
    this->SetFormat(XDMF_FORMAT_HDF);
}

XdmfValuesHDF::~XdmfValuesHDF() {
}

XdmfArray *
XdmfValuesHDF::Read(XdmfArray *Array){
    XdmfArray   *RetArray = Array;
    XdmfString  DataSetName = 0;
    XdmfHDF     H5;

    if(!this->DataDesc){
        XdmfErrorMessage("DataDesc has not been set");
        return(NULL);
    }
    H5.SetWorkingDirectory(this->GetWorkingDirectory());
    XDMF_STRING_DUPLICATE(DataSetName, this->Get("CDATA"));
    if(!DataSetName || strlen(DataSetName) < 1){
        XdmfErrorMessage("Invalid HDF5 Dataset Name");
        return(NULL);
    }
    XDMF_WORD_TRIM(DataSetName);
    XdmfDebug("Opening HDF5 Data for Reading : " << DataSetName);
    // Allocate Array if Necessary
    if(!RetArray){
        RetArray = new XdmfArray();
        if(!RetArray){
            XdmfErrorMessage("Error Allocating New Array");
            return(NULL);
        }
        RetArray->CopyType(this->DataDesc);
        RetArray->CopyShape(this->DataDesc);
        RetArray->CopySelection(this->DataDesc);
        RetArray->Allocate();
    }
    if( H5.Open( DataSetName, "r" ) == XDMF_FAIL ) {
        XdmfErrorMessage("Can't Open Dataset " << DataSetName);
        if(!Array) delete RetArray;
        RetArray = NULL;
    }else{
        if(this->DataDesc->GetSelectionSize() != H5.GetNumberOfElements() ){
          // We're not reading the entire dataset
            if( this->DataDesc->GetSelectionType() == XDMF_HYPERSLAB ){
                XdmfInt32  Rank;
                XdmfInt64  Start[ XDMF_MAX_DIMENSION ];
                XdmfInt64  Stride[ XDMF_MAX_DIMENSION ];
                XdmfInt64  Count[ XDMF_MAX_DIMENSION ];

                // Select the HyperSlab from HDF5
                Rank = this->DataDesc->GetHyperSlab( Start, Stride, Count );
                H5.SelectHyperSlab( Start, Stride, Count );
                RetArray->SetShape(Rank, Count);
                RetArray->SelectAll();
            } else {
                XdmfInt64  NumberOfCoordinates;
                XdmfInt64  *Coordinates;

                // Select Parametric Coordinates from HDF5
                NumberOfCoordinates = this->DataDesc->GetSelectionSize();
                Coordinates = this->DataDesc->GetCoordinates();
                RetArray->SetNumberOfElements(NumberOfCoordinates);
                H5.SelectCoordinates(NumberOfCoordinates, Coordinates);
                delete Coordinates;
                }
            }

        if( H5.Read(RetArray) == NULL ){
            XdmfErrorMessage("Can't Read Dataset " << DataSetName);
            if(!Array) delete RetArray;
            RetArray = NULL;
        }else{
            this->SetHeavyDataSetName(DataSetName);
        }
    H5.Close();
    }
    delete [] DataSetName;
    return(RetArray);
}

XdmfInt32
XdmfValuesHDF::Write(XdmfArray *Array, XdmfConstString HeavyDataSetName){
    char* hds;
    XdmfHDF H5;

    if(!HeavyDataSetName) HeavyDataSetName = this->GetHeavyDataSetName();
    if(!HeavyDataSetName){
        HeavyDataSetName = "Xdmf.h5:/Data";
    }
    XdmfDebug("Writing Values to " << HeavyDataSetName);
    if(!this->DataDesc ){
        XdmfErrorMessage("DataDesc has not been set");
        return(XDMF_FAIL);
    }
    if(!Array){
        XdmfErrorMessage("Array to Write is NULL");
        return(XDMF_FAIL);
    }
    XDMF_STRING_DUPLICATE(hds, HeavyDataSetName);
    XDMF_WORD_TRIM( hds );
    this->Set("CDATA", hds);
    H5.CopyType(this->DataDesc);
    H5.CopyShape(this->DataDesc);
    H5.CopySelection(this->DataDesc);
    if(H5.Open(hds, "rw") == XDMF_FAIL){
        XdmfErrorMessage("Error Opening " << hds << " for Writing");
        delete [] hds ;
        return(XDMF_FAIL);
    }
    if(H5.Write(Array) == XDMF_FAIL){
        XdmfErrorMessage("Error Writing " << hds );
        H5.Close();
        delete [] hds;
        return(XDMF_FAIL);
    }
    H5.Close();
    delete [] hds;
    return(XDMF_SUCCESS);
}
<commit_msg>Get Working Directory from DOM not Element<commit_after>/*******************************************************************/
/*                               XDMF                              */
/*                   eXtensible Data Model and Format */
/*                                                                 */
/*  Id : Id  */
/*  Date : $Date$ */
/*  Version : $Revision$ */
/*                                                                 */
/*  Author:                                                        */
/*     Jerry A. Clarke                                             */
/*     clarke@arl.army.mil                                         */
/*     US Army Research Laboratory                                 */
/*     Aberdeen Proving Ground, MD                                 */
/*                                                                 */
/*     Copyright @ 2002 US Army Research Laboratory                */
/*     All Rights Reserved                                         */
/*     See Copyright.txt or http://www.arl.hpc.mil/ice 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 "XdmfObject.h"
#include "XdmfValuesHDF.h"
#include "XdmfHDF.h"
#include "XdmfDOM.h"
#include "XdmfDataStructure.h"
#include "XdmfArray.h"

XdmfValuesHDF::XdmfValuesHDF() {
    this->SetFormat(XDMF_FORMAT_HDF);
}

XdmfValuesHDF::~XdmfValuesHDF() {
}

XdmfArray *
XdmfValuesHDF::Read(XdmfArray *Array){
    XdmfArray   *RetArray = Array;
    XdmfString  DataSetName = 0;
    XdmfHDF     H5;

    if(!this->DataDesc){
        XdmfErrorMessage("DataDesc has not been set");
        return(NULL);
    }
    H5.SetWorkingDirectory(this->DOM->GetWorkingDirectory());
    XDMF_STRING_DUPLICATE(DataSetName, this->Get("CDATA"));
    if(!DataSetName || strlen(DataSetName) < 1){
        XdmfErrorMessage("Invalid HDF5 Dataset Name");
        return(NULL);
    }
    XDMF_WORD_TRIM(DataSetName);
    XdmfDebug("Opening HDF5 Data for Reading : " << DataSetName);
    // Allocate Array if Necessary
    if(!RetArray){
        RetArray = new XdmfArray();
        if(!RetArray){
            XdmfErrorMessage("Error Allocating New Array");
            return(NULL);
        }
        RetArray->CopyType(this->DataDesc);
        RetArray->CopyShape(this->DataDesc);
        RetArray->CopySelection(this->DataDesc);
        RetArray->Allocate();
    }
    if( H5.Open( DataSetName, "r" ) == XDMF_FAIL ) {
        XdmfErrorMessage("Can't Open Dataset " << DataSetName);
        if(!Array) delete RetArray;
        RetArray = NULL;
    }else{
        if(this->DataDesc->GetSelectionSize() != H5.GetNumberOfElements() ){
          // We're not reading the entire dataset
            if( this->DataDesc->GetSelectionType() == XDMF_HYPERSLAB ){
                XdmfInt32  Rank;
                XdmfInt64  Start[ XDMF_MAX_DIMENSION ];
                XdmfInt64  Stride[ XDMF_MAX_DIMENSION ];
                XdmfInt64  Count[ XDMF_MAX_DIMENSION ];

                // Select the HyperSlab from HDF5
                Rank = this->DataDesc->GetHyperSlab( Start, Stride, Count );
                H5.SelectHyperSlab( Start, Stride, Count );
                RetArray->SetShape(Rank, Count);
                RetArray->SelectAll();
            } else {
                XdmfInt64  NumberOfCoordinates;
                XdmfInt64  *Coordinates;

                // Select Parametric Coordinates from HDF5
                NumberOfCoordinates = this->DataDesc->GetSelectionSize();
                Coordinates = this->DataDesc->GetCoordinates();
                RetArray->SetNumberOfElements(NumberOfCoordinates);
                H5.SelectCoordinates(NumberOfCoordinates, Coordinates);
                delete Coordinates;
                }
            }

        if( H5.Read(RetArray) == NULL ){
            XdmfErrorMessage("Can't Read Dataset " << DataSetName);
            if(!Array) delete RetArray;
            RetArray = NULL;
        }else{
            this->SetHeavyDataSetName(DataSetName);
        }
    H5.Close();
    }
    delete [] DataSetName;
    return(RetArray);
}

XdmfInt32
XdmfValuesHDF::Write(XdmfArray *Array, XdmfConstString HeavyDataSetName){
    char* hds;
    XdmfHDF H5;

    if(!HeavyDataSetName) HeavyDataSetName = this->GetHeavyDataSetName();
    if(!HeavyDataSetName){
        HeavyDataSetName = "Xdmf.h5:/Data";
    }
    XdmfDebug("Writing Values to " << HeavyDataSetName);
    if(!this->DataDesc ){
        XdmfErrorMessage("DataDesc has not been set");
        return(XDMF_FAIL);
    }
    if(!Array){
        XdmfErrorMessage("Array to Write is NULL");
        return(XDMF_FAIL);
    }
    XDMF_STRING_DUPLICATE(hds, HeavyDataSetName);
    XDMF_WORD_TRIM( hds );
    this->Set("CDATA", hds);
    H5.CopyType(this->DataDesc);
    H5.CopyShape(this->DataDesc);
    H5.CopySelection(this->DataDesc);
    if(H5.Open(hds, "rw") == XDMF_FAIL){
        XdmfErrorMessage("Error Opening " << hds << " for Writing");
        delete [] hds ;
        return(XDMF_FAIL);
    }
    if(H5.Write(Array) == XDMF_FAIL){
        XdmfErrorMessage("Error Writing " << hds );
        H5.Close();
        delete [] hds;
        return(XDMF_FAIL);
    }
    H5.Close();
    delete [] hds;
    return(XDMF_SUCCESS);
}
<|endoftext|>


<commit_before>#include "LowestCommonAncestorOfABinarySearchTree.hpp"

TreeNode* LowestCommonAncestorOfABinarySearchTree::lowestCommonAncestor(
  TreeNode* root, TreeNode* p, TreeNode* q)
{
  if (root == nullptr || p == nullptr || q == nullptr)
    return nullptr;

  if (p->val > q->val)
    return lowestCommonAncestor(root, q, p);

  if (p->val == q->val)
    return p;

  if (root->val == p->val)
    return p;

  if (root->val == q->val)
    return q;

  if (p->val < root->val && root->val < q->val)
    return root;

  if (q->val < root->val)
    return lowestCommonAncestor(root->left, p, q);
  else
    return lowestCommonAncestor(root->right, p, q);
}
<commit_msg>Refine Problem 235. Lowest Common Ancestor of a Binary Search Tree<commit_after>#include "LowestCommonAncestorOfABinarySearchTree.hpp"

TreeNode* LowestCommonAncestorOfABinarySearchTree::lowestCommonAncestor(
  TreeNode* root, TreeNode* p, TreeNode* q)
{
  if (root == nullptr || p == nullptr || q == nullptr)
    return nullptr;

  if (root->val > p->val && root->val > q->val)
    return lowestCommonAncestor(root->left, p, q);

  if (root->val < p->val && root->val < q->val)
    return lowestCommonAncestor(root->right, p, q);

  return root;
}
<|endoftext|>


<commit_before>// Copyright © 2015 Mikko Ronkainen <firstname@mikkoronkainen.com>
// License: MIT, see the LICENSE file.

#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#endif

#include <GL/gl3w.h>
#include <GLFW/glfw3.h>
#include <tinyformat/tinyformat.h>

#include "Runners/WindowRunnerStates/DefaultState.h"
#include "App.h"
#include "Utils/Log.h"
#include "OpenCL/CLRaytracer.h"
#include "Math/Color.h"
#include "Math/EulerAngle.h"
#include "Math/Vector3.h"
#include "Raytracing/Camera.h"
#include "Raytracing/Raytracer.h"
#include "Rendering/Framebuffer.h"
#include "Rendering/Text.h"
#include "Runners/WindowRunner.h"
#include "Utils/Settings.h"

using namespace Raycer;

void DefaultState::initialize()
{
	Settings& settings = App::getSettings();
	Framebuffer& framebuffer = App::getFramebuffer();
	CLRaytracer& clRaytracer = App::getCLRaytracer();

	if (settings.scene.enableTestScenes)
		scene = Scene::createTestScene(settings.scene.testSceneNumber);
	else
		scene = Scene::loadFromFile(settings.scene.fileName);

	scene.initialize();
	scene.camera.setImagePlaneSize(framebuffer.getWidth(), framebuffer.getHeight());

	if (settings.openCL.enabled)
		clRaytracer.initialize();

	currentTestSceneNumber = settings.scene.testSceneNumber;
}

void DefaultState::pause()
{
}

void DefaultState::resume()
{
}

void DefaultState::shutdown()
{
}

void DefaultState::update(double timeStep)
{
	WindowRunner& windowRunner = App::getWindowRunner();
	Framebuffer& framebuffer = App::getFramebuffer();

	bool increaseTestSceneNumber = windowRunner.keyWasPressed(GLFW_KEY_F2);
	bool decreaseTestSceneNumber = windowRunner.keyWasPressed(GLFW_KEY_F3);

	if (increaseTestSceneNumber || decreaseTestSceneNumber)
	{
		if (increaseTestSceneNumber)
			currentTestSceneNumber++;

		if (decreaseTestSceneNumber)
			currentTestSceneNumber--;

		if (currentTestSceneNumber < 1)
			currentTestSceneNumber = 1;

		if (currentTestSceneNumber > Scene::TEST_SCENE_COUNT)
			currentTestSceneNumber = Scene::TEST_SCENE_COUNT;

		scene = Scene::createTestScene(currentTestSceneNumber);
		scene.initialize();
		scene.camera.setImagePlaneSize(framebuffer.getWidth(), framebuffer.getHeight());
	}

	if (windowRunner.keyWasPressed(GLFW_KEY_F6))
		scene.raytracer.visualizeDepth = !scene.raytracer.visualizeDepth;

	if (windowRunner.keyWasPressed(GLFW_KEY_F7))
		scene.saveToFile("scene.xml");

	if (windowRunner.keyWasPressed(GLFW_KEY_F8))
	{
		windowRunner.pause();
		scene.saveToFile("scene.xml");

#ifdef _WIN32
		ShellExecuteA(NULL, "open", "raycer.exe", "-s scene.xml --non-interactive --non-test --view", NULL, SW_SHOWNORMAL);
#else
		int pid = fork();

		if (pid == 0)
		{
			char* arg[] = { (char*)"raycer", (char*)"-s scene.xml", (char*)"--non-interactive", (char*)"--non-test", (char*)"--view", (char*)0 };

			if (execvp(arg[0], arg) == -1)
				App::getLog().logWarning("Could not launch external rendering (%d) (try adding raycer to PATH)", errno);
		}
#endif
	}

	scene.camera.update(scene, timeStep);
}

void DefaultState::render(double timeStep, double interpolation)
{
	(void)timeStep;
	(void)interpolation;

	Framebuffer& framebuffer = App::getFramebuffer();
	Settings& settings = App::getSettings();
	Raytracer& raytracer = App::getRaytracer();
	CLRaytracer& clRaytracer = App::getCLRaytracer();
	WindowRunner& runner = App::getWindowRunner();
	Text& text = runner.getDefaultText();

	state.image = &framebuffer.getImage();
	state.scene = &scene;
	state.sceneWidth = framebuffer.getWidth();
	state.sceneHeight = framebuffer.getHeight();
	state.pixelOffset = 0;
	state.pixelCount = state.sceneWidth * state.sceneHeight;
	state.pixelsProcessed = 0;

	if (!settings.openCL.enabled)
		raytracer.run(state, interrupted);
	else
		clRaytracer.run(state, interrupted);

	if (settings.window.showInfoText)
	{
		text.drawText(5.0, (double)(runner.getWindowHeight() - 3 * settings.window.defaultFontSize), Color(255, 255, 255, 255), tfm::format("Pos: (%.2f, %.2f, %.2f)", scene.camera.position.x, scene.camera.position.y, scene.camera.position.z));
		text.drawText(5.0, (double)(runner.getWindowHeight() - 4 * settings.window.defaultFontSize - 2), Color(255, 255, 255, 255), tfm::format("Rot: (%.2f, %.2f, %.2f)", scene.camera.orientation.pitch, scene.camera.orientation.yaw, scene.camera.orientation.roll));
		text.drawText(5.0, (double)(runner.getWindowHeight() - 5 * settings.window.defaultFontSize - 4), Color(255, 255, 255, 255), tfm::format("Pix: (%d, %d)", runner.getMouseInfo().framebufferX, runner.getMouseInfo().framebufferY));
		text.drawText(5.0, (double)(runner.getWindowHeight() - 6 * settings.window.defaultFontSize - 6), Color(255, 255, 255, 255), tfm::format("Mov: %s", scene.camera.hasMoved()));
	}
}

void DefaultState::windowResized(int width, int height)
{
	(void)width;
	(void)height;
}

void DefaultState::framebufferResized(int width, int height)
{
	scene.camera.setImagePlaneSize(width, height);
}
<commit_msg>Added error checking to test scene loading<commit_after>// Copyright © 2015 Mikko Ronkainen <firstname@mikkoronkainen.com>
// License: MIT, see the LICENSE file.

#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#endif

#include <GL/gl3w.h>
#include <GLFW/glfw3.h>
#include <tinyformat/tinyformat.h>

#include "Runners/WindowRunnerStates/DefaultState.h"
#include "App.h"
#include "Utils/Log.h"
#include "OpenCL/CLRaytracer.h"
#include "Math/Color.h"
#include "Math/EulerAngle.h"
#include "Math/Vector3.h"
#include "Raytracing/Camera.h"
#include "Raytracing/Raytracer.h"
#include "Rendering/Framebuffer.h"
#include "Rendering/Text.h"
#include "Runners/WindowRunner.h"
#include "Utils/Settings.h"

using namespace Raycer;

void DefaultState::initialize()
{
	Settings& settings = App::getSettings();
	Framebuffer& framebuffer = App::getFramebuffer();
	CLRaytracer& clRaytracer = App::getCLRaytracer();

	if (settings.scene.enableTestScenes)
		scene = Scene::createTestScene(settings.scene.testSceneNumber);
	else
		scene = Scene::loadFromFile(settings.scene.fileName);

	scene.initialize();
	scene.camera.setImagePlaneSize(framebuffer.getWidth(), framebuffer.getHeight());

	if (settings.openCL.enabled)
		clRaytracer.initialize();

	currentTestSceneNumber = settings.scene.testSceneNumber;
}

void DefaultState::pause()
{
}

void DefaultState::resume()
{
}

void DefaultState::shutdown()
{
}

void DefaultState::update(double timeStep)
{
	Log& log = App::getLog();
	WindowRunner& windowRunner = App::getWindowRunner();
	Framebuffer& framebuffer = App::getFramebuffer();

	bool increaseTestSceneNumber = windowRunner.keyWasPressed(GLFW_KEY_F2);
	bool decreaseTestSceneNumber = windowRunner.keyWasPressed(GLFW_KEY_F3);

	if (increaseTestSceneNumber || decreaseTestSceneNumber)
	{
		if (increaseTestSceneNumber)
			currentTestSceneNumber++;

		if (decreaseTestSceneNumber)
			currentTestSceneNumber--;

		if (currentTestSceneNumber < 1)
			currentTestSceneNumber = 1;

		if (currentTestSceneNumber > Scene::TEST_SCENE_COUNT)
			currentTestSceneNumber = Scene::TEST_SCENE_COUNT;

		try
		{
			scene = Scene::createTestScene(currentTestSceneNumber);
			scene.initialize();
		}
		catch (const std::exception& ex)
		{
			log.logWarning("Could not create test scene: %s", ex.what());
			scene = Scene();
			scene.initialize();
		}

		scene.camera.setImagePlaneSize(framebuffer.getWidth(), framebuffer.getHeight());
	}

	if (windowRunner.keyWasPressed(GLFW_KEY_F6))
		scene.raytracer.visualizeDepth = !scene.raytracer.visualizeDepth;

	if (windowRunner.keyWasPressed(GLFW_KEY_F7))
		scene.saveToFile("scene.xml");

	if (windowRunner.keyWasPressed(GLFW_KEY_F8))
	{
		windowRunner.pause();
		scene.saveToFile("scene.xml");

#ifdef _WIN32
		ShellExecuteA(NULL, "open", "raycer.exe", "-s scene.xml --non-interactive --non-test --view", NULL, SW_SHOWNORMAL);
#else
		int pid = fork();

		if (pid == 0)
		{
			char* arg[] = { (char*)"raycer", (char*)"-s scene.xml", (char*)"--non-interactive", (char*)"--non-test", (char*)"--view", (char*)0 };

			if (execvp(arg[0], arg) == -1)
				App::getLog().logWarning("Could not launch external rendering (%d) (try adding raycer to PATH)", errno);
		}
#endif
	}

	scene.camera.update(scene, timeStep);
}

void DefaultState::render(double timeStep, double interpolation)
{
	(void)timeStep;
	(void)interpolation;

	Framebuffer& framebuffer = App::getFramebuffer();
	Settings& settings = App::getSettings();
	Raytracer& raytracer = App::getRaytracer();
	CLRaytracer& clRaytracer = App::getCLRaytracer();
	WindowRunner& runner = App::getWindowRunner();
	Text& text = runner.getDefaultText();

	state.image = &framebuffer.getImage();
	state.scene = &scene;
	state.sceneWidth = framebuffer.getWidth();
	state.sceneHeight = framebuffer.getHeight();
	state.pixelOffset = 0;
	state.pixelCount = state.sceneWidth * state.sceneHeight;
	state.pixelsProcessed = 0;

	if (!settings.openCL.enabled)
		raytracer.run(state, interrupted);
	else
		clRaytracer.run(state, interrupted);

	if (settings.window.showInfoText)
	{
		text.drawText(5.0, (double)(runner.getWindowHeight() - 3 * settings.window.defaultFontSize), Color(255, 255, 255, 255), tfm::format("Pos: (%.2f, %.2f, %.2f)", scene.camera.position.x, scene.camera.position.y, scene.camera.position.z));
		text.drawText(5.0, (double)(runner.getWindowHeight() - 4 * settings.window.defaultFontSize - 2), Color(255, 255, 255, 255), tfm::format("Rot: (%.2f, %.2f, %.2f)", scene.camera.orientation.pitch, scene.camera.orientation.yaw, scene.camera.orientation.roll));
		text.drawText(5.0, (double)(runner.getWindowHeight() - 5 * settings.window.defaultFontSize - 4), Color(255, 255, 255, 255), tfm::format("Pix: (%d, %d)", runner.getMouseInfo().framebufferX, runner.getMouseInfo().framebufferY));
		text.drawText(5.0, (double)(runner.getWindowHeight() - 6 * settings.window.defaultFontSize - 6), Color(255, 255, 255, 255), tfm::format("Mov: %s", scene.camera.hasMoved()));
	}
}

void DefaultState::windowResized(int width, int height)
{
	(void)width;
	(void)height;
}

void DefaultState::framebufferResized(int width, int height)
{
	scene.camera.setImagePlaneSize(width, height);
}
<|endoftext|>


<commit_before>#pragma once

#include <memory>

namespace shadow
{

// abstract base class providing interface to held value
class holder_base
{
public:
    virtual holder_base* clone() const = 0;
    virtual ~holder_base() = default;
};

// concrete subclass holding value of any type
template <class T>
class holder : public holder_base
{
public:
    // this is necessary for any to access raw value
    friend class any;

public:
    holder(const T& value) : value_(value)
    {
    }

    virtual holder_base*
    clone() const override
    {
        return new holder(value_);
    }

private:
    T value_;
};

// specialization for type void, represents empty value
// holds no type information, intended as building block for a more complex type
// that holds type information through a reflection mechanism
template <>
class holder<void> : public holder_base
{
public:
    virtual holder_base*
    clone() const override
    {
        return new holder();
    }
};

// type erasure wrapper for value of any type
class any
{
public:
    // construct empty any (holds 'void')
    any() : holder_(std::make_unique<holder<void>>())
    {
    }

    // construct empty with a held value of type T
    template <class T>
    any(const T& value) : holder_(std::make_unique<holder<T>>(value))
    {
    }

    // copy construct, relies on holder implementation of clone
    any(const any& other) : holder_(other.holder_->clone())
    {
    }

    any(any&&) = default;

    any&
    operator=(any other)
    {
        holder_ = std::move(other.holder_);
        return *this;
    }

public:
    // unsafe interaction with underlying value, intended to be used by higher
    // level reflection mechanism that holds information about the type of held
    // value

    template <class T>
    T&
    get()
    {
        return static_cast<holder<T>*>(holder_.get())->value_;
    }

    template <class T>
    const T&
    get() const
    {
        return static_cast<holder<T>*>(holder_.get())->value_;
    }

private:
    std::unique_ptr<holder_base> holder_;
};
}
<commit_msg>Rearrange comment. 	modified:   include/any.hpp<commit_after>#pragma once

#include <memory>

namespace shadow
{

// abstract base class providing interface to held value
// holds no type information, intended as building block for a more complex type
// that holds type information through a reflection mechanism
class holder_base
{
public:
    virtual holder_base* clone() const = 0;
    virtual ~holder_base() = default;
};

// concrete subclass holding value of any type
template <class T>
class holder : public holder_base
{
public:
    // this is necessary for any to access raw value
    friend class any;

public:
    holder(const T& value) : value_(value)
    {
    }

    virtual holder_base*
    clone() const override
    {
        return new holder(value_);
    }

private:
    T value_;
};

// specialization for type void, represents empty value
template <>
class holder<void> : public holder_base
{
public:
    virtual holder_base*
    clone() const override
    {
        return new holder();
    }
};

// type erasure wrapper for value of any type
class any
{
public:
    // construct empty any (holds 'void')
    any() : holder_(std::make_unique<holder<void>>())
    {
    }

    // construct empty with a held value of type T
    template <class T>
    any(const T& value) : holder_(std::make_unique<holder<T>>(value))
    {
    }

    // copy construct, relies on holder implementation of clone
    any(const any& other) : holder_(other.holder_->clone())
    {
    }

    any(any&&) = default;

    any&
    operator=(any other)
    {
        holder_ = std::move(other.holder_);
        return *this;
    }

public:
    // unsafe interaction with underlying value, intended to be used by higher
    // level reflection mechanism that holds information about the type of held
    // value

    template <class T>
    T&
    get()
    {
        return static_cast<holder<T>*>(holder_.get())->value_;
    }

    template <class T>
    const T&
    get() const
    {
        return static_cast<holder<T>*>(holder_.get())->value_;
    }

private:
    std::unique_ptr<holder_base> holder_;
};
}
<|endoftext|>


<commit_before>/*

 * code.cpp
 *
 *  Created on: Oct 30, 2015
 *      Author: (Bu)nn

 */

#include <core/cvdef.h>
#include <core/cvstd.hpp>
#include <core/mat.hpp>
#include <core/mat.inl.hpp>
#include <core/matx.hpp>
#include <core/ptr.inl.hpp>
#include <core/types.hpp>
#include <core.hpp>
#include <highgui.hpp>
#include <imgproc/types_c.h>
#include <imgproc.hpp>
#include <objdetect.hpp>
#include <video/background_segm.hpp>
#include <videoio.hpp>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>

using namespace cv;
using namespace std;

Mat frame; //current frame
Mat fgMaskMOG2; //fg mask fg mask generated by MOG2 method
Mat back;
Ptr<BackgroundSubtractorMOG2> pMOG2; //MOG2 Background subtractor
vector<pair<Point, double>> palm_centers;
Mat draw;

/*

* Global variables
//String face_cascade_name = "../../../data/haarcascades/haarcascade_frontalface_alt.xml";
String face_cascade_name = "../../../data/haarcascades/aGest.xml";

CascadeClassifier face_cascade;
*/

//This function returns the square of the euclidean distance between 2 points.
double dist(Point x, Point y) {
  return (x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y);
}

Mat pre_processing(Mat frame) {

  GaussianBlur(frame, frame, Size(7, 7), 10, 10);
  Mat gray_scale;
  cvtColor(frame, gray_scale, COLOR_BGR2GRAY, 1);

  Mat element = (Mat_<uchar>(3, 3) << 0, 1, 0, 1, 1, 1, 0, 1, 0);
  morphologyEx(gray_scale, gray_scale, MORPH_OPEN, element);

  return gray_scale;
}

Mat bg_subtraction(VideoCapture cap, Mat frame) {
  //update the background model
  pMOG2->apply(frame, fgMaskMOG2);

  //Get background image to display it
  pMOG2->getBackgroundImage(back);
  pMOG2->setDetectShadows(0);
  pMOG2->setNMixtures(3);
  return fgMaskMOG2;
}

//This function returns the radius and the center of the circle given 3 points
//If a circle cannot be formed , it returns a zero radius circle centered at (0,0)
pair<Point, double> circleFromPoints(Point p1, Point p2, Point p3) {
  double offset = pow(p2.x, 2) + pow(p2.y, 2);
  double bc = (pow(p1.x, 2) + pow(p1.y, 2) - offset) / 2.0;
  double cd = (offset - pow(p3.x, 2) - pow(p3.y, 2)) / 2.0;
  double det = (p1.x - p2.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p2.y);
  double TOL = 0.0000001;
  if (abs(det) < TOL) {
    cout << "POINTS TOO CLOSE" << endl;
    return make_pair(Point(0, 0), 0);
  }

  double idet = 1 / det;
  double centerx = (bc * (p2.y - p3.y) - cd * (p1.y - p2.y)) * idet;
  double centery = (cd * (p1.x - p2.x) - bc * (p2.x - p3.x)) * idet;
  double radius = sqrt(pow(p2.x - centerx, 2) + pow(p2.y - centery, 2));

  return make_pair(Point(centerx, centery), radius);
}

Mat contouring(Mat binarized, Mat pre_processed) {
  vector<vector<Point>> contours;
//  vector<Vec4i> hierarchy;

  //Find the contours in the binarized foreground

//  findContours(binarized, contours,hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0));

  findContours(binarized, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_TC89_KCOS);

  for (int i = 0; i < contours.size(); i++)
    //Ignore all small insignificant areas
    if (contourArea(contours[i]) >= 5000) {
      //Draw contour
      vector<vector<Point>> tcontours;
      tcontours.push_back(contours[i]);
      drawContours(pre_processed, tcontours, -1, Scalar(0, 0, 255), 2);

      //Detect Hull in current contour
      vector<vector<Point> > hulls(1);
      vector<vector<int> > hullsI(1);
      convexHull(Mat(tcontours[0]), hulls[0], false);
      convexHull(Mat(tcontours[0]), hullsI[0], false);
      drawContours(pre_processed, hulls, -1, Scalar(0, 255, 0), 2);

      //Find minimum area rectangle to enclose hand
      RotatedRect rect = minAreaRect(Mat(tcontours[0]));

      //Find Convex Defects
      vector<Vec4i> defects;
      if (hullsI[0].size() > 0) {
        Point2f rect_points[4];
        rect.points(rect_points);
        for (int j = 0; j < 4; j++)
          line(pre_processed, rect_points[j], rect_points[(j + 1) % 4],
              Scalar(255, 0, 0), 1, 8);
        Point rough_palm_center;
        convexityDefects(tcontours[0], hullsI[0], defects);
        if (defects.size() >= 3) {
          vector<Point> palm_points;
          for (int j = 0; j < defects.size(); j++) {
            int startidx = defects[j][0];
            Point ptStart(tcontours[0][startidx]);
            int endidx = defects[j][1];
            Point ptEnd(tcontours[0][endidx]);
            int faridx = defects[j][2];
            Point ptFar(tcontours[0][faridx]);
            //Sum up all the hull and defect points to compute average
            rough_palm_center += ptFar + ptStart + ptEnd;
            palm_points.push_back(ptFar);
            palm_points.push_back(ptStart);
            palm_points.push_back(ptEnd);
          }

          //Get palm center by 1st getting the average of all defect points, this is the rough palm center,
          //Then U chose the closest 3 points ang get the circle radius and center formed from them which is the palm center.
          rough_palm_center.x /= defects.size() * 3;
          rough_palm_center.y /= defects.size() * 3;
          Point closest_pt = palm_points[0];
          vector<pair<double, int> > distvec;
          for (int i = 0; i < palm_points.size(); i++)
            distvec.push_back(
                make_pair(dist(rough_palm_center, palm_points[i]), i));
          sort(distvec.begin(), distvec.end());

          //Keep choosing 3 points till you find a circle with a valid radius
          //As there is a high chance that the closes points might be in a linear line or too close that it forms a very large circle
          pair<Point, double> soln_circle;
          for (int i = 0; i + 2 < distvec.size(); i++) {
            Point p1 = palm_points[distvec[i + 0].second];
            Point p2 = palm_points[distvec[i + 1].second];
            Point p3 = palm_points[distvec[i + 2].second];
            soln_circle = circleFromPoints(p1, p2, p3); //Final palm center,radius
            if (soln_circle.second != 0)
              break;
          }

          //Find avg palm centers for the last few frames to stabilize its centers, also find the avg radius
          palm_centers.push_back(soln_circle);
          if (palm_centers.size() > 10)
            palm_centers.erase(palm_centers.begin());

          Point palm_center;
          double radius = 0;

          //averaging all palm centres
          for (int i = 0; i < palm_centers.size(); i++) {
            palm_center += palm_centers[i].first;
            radius += palm_centers[i].second;
          }
          palm_center.x /= palm_centers.size();
          palm_center.y /= palm_centers.size();
          radius /= palm_centers.size();

          //Draw the palm center and the palm circle
          //The size of the palm gives the depth of the hand
          circle(pre_processed, palm_center, 5, Scalar(144, 144, 255), 3);
          circle(pre_processed, palm_center, radius, Scalar(144, 144, 255), 2);

          //Detect fingers by finding points that form an almost isosceles triangle with certain thesholds
          int no_of_fingers = 0;
          for (int j = 0; j < defects.size(); j++) {
            int startidx = defects[j][0];
            Point ptStart(tcontours[0][startidx]);
            int endidx = defects[j][1];
            Point ptEnd(tcontours[0][endidx]);
            int faridx = defects[j][2];
            Point ptFar(tcontours[0][faridx]);

            //X o--------------------------o Y

            double Xdist = sqrt(dist(palm_center, ptFar));
            double Ydist = sqrt(dist(palm_center, ptStart));
            double length = sqrt(dist(ptFar, ptStart));

            double retLength = sqrt(dist(ptEnd, ptFar));
            //Play with these thresholds to improve performance

/*

            createTrackbar("length", "Frame",&global_var1, 250, changing_var1);
            createTrackbar("Var2", "Frame",&global_var2, 250, changing_var2);

*/

            if (length <= 3 * radius && Ydist >= 0.4 * radius && length >= 10
                && retLength >= 10
                && max(length, retLength) / min(length, retLength) >= 0.8)
              if (min(Xdist, Ydist) / max(Xdist, Ydist) <= 0.8) {
                if ((Xdist >= 0.1 * radius && Xdist <= 1.3 * radius
                    && Xdist < Ydist)
                    || (Ydist >= 0.1 * radius && Ydist <= 1.3 * radius
                        && Xdist > Ydist))
                  line(pre_processed, ptEnd, ptFar, Scalar(0, 255, 0), 1), no_of_fingers++;
              }
          }
           no_of_fingers = min(5, no_of_fingers);
           cout << "NO OF FINGERS: " << no_of_fingers << endl;
/*

           putText(pre_processed, "NO OF FINGERS: " + to_string(no_of_fingers), Point(30,30),
               FONT_HERSHEY_COMPLEX_SMALL, 0.8, Scalar(200,200,250), 1, CV_AA);

*/
           if(no_of_fingers == 1){
             cout << "NO OF FINGERS: " << no_of_fingers << endl;
             //draw on draw matrix
             circle(draw, palm_center, 2, Scalar(144, 144, 255), 2);
             imshow("draw", draw);
           }
           }
      }

    }

  return pre_processed;
}

/*

void facedetect( Mat frame )
{
    vector<Rect> faces;
    Mat frame_gray;

    if(frame.channels() > 1 )
      cvtColor( frame, frame_gray, COLOR_BGR2GRAY);
    else
      frame_gray = frame;

    equalizeHist( frame_gray, frame_gray );

    //-- Detect faces
    face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size(30, 30) );

    for ( size_t i = 0; i < faces.size(); i++ )
    {
        Point center( faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 );
        ellipse( frame, center, Size( faces[i].width/2, faces[i].height/2 ), 0, 0, 360, Scalar( 0, 0, 0 ), 200, 8, 0 );

        Mat faceROI = frame_gray( faces[i] );
     }

}
*/

Mat skin_detect(Mat frame){
  //blur the image to make segmentation simpler
//  blur(frame, frame, Size(10, 10));

  //convert the image from bgr to hsv mode
  Mat hsv;
  cvtColor(frame, hsv, CV_BGR2HSV);

  Mat ranged;
  //lower bound - Scalar(0, 10, 60)  and upper bound - Scalar(20, 150, 255) for classifying skin
  //ranged is set to 255 (skin) if hsv is within the specified range and 0 otherwise.
  inRange(hsv, Scalar(0, 10, 60), Scalar(20, 150, 255), ranged);

  return ranged;
//  imshow("ranged", ranged);
}

int process_video() {

  VideoCapture cap(0); // open the default camera
  if (!cap.isOpened())  // check if we succeeded
    return -1;
/*

  //-- 1. Load the cascades
   if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading face cascade\n"); return -1; };

*/

  //draw on blackboard
  Size s = Size(640,480);
  draw = Mat::zeros(s,CV_8UC3);

  for (;;) {

/*
 * Play with parameters
 * BG Subt -> threshold [OTSU] -> morph -> contour = shows circles in contours
 * Face detect -> remove with flood fill -> skin -> contour
 * Hand Detection with haar -> bounding box -> contouring within box = shows circles in contours
*/

    //Capture the Frame and convert it to Grayscale
    cap >> frame; // get a new frame from camera

    Mat orig = frame.clone();

    Mat foreground;
    Mat pre_processed = pre_processing(frame);
    Mat bg_sub = bg_subtraction(cap, pre_processed);

/*
        facedetect(pre_processed);
        facedetect(back);
*/

    absdiff(pre_processed, back, foreground);

/*
    // detect and remove face
    //skin extraction and binarize on that basis
    Mat hand_binarized = skin_detect(frame);
*/

    Mat fg_binarized;
    threshold(foreground, fg_binarized, 0, 255, THRESH_BINARY | THRESH_OTSU);

    GaussianBlur(fg_binarized, fg_binarized, Size(7, 7), 10, 10);

    //morphology to remove noise
    Mat element = (Mat_<uchar>(3, 3) << 0, 1, 0, 1, 1, 1, 0, 1, 0);
    morphologyEx(fg_binarized, fg_binarized, MORPH_OPEN, element);

    //finally contour
    Mat contour = contouring(fg_binarized,orig);

    imshow("Frame", contour);
    if (waitKey(30) >= 0)
      break;
  }
  return 0;
}

int main(int, char**) {
  //create Background Subtractor objects
  pMOG2 = createBackgroundSubtractorMOG2(); //MOG2 approach
  int res = process_video();
  return 0;
}
<commit_msg>number of fingers being displayed to know the accuracy<commit_after>/*

 * code.cpp
 *
 *  Created on: Oct 30, 2015
 *      Author: (Bu)nn

 */

#include <core/cvdef.h>
#include <core/cvstd.hpp>
#include <core/mat.hpp>
#include <core/mat.inl.hpp>
#include <core/matx.hpp>
#include <core/ptr.inl.hpp>
#include <core/types.hpp>
#include <core.hpp>
#include <highgui.hpp>
#include <imgproc/types_c.h>
#include <imgproc.hpp>
#include <objdetect.hpp>
#include <video/background_segm.hpp>
#include <videoio.hpp>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <utility>
#include <vector>

using namespace cv;
using namespace std;

Mat frame; //current frame
Mat fgMaskMOG2; //fg mask fg mask generated by MOG2 method
Mat back;
Ptr<BackgroundSubtractorMOG2> pMOG2; //MOG2 Background subtractor
vector<pair<Point, double>> palm_centers;
Mat draw;

/*

* Global variables
//String face_cascade_name = "../../../data/haarcascades/haarcascade_frontalface_alt.xml";
String face_cascade_name = "../../../data/haarcascades/aGest.xml";

CascadeClassifier face_cascade;
*/

//This function returns the square of the euclidean distance between 2 points.
double dist(Point x, Point y) {
  return (x.x - y.x) * (x.x - y.x) + (x.y - y.y) * (x.y - y.y);
}

Mat pre_processing(Mat frame) {

  GaussianBlur(frame, frame, Size(7, 7), 10, 10);
  Mat gray_scale;
  cvtColor(frame, gray_scale, COLOR_BGR2GRAY, 1);

  Mat element = (Mat_<uchar>(3, 3) << 0, 1, 0, 1, 1, 1, 0, 1, 0);
  morphologyEx(gray_scale, gray_scale, MORPH_OPEN, element);

  return gray_scale;
}

Mat bg_subtraction(VideoCapture cap, Mat frame) {
  //update the background model
  pMOG2->apply(frame, fgMaskMOG2);

  //Get background image to display it
  pMOG2->getBackgroundImage(back);
  pMOG2->setDetectShadows(0);
  pMOG2->setNMixtures(3);
  return fgMaskMOG2;
}

//This function returns the radius and the center of the circle given 3 points
//If a circle cannot be formed , it returns a zero radius circle centered at (0,0)
pair<Point, double> circleFromPoints(Point p1, Point p2, Point p3) {
  double offset = pow(p2.x, 2) + pow(p2.y, 2);
  double bc = (pow(p1.x, 2) + pow(p1.y, 2) - offset) / 2.0;
  double cd = (offset - pow(p3.x, 2) - pow(p3.y, 2)) / 2.0;
  double det = (p1.x - p2.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p2.y);
  double TOL = 0.0000001;
  if (abs(det) < TOL) {
    cout << "POINTS TOO CLOSE" << endl;
    return make_pair(Point(0, 0), 0);
  }

  double idet = 1 / det;
  double centerx = (bc * (p2.y - p3.y) - cd * (p1.y - p2.y)) * idet;
  double centery = (cd * (p1.x - p2.x) - bc * (p2.x - p3.x)) * idet;
  double radius = sqrt(pow(p2.x - centerx, 2) + pow(p2.y - centery, 2));

  return make_pair(Point(centerx, centery), radius);
}

Mat contouring(Mat binarized, Mat pre_processed) {
  vector<vector<Point>> contours;
//  vector<Vec4i> hierarchy;

  //Find the contours in the binarized foreground

//  findContours(binarized, contours,hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0));

  findContours(binarized, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_TC89_KCOS);

  for (int i = 0; i < contours.size(); i++)
    //Ignore all small insignificant areas
    if (contourArea(contours[i]) >= 5000) {
      //Draw contour
      vector<vector<Point>> tcontours;
      tcontours.push_back(contours[i]);
      drawContours(pre_processed, tcontours, -1, Scalar(0, 0, 255), 2);

      //Detect Hull in current contour
      vector<vector<Point> > hulls(1);
      vector<vector<int> > hullsI(1);
      convexHull(Mat(tcontours[0]), hulls[0], false);
      convexHull(Mat(tcontours[0]), hullsI[0], false);
      drawContours(pre_processed, hulls, -1, Scalar(0, 255, 0), 2);

      //Find minimum area rectangle to enclose hand
      RotatedRect rect = minAreaRect(Mat(tcontours[0]));

      //Find Convex Defects
      vector<Vec4i> defects;
      if (hullsI[0].size() > 0) {
        Point2f rect_points[4];
        rect.points(rect_points);
        for (int j = 0; j < 4; j++)
          line(pre_processed, rect_points[j], rect_points[(j + 1) % 4],
              Scalar(255, 0, 0), 1, 8);
        Point rough_palm_center;
        convexityDefects(tcontours[0], hullsI[0], defects);
        if (defects.size() >= 3) {
          vector<Point> palm_points;
          for (int j = 0; j < defects.size(); j++) {
            int startidx = defects[j][0];
            Point ptStart(tcontours[0][startidx]);
            int endidx = defects[j][1];
            Point ptEnd(tcontours[0][endidx]);
            int faridx = defects[j][2];
            Point ptFar(tcontours[0][faridx]);
            //Sum up all the hull and defect points to compute average
            rough_palm_center += ptFar + ptStart + ptEnd;
            palm_points.push_back(ptFar);
            palm_points.push_back(ptStart);
            palm_points.push_back(ptEnd);
          }

          //Get palm center by 1st getting the average of all defect points, this is the rough palm center,
          //Then U chose the closest 3 points ang get the circle radius and center formed from them which is the palm center.
          rough_palm_center.x /= defects.size() * 3;
          rough_palm_center.y /= defects.size() * 3;
          Point closest_pt = palm_points[0];
          vector<pair<double, int> > distvec;
          for (int i = 0; i < palm_points.size(); i++)
            distvec.push_back(
                make_pair(dist(rough_palm_center, palm_points[i]), i));
          sort(distvec.begin(), distvec.end());

          //Keep choosing 3 points till you find a circle with a valid radius
          //As there is a high chance that the closes points might be in a linear line or too close that it forms a very large circle
          pair<Point, double> soln_circle;
          for (int i = 0; i + 2 < distvec.size(); i++) {
            Point p1 = palm_points[distvec[i + 0].second];
            Point p2 = palm_points[distvec[i + 1].second];
            Point p3 = palm_points[distvec[i + 2].second];
            soln_circle = circleFromPoints(p1, p2, p3); //Final palm center,radius
            if (soln_circle.second != 0)
              break;
          }

          //Find avg palm centers for the last few frames to stabilize its centers, also find the avg radius
          palm_centers.push_back(soln_circle);
          if (palm_centers.size() > 10)
            palm_centers.erase(palm_centers.begin());

          Point palm_center;
          double radius = 0;

          //averaging all palm centres
          for (int i = 0; i < palm_centers.size(); i++) {
            palm_center += palm_centers[i].first;
            radius += palm_centers[i].second;
          }
          palm_center.x /= palm_centers.size();
          palm_center.y /= palm_centers.size();
          radius /= palm_centers.size();

          //Draw the palm center and the palm circle
          //The size of the palm gives the depth of the hand
          circle(pre_processed, palm_center, 5, Scalar(144, 144, 255), 3);
          circle(pre_processed, palm_center, radius, Scalar(144, 144, 255), 2);

          //Detect fingers by finding points that form an almost isosceles triangle with certain thesholds
          int no_of_fingers = 0;
          for (int j = 0; j < defects.size(); j++) {
            int startidx = defects[j][0];
            Point ptStart(tcontours[0][startidx]);
            int endidx = defects[j][1];
            Point ptEnd(tcontours[0][endidx]);
            int faridx = defects[j][2];
            Point ptFar(tcontours[0][faridx]);

            //X o--------------------------o Y

            double Xdist = sqrt(dist(palm_center, ptFar));
            double Ydist = sqrt(dist(palm_center, ptStart));
            double length = sqrt(dist(ptFar, ptStart));

            double retLength = sqrt(dist(ptEnd, ptFar));
            //Play with these thresholds to improve performance

/*

            createTrackbar("length", "Frame",&global_var1, 250, changing_var1);
            createTrackbar("Var2", "Frame",&global_var2, 250, changing_var2);

*/

            if (length <= 3 * radius && Ydist >= 0.4 * radius && length >= 10
                && retLength >= 10
                && max(length, retLength) / min(length, retLength) >= 0.8)
              if (min(Xdist, Ydist) / max(Xdist, Ydist) <= 0.8) {
                if ((Xdist >= 0.1 * radius && Xdist <= 1.3 * radius
                    && Xdist < Ydist)
                    || (Ydist >= 0.1 * radius && Ydist <= 1.3 * radius
                        && Xdist > Ydist))
                  line(pre_processed, ptEnd, ptFar, Scalar(0, 255, 0), 1), no_of_fingers++;
              }
          }
           no_of_fingers = min(5, no_of_fingers);
           cout << "NO OF FINGERS: " << no_of_fingers << endl;

           putText(pre_processed, "NO OF FINGERS: " + to_string(no_of_fingers), Point(30,30),
               FONT_HERSHEY_COMPLEX_SMALL, 0.8, Scalar(200,200,250), 1, CV_AA);

           if(no_of_fingers == 1){
             cout << "NO OF FINGERS: " << no_of_fingers << endl;
             //draw on draw matrix
             circle(draw, palm_center, 2, Scalar(144, 144, 255), 2);
             imshow("draw", draw);
           }
           }
      }

    }

  return pre_processed;
}

/*

void facedetect( Mat frame )
{
    vector<Rect> faces;
    Mat frame_gray;

    if(frame.channels() > 1 )
      cvtColor( frame, frame_gray, COLOR_BGR2GRAY);
    else
      frame_gray = frame;

    equalizeHist( frame_gray, frame_gray );

    //-- Detect faces
    face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size(30, 30) );

    for ( size_t i = 0; i < faces.size(); i++ )
    {
        Point center( faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 );
        ellipse( frame, center, Size( faces[i].width/2, faces[i].height/2 ), 0, 0, 360, Scalar( 0, 0, 0 ), 200, 8, 0 );

        Mat faceROI = frame_gray( faces[i] );
     }

}
*/

Mat skin_detect(Mat frame){
  //blur the image to make segmentation simpler
//  blur(frame, frame, Size(10, 10));

  //convert the image from bgr to hsv mode
  Mat hsv;
  cvtColor(frame, hsv, CV_BGR2HSV);

  Mat ranged;
  //lower bound - Scalar(0, 10, 60)  and upper bound - Scalar(20, 150, 255) for classifying skin
  //ranged is set to 255 (skin) if hsv is within the specified range and 0 otherwise.
  inRange(hsv, Scalar(0, 10, 60), Scalar(20, 150, 255), ranged);

  return ranged;
//  imshow("ranged", ranged);
}

int process_video() {

  VideoCapture cap(0); // open the default camera
  if (!cap.isOpened())  // check if we succeeded
    return -1;
/*

  //-- 1. Load the cascades
   if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading face cascade\n"); return -1; };

*/

  //draw on blackboard
  Size s = Size(640,480);
  draw = Mat::zeros(s,CV_8UC3);

  for (;;) {

/*
 * Play with parameters
 * BG Subt -> threshold [OTSU] -> morph -> contour = shows circles in contours
 * Face detect -> remove with flood fill -> skin -> contour
 * Hand Detection with haar -> bounding box -> contouring within box = shows circles in contours
*/

    //Capture the Frame and convert it to Grayscale
    cap >> frame; // get a new frame from camera

    Mat orig = frame.clone();

    Mat foreground;
    Mat pre_processed = pre_processing(frame);
    Mat bg_sub = bg_subtraction(cap, pre_processed);

/*
        facedetect(pre_processed);
        facedetect(back);
*/

    absdiff(pre_processed, back, foreground);

/*
    // detect and remove face
    //skin extraction and binarize on that basis
    Mat hand_binarized = skin_detect(frame);
*/

    Mat fg_binarized;
    threshold(foreground, fg_binarized, 0, 255, THRESH_BINARY | THRESH_OTSU);

    GaussianBlur(fg_binarized, fg_binarized, Size(7, 7), 10, 10);

    //morphology to remove noise
    Mat element = (Mat_<uchar>(3, 3) << 0, 1, 0, 1, 1, 1, 0, 1, 0);
    morphologyEx(fg_binarized, fg_binarized, MORPH_OPEN, element);

    //finally contour
    Mat contour = contouring(fg_binarized,orig);

    imshow("Frame", contour);
    if (waitKey(30) >= 0)
      break;
  }
  return 0;
}

int main(int, char**) {
  //create Background Subtractor objects
  pMOG2 = createBackgroundSubtractorMOG2(); //MOG2 approach
  int res = process_video();
  return 0;
}
<|endoftext|>


<commit_before>#pragma once
#include <algorithm>
#include <condition_variable>
#include <cstdio>
#include <functional>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>
#include <vector>
#include <limits>
#include <cstring>
#include <bulk/world.hpp>

// Mutexes need to be shared, i.e. single instance of the class
// that is shared amongst threads.
// There is however a separate `world` object for every thread
// Therefore we create an extra class `world_state` of which there
// is only a single instance.

namespace bulk {
namespace cpp {

// Taken from
// http://stackoverflow.com/questions/24465533/implementing-boostbarrier-in-c11
class barrier {
  public:
    explicit barrier(std::size_t count)
        : threshold_(count), count_(count), generation_(0) {}

    void wait() {
        auto gen = generation_;
        std::unique_lock<std::mutex> lock{mutex_};
        if (!--count_) {
            generation_++;
            count_ = threshold_;
            cond_.notify_all();
        } else {
            cond_.wait(lock, [this, gen] { return gen != generation_; });
        }
    }

  private:
    std::mutex mutex_;
    std::condition_variable cond_;
    std::size_t threshold_;
    std::size_t count_;
    std::size_t generation_;
};

// single `world_state` instance shared by every thread
class world_state {
  public:
    explicit world_state(int processors) : sync_barrier(processors) {
        locations_.reserve(20 * processors);
    }

    barrier sync_barrier;
    // Used in var and coarray creation mechanism
    void* var_pointer_;

    std::mutex location_mutex;
    std::vector<void*> locations_;

    std::mutex log_mutex; // mutex for the vector and for sending output
    std::vector<std::pair<int,std::string>> logs;
    std::function<void(int, const std::string&)> log_callback;
};

// separate `world` instance for every thread
class world : public bulk::world {
  public:
    world(world_state* state, int pid, int nprocs)
        : state_(state), pid_(pid), nprocs_(nprocs) {}
    ~world() {}

    // Needs a move for environment::spawn to work
    world(world&& other) {
        state_ = other.state_;
        pid_ = other.pid_;
        nprocs_ = other.nprocs_;
        sync_operations_ = std::move(other.sync_operations_);
    }

    int active_processors() const override final { return nprocs_; }
    int processor_id() const override final { return pid_; }

    void barrier() override final { state_->sync_barrier.wait(); }

    void sync() override final {
        barrier();
        // Perform operations required at each sync like
        // swapping message queues
        for (auto& op : sync_operations_)
            op();

        // Print any log messages
        if (pid_ == 0) {
            auto& logs = state_->logs;
            std::stable_sort(logs.begin(), logs.end());
            if (state_->log_callback == nullptr) {
                for (auto& log : logs)
                    std::cout << log.second;
                std::cout << std::flush;
            } else {
                for (auto& log : logs)
                    state_->log_callback(log.first, log.second);
            }
            logs.clear();
        }
        barrier();
    }

    void log_(std::string message) override final {
        std::lock_guard<std::mutex> lock{state_->log_mutex};
        state_->logs.push_back(std::make_pair(pid_, message));
    }

    template <typename... Ts>
    void log_direct(const char* format, const Ts&... ts) {
        size_t size = snprintf(0, 0, format, ts...);
        char* buffer = new char[size + 1];
        snprintf(buffer, size + 1, format, ts...);
        std::string logmessage(buffer);
        delete[] buffer;
        {
            std::lock_guard<std::mutex> lock{state_->log_mutex};
            if (state_->log_callback == nullptr)
                std::cout << logmessage << std::flush;
            else
                state_->log_callback(pid_, logmessage);
        }
    }

    void abort() override final {
        //TODO
        return;
    }

    int register_sync_operation_(std::function<void(void)> f) {
        for (size_t i = 0; i < sync_operations_.size(); ++i) {
            if (sync_operations_[i] == nullptr) {
                sync_operations_[i] = f;
                return i;
            }
        }
        sync_operations_.push_back(f);
        return sync_operations_.size() - 1;
    }

    void unregister_sync_operation_(int id) {
        sync_operations_[id] = nullptr;
    }

    // Communication mechanism to communicate single pointers
    // Used by var and coarray constructors
    // We could use the variable-id system instead but this seems simpler.
    template <typename T>
    void set_pointer_(T* value) {
        state_->var_pointer_ = value;
    }
    template <typename T>
    T* get_pointer_() {
        return (T*)(state_->var_pointer_);
    }

  protected:
    int register_location_(void* location) override final {
        std::lock_guard<std::mutex> lock{state_->location_mutex};
        auto& locs = state_->locations_;
        for (unsigned int i = 0; i < locs.size(); i += nprocs_) {
            if (locs[i + pid_] == 0) {
                locs[i + pid_] = location;
                return (int)i;
            }
        }
        int id = locs.size();
        // There was no slot yet. In that case, this thread is the first
        // to reach this point, so we have to allocate `nprocs_` extra slots
        locs.insert(locs.end(), nprocs_, 0);
        locs[id + pid_] = location;
        return id;
    }

    void unregister_location_(int id) override final {
        // No mutex needed because each thread sets a different value to zero
        // and other than that, the vector is not modified
        state_->locations_[id + pid_] = 0;
    }

    void put_(int processor, const void* value, int size,
              int var_id) override final {
        memcpy(state_->locations_[var_id + processor], value, size);
        return;
    }

    // Size is per element
    void put_(int processor, const void* values, int size, int var_id,
              int offset, int count) override final {
        // TODO
        return;
    }
    void get_(int processor, int var_id, int size,
              void* target) override final {
        memcpy(target, state_->locations_[var_id + processor], size);
        return;
    }
    // Size is per element
    void get_(int processor, int var_id, int size, void* target, int offset,
              int count) override final {
        // TODO
        return;
    }

    int register_queue_(class queue_base* q) override final {
        // TODO
        return 0;
    }

    void unregister_queue_(int id) override final {
        // TODO
        return;
    }

    void send_(int processor, int queue_id, const void* data,
               int size) override final {
        // TODO
        return;
    }

  private:
    // This should be a reference but we can not assign it in the constructor
    // because `world` does not have a constructor. FIXME: Change this ?
    world_state* state_;
    int pid_;
    int nprocs_;
    std::vector<std::function<void(void)>> sync_operations_;
};

} // namespace cpp
} // namespace bulk
<commit_msg>Update arguments for cpp backend<commit_after>#pragma once

#include <algorithm>
#include <condition_variable>
#include <cstddef>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <limits>
#include <mutex>
#include <string>
#include <thread>
#include <vector>

#include <bulk/world.hpp>

// Mutexes need to be shared, i.e. single instance of the class
// that is shared amongst threads.
// There is however a separate `world` object for every thread
// Therefore we create an extra class `world_state` of which there
// is only a single instance.

namespace bulk {
namespace cpp {

// Taken from
// http://stackoverflow.com/questions/24465533/implementing-boostbarrier-in-c11
class barrier {
   public:
    explicit barrier(std::size_t count)
        : threshold_(count), count_(count), generation_(0) {}

    void wait() {
        auto gen = generation_;
        std::unique_lock<std::mutex> lock{mutex_};
        if (!--count_) {
            generation_++;
            count_ = threshold_;
            cond_.notify_all();
        } else {
            cond_.wait(lock, [this, gen] { return gen != generation_; });
        }
    }

   private:
    std::mutex mutex_;
    std::condition_variable cond_;
    std::size_t threshold_;
    std::size_t count_;
    std::size_t generation_;
};

// single `world_state` instance shared by every thread
class world_state {
   public:
    explicit world_state(int processors) : sync_barrier(processors) {
        locations_.reserve(20 * processors);
    }

    barrier sync_barrier;
    // Used in var and coarray creation mechanism
    void* var_pointer_;

    std::mutex location_mutex;
    std::vector<void*> locations_;

    std::mutex log_mutex;  // mutex for the vector and for sending output
    std::vector<std::pair<int, std::string>> logs;
    std::function<void(int, const std::string&)> log_callback;
};

// separate `world` instance for every thread
class world : public bulk::world {
   public:
    world(world_state* state, int pid, int nprocs)
        : state_(state), pid_(pid), nprocs_(nprocs) {}
    ~world() {}

    // Needs a move for environment::spawn to work
    world(world&& other) {
        state_ = other.state_;
        pid_ = other.pid_;
        nprocs_ = other.nprocs_;
        sync_operations_ = std::move(other.sync_operations_);
    }

    int active_processors() const override final { return nprocs_; }
    int processor_id() const override final { return pid_; }

    void barrier() override final { state_->sync_barrier.wait(); }

    void sync() override final {
        barrier();
        // Perform operations required at each sync like
        // swapping message queues
        for (auto& op : sync_operations_) op();

        // Print any log messages
        if (pid_ == 0) {
            auto& logs = state_->logs;
            std::stable_sort(logs.begin(), logs.end());
            if (state_->log_callback == nullptr) {
                for (auto& log : logs) std::cout << log.second;
                std::cout << std::flush;
            } else {
                for (auto& log : logs)
                    state_->log_callback(log.first, log.second);
            }
            logs.clear();
        }
        barrier();
    }

    void log_(std::string message) override final {
        std::lock_guard<std::mutex> lock{state_->log_mutex};
        state_->logs.push_back(std::make_pair(pid_, message));
    }

    template <typename... Ts>
    void log_direct(const char* format, const Ts&... ts) {
        size_t size = snprintf(0, 0, format, ts...);
        char* buffer = new char[size + 1];
        snprintf(buffer, size + 1, format, ts...);
        std::string logmessage(buffer);
        delete[] buffer;
        {
            std::lock_guard<std::mutex> lock{state_->log_mutex};
            if (state_->log_callback == nullptr)
                std::cout << logmessage << std::flush;
            else
                state_->log_callback(pid_, logmessage);
        }
    }

    void abort() override final {
        // TODO
        return;
    }

    int register_sync_operation_(std::function<void(void)> f) {
        for (size_t i = 0; i < sync_operations_.size(); ++i) {
            if (sync_operations_[i] == nullptr) {
                sync_operations_[i] = f;
                return i;
            }
        }
        sync_operations_.push_back(f);
        return sync_operations_.size() - 1;
    }

    void unregister_sync_operation_(int id) { sync_operations_[id] = nullptr; }

    // Communication mechanism to communicate single pointers
    // Used by var and coarray constructors
    // We could use the variable-id system instead but this seems simpler.
    template <typename T>
    void set_pointer_(T* value) {
        state_->var_pointer_ = value;
    }
    template <typename T>
    T* get_pointer_() {
        return (T*)(state_->var_pointer_);
    }

   protected:
    int register_location_(void* location) override final {
        std::lock_guard<std::mutex> lock{state_->location_mutex};
        auto& locs = state_->locations_;
        for (unsigned int i = 0; i < locs.size(); i += nprocs_) {
            if (locs[i + pid_] == 0) {
                locs[i + pid_] = location;
                return (int)i;
            }
        }
        int id = locs.size();
        // There was no slot yet. In that case, this thread is the first
        // to reach this point, so we have to allocate `nprocs_` extra slots
        locs.insert(locs.end(), nprocs_, 0);
        locs[id + pid_] = location;
        return id;
    }

    void unregister_location_(int id) override final {
        // No mutex needed because each thread sets a different value to zero
        // and other than that, the vector is not modified
        state_->locations_[id + pid_] = 0;
    }

    void put_(int processor, const void* value, std::size_t size,
              int var_id) override final {
        memcpy(state_->locations_[var_id + processor], value, size);
        return;
    }

    // Size is per element
    void put_(int processor, const void* values, std::size_t size, int var_id,
              std::size_t offset, int count) override final {
        // TODO
        return;
    }
    void get_(int processor, int var_id, std::size_t size,
              void* target) override final {
        memcpy(target, state_->locations_[var_id + processor], size);
        return;
    }
    // Size is per element
    void get_(int processor, int var_id, std::size_t size, void* target,
              std::size_t offset, int count) override final {
        // TODO
        return;
    }

    int register_queue_(class queue_base* q) override final {
        // TODO
        return 0;
    }

    void unregister_queue_(int id) override final {
        // TODO
        return;
    }

    void send_(int processor, int queue_id, const void* data,
               std::size_t size) override final {
        // TODO
        return;
    }

   private:
    // This should be a reference but we can not assign it in the constructor
    // because `world` does not have a constructor. FIXME: Change this ?
    world_state* state_;
    int pid_;
    int nprocs_;
    std::vector<std::function<void(void)>> sync_operations_;
};

}  // namespace cpp
}  // namespace bulk
<|endoftext|>


<commit_before>//===-- clang-format/ClangFormat.cpp - Clang format tool ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements a clang-format tool that automatically formats
/// (fragments of) C++ code.
///
//===----------------------------------------------------------------------===//

#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Format/Format.h"
#include "clang/Lex/Lexer.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Signals.h"

using namespace llvm;

static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);

static cl::list<int> Offsets(
    "offset", cl::desc("Format a range starting at this file offset."));
static cl::list<int> Lengths(
    "length", cl::desc("Format a range of this length, -1 for end of file."));
static cl::opt<std::string> Style(
    "style",
    cl::desc("Coding style, currently supports: LLVM, Google, Chromium."),
    cl::init("LLVM"));
static cl::opt<bool> Inplace("i",
                             cl::desc("Inplace edit <file>, if specified."));

static cl::opt<bool> OutputReplacements(
    "output-replacements", cl::desc("Output replacements as JSON."));

// FIXME: Remove this when styles are configurable through files.
static cl::opt<bool> InvertPointerBinding(
    "invert-pointer-binding", cl::desc("Inverts the side to which */& bind"),
    cl::init(false));

static cl::opt<std::string> FileName(cl::Positional, cl::desc("[<file>]"),
                                     cl::init("-"));

namespace clang {
namespace format {

static FileID createInMemoryFile(StringRef FileName, const MemoryBuffer *Source,
                                 SourceManager &Sources, FileManager &Files) {
  const FileEntry *Entry = Files.getVirtualFile(FileName == "-" ? "<stdin>" :
                                                    FileName,
                                                Source->getBufferSize(), 0);
  Sources.overrideFileContents(Entry, Source, true);
  return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
}

static FormatStyle getStyle() {
  FormatStyle TheStyle = getGoogleStyle();
  if (Style == "LLVM")
    TheStyle = getLLVMStyle();
  if (Style == "Chromium")
    TheStyle = getChromiumStyle();
  if (InvertPointerBinding) {
    TheStyle.PointerAndReferenceBindToType =
        !TheStyle.PointerAndReferenceBindToType;
  }
  return TheStyle;
}

static void format() {
  FileManager Files((FileSystemOptions()));
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
      new DiagnosticOptions);
  SourceManager Sources(Diagnostics, Files);
  OwningPtr<MemoryBuffer> Code;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
    llvm::errs() << ec.message() << "\n";
    return;
  }
  FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
  Lexer Lex(ID, Sources.getBuffer(ID), Sources, getFormattingLangOpts());
  if (Offsets.empty())
    Offsets.push_back(0);
  if (Offsets.size() != Lengths.size() &&
      !(Offsets.size() == 1 && Lengths.empty())) {
    llvm::errs() << "Number of -offset and -length arguments must match.\n";
    return;
  }
  std::vector<CharSourceRange> Ranges;
  for (cl::list<int>::size_type i = 0, e = Offsets.size(); i != e; ++i) {
    SourceLocation Start =
        Sources.getLocForStartOfFile(ID).getLocWithOffset(Offsets[i]);
    SourceLocation End;
    if (i < Lengths.size()) {
      End = Start.getLocWithOffset(Lengths[i]);
    } else {
      End = Sources.getLocForEndOfFile(ID);
    }
    Ranges.push_back(CharSourceRange::getCharRange(Start, End));
  }
  tooling::Replacements Replaces = reformat(getStyle(), Lex, Sources, Ranges);
  if (OutputReplacements) {
    llvm::outs() << "[\n";
    for (tooling::Replacements::const_iterator I = Replaces.begin(),
                                               E = Replaces.end();
         I != E; ++I) {
      if (I != Replaces.begin()) {
        llvm::outs() << ",\n";
      }
      llvm::outs() << "  {\n"
                   << "    \"offset\": " << I->getOffset() << ",\n"
                   << "    \"length\": " << I->getLength() << ",\n"
                   << "    \"replacement_text\": \"" << I->getReplacementText()
                   << "\"\n"
                   << "  }";
    }
    llvm::outs() << "\n]\n";
  } else {
    Rewriter Rewrite(Sources, LangOptions());
    tooling::applyAllReplacements(Replaces, Rewrite);
    if (Inplace) {
      if (Replaces.size() == 0)
        return; // Nothing changed, don't touch the file.

      std::string ErrorInfo;
      llvm::raw_fd_ostream FileStream(FileName.c_str(), ErrorInfo,
                                      llvm::raw_fd_ostream::F_Binary);
      if (!ErrorInfo.empty()) {
        llvm::errs() << "Error while writing file: " << ErrorInfo << "\n";
        return;
      }
      Rewrite.getEditBuffer(ID).write(FileStream);
      FileStream.flush();
    } else {
      Rewrite.getEditBuffer(ID).write(outs());
    }
  }
}

}  // namespace format
}  // namespace clang

int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  cl::ParseCommandLineOptions(
      argc, argv,
      "A tool to format C/C++/Obj-C code.\n\n"
      "Currently supports LLVM and Google style guides.\n"
      "If no arguments are specified, it formats the code from standard input\n"
      "and writes the result to the standard output.\n"
      "If <file> is given, it reformats the file. If -i is specified together\n"
      "with <file>, the file is edited in-place. Otherwise, the result is\n"
      "written to the standard output.\n");
  if (Help)
    cl::PrintHelpMessage();
  clang::format::format();
  return 0;
}
<commit_msg>Kick JSON output for XML output.<commit_after>//===-- clang-format/ClangFormat.cpp - Clang format tool ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements a clang-format tool that automatically formats
/// (fragments of) C++ code.
///
//===----------------------------------------------------------------------===//

#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Format/Format.h"
#include "clang/Lex/Lexer.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Signals.h"

using namespace llvm;

static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);

static cl::list<int> Offsets(
    "offset", cl::desc("Format a range starting at this file offset."));
static cl::list<int> Lengths(
    "length", cl::desc("Format a range of this length, -1 for end of file."));
static cl::opt<std::string> Style(
    "style",
    cl::desc("Coding style, currently supports: LLVM, Google, Chromium."),
    cl::init("LLVM"));
static cl::opt<bool> Inplace("i",
                             cl::desc("Inplace edit <file>, if specified."));

static cl::opt<bool> OutputXML(
    "output-replacements-xml", cl::desc("Output replacements as XML."));

// FIXME: Remove this when styles are configurable through files.
static cl::opt<bool> InvertPointerBinding(
    "invert-pointer-binding", cl::desc("Inverts the side to which */& bind"),
    cl::init(false));

static cl::opt<std::string> FileName(cl::Positional, cl::desc("[<file>]"),
                                     cl::init("-"));

namespace clang {
namespace format {

static FileID createInMemoryFile(StringRef FileName, const MemoryBuffer *Source,
                                 SourceManager &Sources, FileManager &Files) {
  const FileEntry *Entry = Files.getVirtualFile(FileName == "-" ? "<stdin>" :
                                                    FileName,
                                                Source->getBufferSize(), 0);
  Sources.overrideFileContents(Entry, Source, true);
  return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
}

static FormatStyle getStyle() {
  FormatStyle TheStyle = getGoogleStyle();
  if (Style == "LLVM")
    TheStyle = getLLVMStyle();
  if (Style == "Chromium")
    TheStyle = getChromiumStyle();
  if (InvertPointerBinding) {
    TheStyle.PointerAndReferenceBindToType =
        !TheStyle.PointerAndReferenceBindToType;
  }
  return TheStyle;
}

static void format() {
  FileManager Files((FileSystemOptions()));
  DiagnosticsEngine Diagnostics(
      IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
      new DiagnosticOptions);
  SourceManager Sources(Diagnostics, Files);
  OwningPtr<MemoryBuffer> Code;
  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
    llvm::errs() << ec.message() << "\n";
    return;
  }
  FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
  Lexer Lex(ID, Sources.getBuffer(ID), Sources, getFormattingLangOpts());
  if (Offsets.empty())
    Offsets.push_back(0);
  if (Offsets.size() != Lengths.size() &&
      !(Offsets.size() == 1 && Lengths.empty())) {
    llvm::errs() << "Number of -offset and -length arguments must match.\n";
    return;
  }
  std::vector<CharSourceRange> Ranges;
  for (cl::list<int>::size_type i = 0, e = Offsets.size(); i != e; ++i) {
    SourceLocation Start =
        Sources.getLocForStartOfFile(ID).getLocWithOffset(Offsets[i]);
    SourceLocation End;
    if (i < Lengths.size()) {
      End = Start.getLocWithOffset(Lengths[i]);
    } else {
      End = Sources.getLocForEndOfFile(ID);
    }
    Ranges.push_back(CharSourceRange::getCharRange(Start, End));
  }
  tooling::Replacements Replaces = reformat(getStyle(), Lex, Sources, Ranges);
  if (OutputXML) {
    llvm::outs() << "<?xml version='1.0'?>\n<replacements>\n";
    for (tooling::Replacements::const_iterator I = Replaces.begin(),
                                               E = Replaces.end();
         I != E; ++I) {
      llvm::outs() << "<replacement "
                   << "offset='" << I->getOffset() << "' "
                   << "length='" << I->getLength() << "'>"
                   << I->getReplacementText() << "</replacement>\n";
    }
    llvm::outs() << "</replacements>\n";
  } else {
    Rewriter Rewrite(Sources, LangOptions());
    tooling::applyAllReplacements(Replaces, Rewrite);
    if (Inplace) {
      if (Replaces.size() == 0)
        return; // Nothing changed, don't touch the file.

      std::string ErrorInfo;
      llvm::raw_fd_ostream FileStream(FileName.c_str(), ErrorInfo,
                                      llvm::raw_fd_ostream::F_Binary);
      if (!ErrorInfo.empty()) {
        llvm::errs() << "Error while writing file: " << ErrorInfo << "\n";
        return;
      }
      Rewrite.getEditBuffer(ID).write(FileStream);
      FileStream.flush();
    } else {
      Rewrite.getEditBuffer(ID).write(outs());
    }
  }
}

}  // namespace format
}  // namespace clang

int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal();
  cl::ParseCommandLineOptions(
      argc, argv,
      "A tool to format C/C++/Obj-C code.\n\n"
      "Currently supports LLVM and Google style guides.\n"
      "If no arguments are specified, it formats the code from standard input\n"
      "and writes the result to the standard output.\n"
      "If <file> is given, it reformats the file. If -i is specified together\n"
      "with <file>, the file is edited in-place. Otherwise, the result is\n"
      "written to the standard output.\n");
  if (Help)
    cl::PrintHelpMessage();
  clang::format::format();
  return 0;
}
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2015 Relja Ljubobratovic, ljubobratovic.relja@gmail.com
//
// 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.
//
// Description:
// Bounded priority queue structure implementation.
//
// Author:
// Relja Ljubobratovic, ljubobratovic.relja@gmail.com

#ifndef BPG_HPP_2QLEMDVV
#define BPG_HPP_2QLEMDVV

#include "fwd.hpp"
#include "vector.hpp"

#include <cstring>
#include <algorithm>

namespace cv {

/*!
 *
 * @brief Bounded priority Queue.
 *
 * Used to define limit sized queue,
 * arranged by priority score.
 *
 * As templates, queue takes a value type, and
 * comparator functor model, which is by default
 * std::less<real_t>.
 *
 * \warning
 * Consider the initial score value (priority_queue::set_init_score)
 * and comparator model together. Enqueue method performs
 * by comparing the current scores with the given one,
 * and if initial score value is too off, no result will
 * be enqueued.
 *
 */
template<class _Tp, unsigned _Dim, class _ComparatorType = std::less<real_t> >
class priority_queue {
public:
	typedef _ComparatorType comparator_type;
	typedef vectorx<_Tp, _Dim> point_type;
	typedef point_type &reference;
	typedef const point_type &const_reference;

private:
	real_t *_score;
	point_type *_data;
	unsigned _length;
	real_t _init_score;
	comparator_type _cmp_model;

	void allocate(unsigned length) {
		if (length > 0) {
			this->_score = new real_t[length];
			this->_data = new point_type[length];
		} else {
			this->_score = nullptr;
			this->_data = nullptr;
		}
		this->_lenght = length;
	}

	void deallocate() {
		delete [] this->_score;
		delete [] this->_data;
		this->_score = nullptr;
		this->_data = nullptr;
		this->_length = 0;
	}

	void init_score() {
		if (this->_length) {
			std::fill(this->_score, this->_score + this->_length, this->_init_score);
		}
	}

	void copy_score(real_t *score, unsigned length) {
		ASSERT(score);
		if (length) {
			if (length != this->_length)
				this->allocate(length);
			std::copy(score, score + length, _score);
		}
	}

public:
	//! Default constructor.
	priority_queue() :
		_score(nullptr), _data(nullptr), _length(0), _init_score(CV_BPQ_INIT_VALUE) {
	}
	//! Class constructor using size and initial value.
	priority_queue(unsigned length, real_t _init_score = CV_BPQ_INIT_VALUE) :
		_score(nullptr), _data(nullptr), _init_score(_init_score)
	{
		this->allocate(length);
		init_score();
	}
	//! Copy constructor.
	priority_queue(const priority_queue& cpy) :
		_score(nullptr), _data(nullptr), _length(0), _init_score(cpy._init_score)
	{
		this->allocate(cpy._length);
		std::copy(cpy._score, cpy._score + cpy._length, this->_score);
		std::copy(cpy._data, cpy._data + cpy._length, this->_data);
	}
	//! Move constructor.
	priority_queue(priority_queue &&move) :
	_score(move._score), _data(move._data), _length(move._length), _init_score(move._init_score) {
		move._score = nullptr;
		move._data = nullptr;
		move._length = 0;
		move._init_score = CV_BPQ_INIT_VALUE;
	}
	//! Class destructor.
	~priority_queue() {
	}

	//! Create the queue of given size, and initial score.
	priority_queue &create(unsigned length, real_t _init_score = CV_BPQ_INIT_VALUE) {

		ASSERT(length);

		this->_init_score = _init_score;
		this->deallocate();
		this->allocate(length);
		this->init_score();

		return *this;
	}

	//! Assignment operator.
	priority_queue &operator=(const priority_queue &rhs) {
		if (this != &rhs) {
			this->deallocate();
			this->allocate(rhs._length);
			this->_init_score = rhs._init_score;
			if (this->_score) {
				std::copy(rhs._score, rhs._score + rhs._length, this->_score);
				std::copy(rhs._data, rhs._data + rhs._length, this->_data);
			}
		}
		return *this;
	}

	//! Move operator.
	priority_queue &operator=(priority_queue &&rhs) {
		if (this != &rhs) {
			this->_score = rhs._score;
			this->_data = rhs._data;
			this->_length = rhs._length;
			this->_init_score = rhs._init_score;
			rhs._score = nullptr;
			rhs._data = nullptr;
			rhs._length = 0;
			rhs._init_score = CV_BPQ_INIT_VALUE;
		}
		return *this;
	}

	//! Append item to queue.
	void enque(const point_type &in, real_t score) {
		ASSERT(*this && score >= 0);

		for(unsigned i = 0; i < this->length(); ++i) {
			if (this->_cmp_model(score, this->_score[i])) {
				// move _data and _score, from i-th index to end.
				for (int j = this->length() - 1; j > i; j--) {
					this->_data[j] = this->_data[j - 1];
					this->_score[j] = this->_score[j - 1];
				}
				// set result
				this->_data[i] = in;
				_score[i] = score;
				return;
			}
		}
	}

	//! Return the value of the queue item at index.
	const_reference get_value(unsigned index) const {
		ASSERT(index < this->length());
		return this->_data[index];
	}

	//! Return the score of the queue item at index.
	real_t get_score(unsigned index) const {
		ASSERT(index < this->length());
		return this->_score[index];
	}

	//! Assign initialization score value.
	void set_init_score(real_t init) {
		this->_init_score = init;
	}

	/*!
	 * @brief Find out if indexed queue item has been populated with valid data.
	 *
	 * Non-populated queue item is the one with the score value
	 * equal to the initial score value.
	 */
	bool is_populated(unsigned index) const {
		ASSERT(index < this->length());
		return (_score[index] < _init_score) ? true : false;
	}

	//! Maximal distance in the queue, without including items which are not queued.
	real_t max_distance() {
		real_t dist = 0;
		for(unsigned i = 0; i < this->length(); ++i) {
			if (this->_score[i] < _init_score && this->_score[i] > dist)
				dist = this->_score[i];
		}
		return dist;
	}
};

}

#endif /* end of include guard: BPG_HPP_2QLEMDVV */
<commit_msg>fixed value type<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2015 Relja Ljubobratovic, ljubobratovic.relja@gmail.com
//
// 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.
//
// Description:
// Bounded priority queue structure implementation.
//
// Author:
// Relja Ljubobratovic, ljubobratovic.relja@gmail.com

#ifndef BPG_HPP_2QLEMDVV
#define BPG_HPP_2QLEMDVV

#include "fwd.hpp"
#include "vector.hpp"

#include <cstring>
#include <algorithm>

namespace cv {

/*!
 *
 * @brief Bounded priority Queue.
 *
 * Used to define limit sized queue,
 * arranged by priority score.
 *
 * As templates, queue takes a value type, and
 * comparator functor model, which is by default
 * std::less<real_t>.
 *
 * \warning
 * Consider the initial score value (priority_queue::set_init_score)
 * and comparator model together. Enqueue method performs
 * by comparing the current scores with the given one,
 * and if initial score value is too off, no result will
 * be enqueued.
 *
 */
template<typename _Tp, class _ComparatorType = std::less<real_t> >
class priority_queue {
public:
	typedef _ComparatorType comparator_type;
	typedef _Tp value_type;
	typedef value_type &reference;
	typedef const value_type &const_reference;

private:
	real_t *_score;
	value_type *_data;
	unsigned _length;
	real_t _init_score;
	comparator_type _cmp_model;

	void allocate(unsigned length) {
		if (length > 0) {
			this->_score = new real_t[length];
			this->_data = new value_type[length];
		} else {
			this->_score = nullptr;
			this->_data = nullptr;
		}
		this->_lenght = length;
	}

	void deallocate() {
		delete [] this->_score;
		delete [] this->_data;
		this->_score = nullptr;
		this->_data = nullptr;
		this->_length = 0;
	}

	void init_score() {
		if (this->_length) {
			std::fill(this->_score, this->_score + this->_length, this->_init_score);
		}
	}

	void copy_score(real_t *score, unsigned length) {
		ASSERT(score);
		if (length) {
			if (length != this->_length)
				this->allocate(length);
			std::copy(score, score + length, _score);
		}
	}

public:
	//! Default constructor.
	priority_queue() :
		_score(nullptr), _data(nullptr), _length(0), _init_score(CV_BPQ_INIT_VALUE) {
	}
	//! Class constructor using size and initial value.
	priority_queue(unsigned length, real_t _init_score = CV_BPQ_INIT_VALUE) :
		_score(nullptr), _data(nullptr), _init_score(_init_score)
	{
		this->allocate(length);
		init_score();
	}
	//! Copy constructor.
	priority_queue(const priority_queue& cpy) :
		_score(nullptr), _data(nullptr), _length(0), _init_score(cpy._init_score)
	{
		this->allocate(cpy._length);
		std::copy(cpy._score, cpy._score + cpy._length, this->_score);
		std::copy(cpy._data, cpy._data + cpy._length, this->_data);
	}
	//! Move constructor.
	priority_queue(priority_queue &&move) :
	_score(move._score), _data(move._data), _length(move._length), _init_score(move._init_score) {
		move._score = nullptr;
		move._data = nullptr;
		move._length = 0;
		move._init_score = CV_BPQ_INIT_VALUE;
	}
	//! Class destructor.
	~priority_queue() {
	}

	//! Create the queue of given size, and initial score.
	priority_queue &create(unsigned length, real_t _init_score = CV_BPQ_INIT_VALUE) {

		ASSERT(length);

		this->_init_score = _init_score;
		this->deallocate();
		this->allocate(length);
		this->init_score();

		return *this;
	}

	//! Assignment operator.
	priority_queue &operator=(const priority_queue &rhs) {
		if (this != &rhs) {
			this->deallocate();
			this->allocate(rhs._length);
			this->_init_score = rhs._init_score;
			if (this->_score) {
				std::copy(rhs._score, rhs._score + rhs._length, this->_score);
				std::copy(rhs._data, rhs._data + rhs._length, this->_data);
			}
		}
		return *this;
	}

	//! Move operator.
	priority_queue &operator=(priority_queue &&rhs) {
		if (this != &rhs) {
			this->_score = rhs._score;
			this->_data = rhs._data;
			this->_length = rhs._length;
			this->_init_score = rhs._init_score;
			rhs._score = nullptr;
			rhs._data = nullptr;
			rhs._length = 0;
			rhs._init_score = CV_BPQ_INIT_VALUE;
		}
		return *this;
	}

	//! Append item to queue.
	void enque(const value_type &in, real_t score) {
		ASSERT(*this && score >= 0);

		for(unsigned i = 0; i < this->length(); ++i) {
			if (this->_cmp_model(score, this->_score[i])) {
				// move _data and _score, from i-th index to end.
				for (int j = this->length() - 1; j > i; j--) {
					this->_data[j] = this->_data[j - 1];
					this->_score[j] = this->_score[j - 1];
				}
				// set result
				this->_data[i] = in;
				_score[i] = score;
				return;
			}
		}
	}

	//! Return the value of the queue item at index.
	const_reference get_value(unsigned index) const {
		ASSERT(index < this->length());
		return this->_data[index];
	}

	//! Return the score of the queue item at index.
	real_t get_score(unsigned index) const {
		ASSERT(index < this->length());
		return this->_score[index];
	}

	//! Assign initialization score value.
	void set_init_score(real_t init) {
		this->_init_score = init;
	}

	/*!
	 * @brief Find out if indexed queue item has been populated with valid data.
	 *
	 * Non-populated queue item is the one with the score value
	 * equal to the initial score value.
	 */
	bool is_populated(unsigned index) const {
		ASSERT(index < this->length());
		return (_score[index] < _init_score) ? true : false;
	}

	//! Maximal distance in the queue, without including items which are not queued.
	real_t max_distance() {
		real_t dist = 0;
		for(unsigned i = 0; i < this->length(); ++i) {
			if (this->_score[i] < _init_score && this->_score[i] > dist)
				dist = this->_score[i];
		}
		return dist;
	}
};

}

#endif /* end of include guard: BPG_HPP_2QLEMDVV */
<|endoftext|>


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

#include "i6engine/rpg/components/AttributeComponent.h"

#include "i6engine/utils/Exceptions.h"

#include "i6engine/rpg/components/Config.h"

namespace i6engine {
namespace rpg {
namespace components {

	AttributeComponent::AttributeComponent(int64_t id, const api::attributeMap & params) : Component(id, params), _attributes(size_t(Attribute::COUNT)) {
		_objFamilyID = config::ComponentTypes::AttributeComponent;
		_objComponentID = config::ComponentTypes::AttributeComponent;

		_attributes[0] = std::stoi(params.find("attribute_0")->second.c_str());
		_attributes[1] = std::stoi(params.find("attribute_1")->second.c_str());
	}

	api::ComPtr AttributeComponent::createC(int64_t id, const api::attributeMap & params) {
		ISIXE_THROW_API_COND("AttributeComponent", "attribute_0 not set!", params.find("attribute_0") != params.end());
		ISIXE_THROW_API_COND("AttributeComponent", "attribute_1 not set!", params.find("attribute_1") != params.end());
		return utils::make_shared<AttributeComponent, api::Component>(id, params);
	}

	void AttributeComponent::Init() {
	}

	api::attributeMap AttributeComponent::synchronize() const {
		api::attributeMap params;

		for (size_t i = 0; i < _attributes.size(); i++) {
			params.insert(std::make_pair("attribute_" + std::to_string(i), std::to_string(_attributes[i])));
		}

		return params;
	}

	void AttributeComponent::changeAttribute(Attribute attribute, int32_t diff) {
		_attributes[size_t(attribute)] = _attributes[size_t(attribute)] + diff;
	}

	void AttributeComponent::registerListener(Attribute attribute, const std::function<void(int32_t)> & func) {
		_attributes[size_t(attribute)].registerUpdate(func);
	}

} /* namespace components */
} /* namespace rpg */
} /* namespace i6engine */
<commit_msg>ISIXE-909 refactoring<commit_after>/**
 * Copyright 2012 FAU (Friedrich Alexander University of Erlangen-Nuremberg)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "i6engine/rpg/components/AttributeComponent.h"

#include "i6engine/utils/Exceptions.h"

#include "i6engine/rpg/components/Config.h"

namespace i6engine {
namespace rpg {
namespace components {

	AttributeComponent::AttributeComponent(int64_t id, const api::attributeMap & params) : Component(id, params), _attributes(size_t(Attribute::COUNT)) {
		_objFamilyID = config::ComponentTypes::AttributeComponent;
		_objComponentID = config::ComponentTypes::AttributeComponent;

		_attributes[0] = std::stoi(params.find("attribute_0")->second);
		_attributes[1] = std::stoi(params.find("attribute_1")->second);
	}

	api::ComPtr AttributeComponent::createC(int64_t id, const api::attributeMap & params) {
		ISIXE_THROW_API_COND("AttributeComponent", "attribute_0 not set!", params.find("attribute_0") != params.end());
		ISIXE_THROW_API_COND("AttributeComponent", "attribute_1 not set!", params.find("attribute_1") != params.end());
		return utils::make_shared<AttributeComponent, api::Component>(id, params);
	}

	void AttributeComponent::Init() {
	}

	api::attributeMap AttributeComponent::synchronize() const {
		api::attributeMap params;

		for (size_t i = 0; i < _attributes.size(); i++) {
			params.insert(std::make_pair("attribute_" + std::to_string(i), std::to_string(_attributes[i])));
		}

		return params;
	}

	void AttributeComponent::changeAttribute(Attribute attribute, int32_t diff) {
		_attributes[size_t(attribute)] = _attributes[size_t(attribute)] + diff;
	}

	void AttributeComponent::registerListener(Attribute attribute, const std::function<void(int32_t)> & func) {
		_attributes[size_t(attribute)].registerUpdate(func);
	}

} /* namespace components */
} /* namespace rpg */
} /* namespace i6engine */
<|endoftext|>