<commit_before>//------------------------------------------------------------------------------
// File: oapis.hpp
//
// Desc: OpenCVR API - OpenCVR API.
//
// Copyright (c) 2014-2018 opencvr.com. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __VSC_OAPIS_H_
#define __VSC_OAPIS_H_
#include "oapicmn.hpp"
#include "factory.hpp"
#include "oapiproto.hpp"
#include "XSDK/XHash.h"
#include "XSDK/TimeUtils.h"
#include "XSDK/XSocket.h"
#include "XSDK/XSSLSocket.h"

using namespace XSDK;
using namespace std;
using namespace oapi;

class OAPIConverter
{
public:
	inline static BOOL Converter(VSCDeviceData__ &from, oapi::Device &to);
	inline static BOOL Converter(oapi::Device &from, VSCDeviceData__ &to);
};

/* a internal thread to process all the request of XSocket */
class OAPIServer
{
public:
	inline OAPIServer(XRef<XSocket> pSocket, Factory &pFactory);
	inline ~OAPIServer();
public:
	inline BOOL Process(OAPIHeader &header);

public:
	inline BOOL ProcessGetDevice(s32 len);
	inline BOOL ProcessStartLive(s32 len);
	inline BOOL ProcessStopLive(s32 len);
public:
	inline void DataHandler1(VideoFrame& frame);
	inline static void DataHandler(VideoFrame& frame, void * pParam);
public:
	void Lock()
	{
		m_Lock.lock();
	}
	void UnLock()
	{
		m_Lock.unlock();
	}

private:
	fast_mutex m_Lock;
	XRef<XSocket> m_pSocket;
	Factory &m_pFactory;
	int m_nLiveviewId;
	int m_cnt;
};

#include "oapisimpl.hpp"
#endif<commit_msg>change oapi define<commit_after>//------------------------------------------------------------------------------
// File: oapis.hpp
//
// Desc: OpenCVR API - OpenCVR API.
//
// Copyright (c) 2014-2018 opencvr.com. All rights reserved.
//------------------------------------------------------------------------------
#ifndef __VSC_OAPIS_H_
#define __VSC_OAPIS_H_
#include "oapicmn.hpp"
#include "factory.hpp"
#include "oapiproto.hpp"
#include "XSDK/XHash.h"
#include "XSDK/TimeUtils.h"
#include "XSDK/XSocket.h"
#include "XSDK/XSSLSocket.h"
#include "Poco/UUIDGenerator.h"
#include "XSDK/XMD5.h"

using namespace XSDK;
using namespace std;
using namespace oapi;
using namespace Poco;

class OAPIConverter
{
public:
	inline static BOOL Converter(VSCDeviceData__ &from, oapi::Device &to);
	inline static BOOL Converter(oapi::Device &from, VSCDeviceData__ &to);
};

/* a internal thread to process all the request of XSocket */
class OAPIServer
{
public:
	inline OAPIServer(XRef<XSocket> pSocket, Factory &pFactory);
	inline ~OAPIServer();
public:
	inline BOOL Process(OAPIHeader &header);

public:
	inline BOOL ProcessGetDevice(s32 len);
	inline BOOL ProcessStartLive(s32 len);
	inline BOOL ProcessStopLive(s32 len);
	inline BOOL ProcessLogin(s32 len);
public:
	inline void DataHandler1(VideoFrame& frame);
	inline static void DataHandler(VideoFrame& frame, void * pParam);
public:
	void Lock()
	{
		m_Lock.lock();
	}
	void UnLock()
	{
		m_Lock.unlock();
	}

private:
	fast_mutex m_Lock;
	XRef<XSocket> m_pSocket;
	Factory &m_pFactory;
	int m_nLiveviewId;
	int m_cnt;
	BOOL m_bLogin;
	astring m_seesionId;
};

#include "oapisimpl.hpp"
#endif<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_FORCEFIELD_CONSTANTFORCEFIELD_INL
#define SOFA_COMPONENT_FORCEFIELD_CONSTANTFORCEFIELD_INL

#include <sofa/component/forcefield/ConstantForceField.h>
#include <sofa/helper/system/config.h>
#include <sofa/helper/gl/template.h>
#include <assert.h>
#include <iostream>
//#include <sofa/helper/gl/BasicShapes.h>
#include <sofa/simulation/common/Simulation.h>
#include <sofa/core/behavior/ForceField.inl>
#include <sofa/core/visual/VisualParams.h>
#include <sofa/component/topology/TopologySubsetData.inl>

namespace sofa
{

namespace component
{

namespace forcefield
{

template<class DataTypes>
ConstantForceField<DataTypes>::ConstantForceField()
    : points(initData(&points, "points", "points where the forces are applied"))
    , forces(initData(&forces, "forces", "applied forces at each point"))
    , force(initData(&force, "force", "applied force to all points if forces attribute is not specified"))
    , totalForce(initData(&totalForce, "totalForce", "total force for all points, will be distributed uniformly over points"))
    , arrowSizeCoef(initData(&arrowSizeCoef,0.0, "arrowSizeCoef", "Size of the drawn arrows (0->no arrows, sign->direction of drawing"))
    , indexFromEnd(initData(&indexFromEnd,(bool)false,"indexFromEnd", "Concerned DOFs indices are numbered from the end of the MState DOFs vector"))
{
}

template<class DataTypes>
void ConstantForceField<DataTypes>::init()
{
    topology = this->getContext()->getMeshTopology();

    // Initialize functions and parameters for topology data and handler
    points.createTopologicalEngine(topology);
    points.registerTopologicalData();

    Inherit::init();
}

template<class DataTypes>
void ConstantForceField<DataTypes>::addForce(const core::MechanicalParams* /*params*/ /* PARAMS FIRST */, DataVecDeriv& f1, const DataVecCoord& p1, const DataVecDeriv&)
{
    sofa::helper::WriteAccessor< core::objectmodel::Data< VecDeriv > > _f1 = f1;
    _f1.resize(p1.getValue().size());

//        sout << "Points = " << points.getValue() << sendl;
    Deriv singleForce;
    if ( totalForce.getValue()*totalForce.getValue() > 0.0)
    {
        for (unsigned comp = 0; comp < totalForce.getValue().size(); comp++)
            singleForce[comp] = (totalForce.getValue()[comp])/(Real(points.getValue().size()));
        //std::cout << "Setting forces for each node to = " << singleForce << std::endl;
    }
    else if (force.getValue()*force.getValue() > 0.0)
    {
        singleForce = force.getValue();
        //std::cout << "Setting forces for each node to = " << singleForce << std::endl;
    }

    const VecIndex& indices = points.getValue();
//        sout << "indices = " << indices << sendl;
    const VecDeriv& f = forces.getValue();
    //const Deriv f_end = (f.empty()? force.getValue() : f[f.size()-1]);
    const Deriv f_end = (f.empty()? singleForce : f[f.size()-1]);
    unsigned int i = 0;

    if (!indexFromEnd.getValue())
    {
        for (; i < f.size(); i++)
        {
            sout<<"_f1[indices[i]] += f[i], "<< _f1[indices.empty() ? i : indices[i]] << " += " << f[i] << sendl;
            _f1[ indices.empty() ? i : indices[i] ] += f[i];  // if indices are not set, use the force indices

        }
        for (; i < indices.size(); i++)
        {
//                    sout<<"_f1[indices[i]] += f_end, "<< _f1[indices[i]] << " += " << f_end << sendl;
            _f1[indices[i]] += f_end;
        }
    }
    else
    {
        for (; i < f.size(); i++)
        {
            _f1[_f1.size() - indices[i] - 1] += f[i];
        }
        for (; i < indices.size(); i++)
        {
            _f1[_f1.size() - indices[i] - 1] += f_end;
        }
    }
}

template<class DataTypes>
void ConstantForceField<DataTypes>::addKToMatrix(sofa::defaulttype::BaseMatrix * /* mat */, SReal /* k */, unsigned int & /* offset */)
{
}

template <class DataTypes>
double ConstantForceField<DataTypes>::getPotentialEnergy(const core::MechanicalParams* /*params*/ /* PARAMS FIRST */, const DataVecCoord& x) const
{
    const VecIndex& indices = points.getValue();
    const VecDeriv& f = forces.getValue();
    const VecCoord& _x = x.getValue();
    const Deriv f_end = (f.empty()? force.getValue() : f[f.size()-1]);
    double e = 0;
    unsigned int i = 0;

    if (!indexFromEnd.getValue())
    {
        for (; i<f.size(); i++)
        {
            e -= f[i] * _x[indices[i]];
        }
        for (; i<indices.size(); i++)
        {
            e -= f_end * _x[indices[i]];
        }
    }
    else
    {
        for (; i < f.size(); i++)
        {
            e -= f[i] * _x[_x.size() - indices[i] -1];
        }
        for (; i < indices.size(); i++)
        {
            e -= f_end * _x[_x.size() - indices[i] -1];
        }
    }

    return e;
}

template <class DataTypes>
void ConstantForceField<DataTypes>::setForce(unsigned i, const Deriv& force)
{
    VecIndex& indices = *points.beginEdit();
    VecDeriv& f = *forces.beginEdit();
    indices.push_back(i);
    f.push_back( force );
    points.endEdit();
    forces.endEdit();
}

template<class DataTypes>
void ConstantForceField<DataTypes>::draw(const core::visual::VisualParams* vparams)
{
#ifndef SOFA_NO_OPENGL
    double aSC = arrowSizeCoef.getValue();

    Deriv singleForce;
    if (totalForce.getValue()*totalForce.getValue() > 0.0)
    {
        for (unsigned comp = 0; comp < totalForce.getValue().size(); comp++)
            singleForce[comp] = (totalForce.getValue()[comp])/(Real(points.getValue().size()));
    }
    else if (force.getValue() * force.getValue() > 0.0)
    {
        singleForce = force.getValue();
    }

    if ((!vparams->displayFlags().getShowForceFields() && (aSC==0)) || (aSC < 0.0)) return;
    const VecIndex& indices = points.getValue();
    const VecDeriv& f = forces.getValue();
    const Deriv f_end = (f.empty()? singleForce : f[f.size()-1]);
    const VecCoord& x = *this->mstate->getX();

    if( fabs(aSC)<1.0e-10 )
    {
        std::vector<defaulttype::Vector3> points;
        for (unsigned int i=0; i<indices.size(); i++)
        {
            Real xx,xy,xz,fx,fy,fz;

            if (!indexFromEnd.getValue())
            {
                DataTypes::get(xx,xy,xz,x[indices[i]]);
            }
            else
            {
                DataTypes::get(xx,xy,xz,x[x.size() - indices[i] - 1]);
            }

            DataTypes::get(fx,fy,fz,(i<f.size())? f[i] : f_end);
            points.push_back(defaulttype::Vector3(xx, xy, xz ));
            points.push_back(defaulttype::Vector3(xx+fx, xy+fy, xz+fz ));
        }
        vparams->drawTool()->drawLines(points, 2, defaulttype::Vec<4,float>(0,1,0,1));
    }
    else
    {
        glPushAttrib(GL_LIGHTING_BIT);
        glEnable(GL_LIGHTING);
        for (unsigned int i=0; i<indices.size(); i++)
        {
            Real xx,xy,xz,fx,fy,fz;

            if (!indexFromEnd.getValue())
            {
                DataTypes::get(xx,xy,xz,x[indices[i]]);
            }
            else
            {
                DataTypes::get(xx,xy,xz,x[x.size() - indices[i] - 1]);
            }

            DataTypes::get(fx,fy,fz,(i<f.size())? f[i] : f_end);

            defaulttype::Vector3 p1( xx, xy, xz);
            defaulttype::Vector3 p2( aSC*fx+xx, aSC*fy+xy, aSC*fz+xz );

            float norm = (float)(p2-p1).norm();

//            static const defaulttype::Vec<4,float> color(1.0f,0.4f,0.4f,1.0f);
            static const defaulttype::Vec<4,float> color(0.2,0.9,0.3,1.0f);

            if( aSC > 0)
            {
                //helper::gl::drawArrow(p1,p2, norm/20.0);
                vparams->drawTool()->drawArrow(p1,p2, norm/20.0f, color);
            }
            else
            {
                //helper::gl::drawArrow(p2,p1, norm/20.0);
                vparams->drawTool()->drawArrow(p2,p1, norm/20.0f, color);
            }
        }
        glPopAttrib();
    }

#endif /* SOFA_NO_OPENGL */
}

} // namespace forcefield

} // namespace component

} // namespace sofa

#endif // SOFA_COMPONENT_FORCEFIELD_CONSTANTFORCEFIELD_INL

<commit_msg>FIX ConstantForceField for some use cases.<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_FORCEFIELD_CONSTANTFORCEFIELD_INL
#define SOFA_COMPONENT_FORCEFIELD_CONSTANTFORCEFIELD_INL

#include <sofa/component/forcefield/ConstantForceField.h>
#include <sofa/helper/system/config.h>
#include <sofa/helper/gl/template.h>
#include <assert.h>
#include <iostream>
//#include <sofa/helper/gl/BasicShapes.h>
#include <sofa/simulation/common/Simulation.h>
#include <sofa/core/behavior/ForceField.inl>
#include <sofa/core/visual/VisualParams.h>
#include <sofa/component/topology/TopologySubsetData.inl>

namespace sofa
{

namespace component
{

namespace forcefield
{

template<class DataTypes>
ConstantForceField<DataTypes>::ConstantForceField()
    : points(initData(&points, "points", "points where the forces are applied"))
    , forces(initData(&forces, "forces", "applied forces at each point"))
    , force(initData(&force, "force", "applied force to all points if forces attribute is not specified"))
    , totalForce(initData(&totalForce, "totalForce", "total force for all points, will be distributed uniformly over points"))
    , arrowSizeCoef(initData(&arrowSizeCoef,0.0, "arrowSizeCoef", "Size of the drawn arrows (0->no arrows, sign->direction of drawing"))
    , indexFromEnd(initData(&indexFromEnd,(bool)false,"indexFromEnd", "Concerned DOFs indices are numbered from the end of the MState DOFs vector"))
{
}

template<class DataTypes>
void ConstantForceField<DataTypes>::init()
{
    topology = this->getContext()->getMeshTopology();

    // Initialize functions and parameters for topology data and handler
    points.createTopologicalEngine(topology);
    points.registerTopologicalData();

    Inherit::init();
}

template<class DataTypes>
void ConstantForceField<DataTypes>::addForce(const core::MechanicalParams* /*params*/ /* PARAMS FIRST */, DataVecDeriv& f1, const DataVecCoord& p1, const DataVecDeriv&)
{
    sofa::helper::WriteAccessor< core::objectmodel::Data< VecDeriv > > _f1 = f1;
    _f1.resize(p1.getValue().size());

    Deriv singleForce;
    const Deriv& forceVal = force.getValue();
    const Deriv& totalForceVal = totalForce.getValue();
    const VecIndex& indices = points.getValue();
    const VecDeriv& f = forces.getValue();
    unsigned int i = 0, nbForcesIn = f.size(), nbForcesOut = _f1.size();

    if (totalForceVal * totalForceVal > 0)
    {
        unsigned int nbForces = indices.empty() ? nbForcesOut : indices.size();
        singleForce = totalForceVal / (Real)nbForces;
    }
    else if (forceVal * forceVal > 0.0)
        singleForce = forceVal;

    const Deriv f_end = (f.empty() ? singleForce : f.back());

    // When no indices are given, copy the forces from the start
    if (indices.empty())
    {
        unsigned int nbCopy = std::min(nbForcesIn, nbForcesOut);
        for (; i < nbCopy; ++i) // Copy from the forces list
            _f1[i] += f[i];
        for (; i < nbForcesOut; ++i) // Copy from the single value or the last value of the forces list
            _f1[i] += f_end;
    }
    else
    {
        unsigned int nbIndices = indices.size();
        unsigned int nbCopy = std::min(nbForcesIn, nbIndices); // forces & points are not garanteed to be of the same size
        if (!indexFromEnd.getValue())
        {
            for (; i < nbCopy; ++i)
                _f1[indices[i]] += f[i];
            for (; i < nbIndices; ++i)
                _f1[indices[i]] += f_end;
        }
        else
        {
            for (; i < nbCopy; ++i)
                _f1[nbForcesOut - indices[i] - 1] += f[i];
            for (; i < nbIndices; ++i)
                _f1[nbForcesOut - indices[i] - 1] += f_end;
        }
    }
}

template<class DataTypes>
void ConstantForceField<DataTypes>::addKToMatrix(sofa::defaulttype::BaseMatrix * /* mat */, SReal /* k */, unsigned int & /* offset */)
{
}

template <class DataTypes>
double ConstantForceField<DataTypes>::getPotentialEnergy(const core::MechanicalParams* /*params*/ /* PARAMS FIRST */, const DataVecCoord& x) const
{
    const VecIndex& indices = points.getValue();
    const VecDeriv& f = forces.getValue();
    const VecCoord& _x = x.getValue();
    const Deriv f_end = (f.empty()? force.getValue() : f[f.size()-1]);
    double e = 0;
    unsigned int i = 0;

    if (!indexFromEnd.getValue())
    {
        for (; i<f.size(); i++)
        {
            e -= f[i] * _x[indices[i]];
        }
        for (; i<indices.size(); i++)
        {
            e -= f_end * _x[indices[i]];
        }
    }
    else
    {
        for (; i < f.size(); i++)
        {
            e -= f[i] * _x[_x.size() - indices[i] -1];
        }
        for (; i < indices.size(); i++)
        {
            e -= f_end * _x[_x.size() - indices[i] -1];
        }
    }

    return e;
}

template <class DataTypes>
void ConstantForceField<DataTypes>::setForce(unsigned i, const Deriv& force)
{
    VecIndex& indices = *points.beginEdit();
    VecDeriv& f = *forces.beginEdit();
    indices.push_back(i);
    f.push_back( force );
    points.endEdit();
    forces.endEdit();
}

template<class DataTypes>
void ConstantForceField<DataTypes>::draw(const core::visual::VisualParams* vparams)
{
#ifndef SOFA_NO_OPENGL
    double aSC = arrowSizeCoef.getValue();

    Deriv singleForce;
    if (totalForce.getValue()*totalForce.getValue() > 0.0)
    {
        for (unsigned comp = 0; comp < totalForce.getValue().size(); comp++)
            singleForce[comp] = (totalForce.getValue()[comp])/(Real(points.getValue().size()));
    }
    else if (force.getValue() * force.getValue() > 0.0)
    {
        singleForce = force.getValue();
    }

    if ((!vparams->displayFlags().getShowForceFields() && (aSC==0)) || (aSC < 0.0)) return;
    const VecIndex& indices = points.getValue();
    const VecDeriv& f = forces.getValue();
    const Deriv f_end = (f.empty()? singleForce : f[f.size()-1]);
    const VecCoord& x = *this->mstate->getX();

    if( fabs(aSC)<1.0e-10 )
    {
        std::vector<defaulttype::Vector3> points;
        for (unsigned int i=0; i<indices.size(); i++)
        {
            Real xx,xy,xz,fx,fy,fz;

            if (!indexFromEnd.getValue())
            {
                DataTypes::get(xx,xy,xz,x[indices[i]]);
            }
            else
            {
                DataTypes::get(xx,xy,xz,x[x.size() - indices[i] - 1]);
            }

            DataTypes::get(fx,fy,fz,(i<f.size())? f[i] : f_end);
            points.push_back(defaulttype::Vector3(xx, xy, xz ));
            points.push_back(defaulttype::Vector3(xx+fx, xy+fy, xz+fz ));
        }
        vparams->drawTool()->drawLines(points, 2, defaulttype::Vec<4,float>(0,1,0,1));
    }
    else
    {
        glPushAttrib(GL_LIGHTING_BIT);
        glEnable(GL_LIGHTING);
        for (unsigned int i=0; i<indices.size(); i++)
        {
            Real xx,xy,xz,fx,fy,fz;

            if (!indexFromEnd.getValue())
            {
                DataTypes::get(xx,xy,xz,x[indices[i]]);
            }
            else
            {
                DataTypes::get(xx,xy,xz,x[x.size() - indices[i] - 1]);
            }

            DataTypes::get(fx,fy,fz,(i<f.size())? f[i] : f_end);

            defaulttype::Vector3 p1( xx, xy, xz);
            defaulttype::Vector3 p2( aSC*fx+xx, aSC*fy+xy, aSC*fz+xz );

            float norm = (float)(p2-p1).norm();

            static const defaulttype::Vec<4,float> color(0.2f,0.9f,0.3f,1.0f);

            if( aSC > 0)
            {
                //helper::gl::drawArrow(p1,p2, norm/20.0);
                vparams->drawTool()->drawArrow(p1,p2, norm/20.0f, color);
            }
            else
            {
                //helper::gl::drawArrow(p2,p1, norm/20.0);
                vparams->drawTool()->drawArrow(p2,p1, norm/20.0f, color);
            }
        }
        glPopAttrib();
    }

#endif /* SOFA_NO_OPENGL */
}

} // namespace forcefield

} // namespace component

} // namespace sofa

#endif // SOFA_COMPONENT_FORCEFIELD_CONSTANTFORCEFIELD_INL

<|endoftext|>


<commit_before>/*
 * MovementReader.hpp
 *
 *  Created on: Mar 16, 2013
 *      Author: link
 */

#ifndef MOVEMENTREADER_HPP_
#define MOVEMENTREADER_HPP_

#include <vector>
#include <list>

#include <opencv2/core/core.hpp>

#include "FeatureExtractor.hpp"
#include "FeatureTracker.hpp"
#include "FeatureFilter.hpp"

class MovementReader {
    protected:
        std::vector<std::list<cv::Point2f> > _trackedFeatures;
        FeatureTracker *_tracker;
        FeatureExtractor *_extractor;
        std::list<FeatureFilter*> _filters;
        unsigned int _maxFeatures;
        cv::Mat _oldFrame;
        MovementReader(const FeatureTracker &tracker,
                const FeatureExtractor &extractor,
                const std::list<FeatureFilter*> &filters,
                const unsigned int &maxFeatures,
                const std::vector<std::list<cv::Point2f> > &trackedFeatures =
                        std::vector<std::list<cv::Point2f> >());
        MovementReader(const MovementReader &toCopy);
    public:
        MovementReader();
        std::vector<std::list<cv::Point2f> > getTrackedFeatures() const;
        void refillFeatures(const int &maxFeatures);
        virtual ~MovementReader();
};

#endif /* MOVEMENTREADER_HPP_ */
<commit_msg>Added doxygen documentation to MovementReader.hpp<commit_after>/**
 * \file MovementReader.hpp
 *
 * \date 16.03.2013
 * \author Michał Orynicz
 */

#ifndef MOVEMENTREADER_HPP_
#define MOVEMENTREADER_HPP_

#include <vector>
#include <list>

#include <opencv2/core/core.hpp>

#include "FeatureExtractor.hpp"
#include "FeatureTracker.hpp"
#include "FeatureFilter.hpp"

/**
 * Base class for objects reading position changes of the camera
 * based on image from it.
 */
class MovementReader {
    protected:
        /// Features tracked
        std::vector<std::list<cv::Point2f> > _trackedFeatures;
        FeatureTracker *_tracker; ///<Feature tracker
        FeatureExtractor *_extractor; ///<Feature extractor
        std::list<FeatureFilter*> _filters; ///<List of feature filters
        ///Upper limit on number of features to track
        unsigned int _maxFeatures;
        cv::Mat _oldFrame;        ///<Previous frame
        ///Constructor
        /**
         * Constructor
         * @param tracker - feature tracker
         * @param extractor - feature extractor
         * @param filters - list of feature filter pointers
         * @param maxFeatures - upper limit for number of tracked features
         * @param trackedFeatures - tracked features
         */
        MovementReader(const FeatureTracker &tracker,
                const FeatureExtractor &extractor,
                const std::list<FeatureFilter*> &filters,
                const unsigned int &maxFeatures,
                const std::vector<std::list<cv::Point2f> > &trackedFeatures =
                        std::vector<std::list<cv::Point2f> >());
        ///Deep copy constructor
        /**
         * Deep copy constructor
         * @param toCopy - object to initialize with
         */
        MovementReader(const MovementReader &toCopy);
    public:
        ///Default constructor
        MovementReader();
        /// Getter method for tracked features
        /**
         * Getter method for tracked features
         * @return Tracked features container
         */
        std::vector<std::list<cv::Point2f> > getTrackedFeatures() const;
        /// Complement missing features up to maxFeatures
        /**
         * Complement the collection of tracked features so it contains
         * up to maxFeatures of features.
         * @param maxFeatures Upper limit for number of features tracked
         */
        void refillFeatures(const int &maxFeatures);
        ///Destructor
        virtual ~MovementReader();
};

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


<commit_before>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2014 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  support/hasher.inl                                                              */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

#if !defined(UKACHULLDCS_08961_SUPPORT_HASHER_INL)

#define UKACHULLDCS_08961_SUPPORT_HASHER_INL

// includes, system

#include <boost/functional/hash.hpp> // boost::hash_value<>
#include <functional>                // std::hash<>

// includes, project

#include <>

namespace std {

  // functions, inlined (inline)

  template <typename T1, typename T2>
  inline std::size_t
  hash<std::pair<T1, T2>>::operator()(std::pair<T1, T2> const& a) const
  {
    return boost::hash_value(a);
  }

#if (defined(_MSC_VER) && (_MSC_VER <= 1700))
  template <>
  inline std::size_t
  hash<std::string const>::operator()(std::string const& a) const
  {
    return hash<std::string>()(a);
  }
#endif

} // namespace std {

#endif // #if !defined(UKACHULLDCS_08961_SUPPORT_HASHER_INL)
<commit_msg>fixed: typo<commit_after>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2014 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  support/hasher.inl                                                              */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

#if !defined(UKACHULLDCS_08961_SUPPORT_HASHER_INL)

#define UKACHULLDCS_08961_SUPPORT_HASHER_INL

// includes, system

#include <boost/functional/hash.hpp> // boost::hash_value<>
#include <functional>                // std::hash<>

// includes, project

//#include <>

namespace std {

  // functions, inlined (inline)

  template <typename T1, typename T2>
  inline std::size_t
  hash<std::pair<T1, T2>>::operator()(std::pair<T1, T2> const& a) const
  {
    return boost::hash_value(a);
  }

#if (defined(_MSC_VER) && (_MSC_VER <= 1700))
  template <>
  inline std::size_t
  hash<std::string const>::operator()(std::string const& a) const
  {
    return hash<std::string>()(a);
  }
#endif

} // namespace std {

#endif // #if !defined(UKACHULLDCS_08961_SUPPORT_HASHER_INL)
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <fstream>
#include <cstdint>

using namespace std;

template <typename T>
struct Node {
	Node *left;
	Node *right;
	T data;
};

template <typename T>
class BinaryTree
{
private:
	Node<T>* root;
	int CountElements = 0;

public:
	BinaryTree();
	~BinaryTree();
	BinaryTree(const std::initializer_list<T>&);
	unsigned int count() const;
	void insert_node(const T&x);
	Node<T> *find_node(const T&, Node<T>*)const;
	void deleteNode(Node<T>* temp);
	void writing(const std::string& filename)const;
	void output(std::ostream& ost, const Node<T>* temp);
	friend std::ostream& operator<< <> (std::ostream&, const BinaryTree<T>&);

};

template <typename T>
BinaryTree<T>::BinaryTree()
{
	root = nullptr;
}

template<typename T>
Node<T>* BinaryTree<T>::root_()
{
	return root;
}

template <typename T>
BinaryTree<T>::~BinaryTree()
{
	deleteNode(root);
}

template<typename T>
void BinaryTree<T>::insert_node(const T&x)
{
	if (find_node(x, root_())) return;
	Node<T>* MyTree = new Node<T>;
	MyTree->data = x;
	MyTree->left = MyTree->right = 0;
	Node<T>* buff = root;
	Node<T>* temp = root;
	while (temp)
	{
		buff = temp;
		if (x < temp->data)
			temp = temp->left;
		else
			temp = temp->right;
	}
	if (!buff)
		root = MyTree;
	else
	{
		if (x < buff->data)
			buff->left = MyTree;
		else
			buff->right = MyTree;
	}
	++CountElements;
}

template<typename T>
Node<T>* BinaryTree<T>::find_node(const T& value, Node<T>* temp) const
{
	if (temp == 0 || value == temp->data)
		return temp;
	if (value > temp->data)
		return find_node(value, temp->right);
	else
		return find_node(value, temp->left);
}

template <typename T>
void BinaryTree<T>::_deleteElements(Node<T>* temp)
{
	if (!temp)
	{
		throw "error";
	}
	_deleteElements(temp->left);
	_deleteElements(temp->right);
	delete node;
}

template<typename T>
void BinaryTree<T>::deleteNode(Node<T>* temp)
{
	if (!temp)
	{
		throw "error";
	}
	if (temp->left)
	{
		deleteNode(temp->left);
		temp->left = nullptr;
	}

	if (temp->right)
	{
		deleteNode(temp->right);
		temp->right = nullptr;
	}
	delete temp;
}

template<typename T>
void BinaryTree<T>::output(std::ostream& ost, const Node<T>* temp)
{
	if (temp == nullptr)
	{
		throw "error";
		return;
	}
	else
	{
		ost << temp->data << "	";
		output(ost, temp->left);
		output(ost, temp->right);
	}
}

template<typename T>
void BinaryTree<T>::writing(const std::string& filename)const
{
	ofstream file_1(filename);
	file_1 << CountElements << "\t";
	output(file_1, root);
	file_1.close();
}

template <typename T>
std::ostream& show(std::ostream& ost, const Node<T>* node, unsigned int level)
{
	if (!node)
		return ost;
	show(ost, node->right, level + 1);
	for (unsigned int i = 0; i < level; i++)
		ost << "\t";
	ost << node->data << std::endl;
	show(ost, node->left, level + 1);
	return ost;
}

template <typename T>
std::ostream& operator<<(std::ostream& ost, const BinaryTree<T>& temp)
{
	if (!temp.root)
		throw "error";
	show(ost, temp.root, 0);
	return ost;
}
<commit_msg>Update BinaryTree.hpp<commit_after>#include <iostream>
#include <string>
#include <fstream>
#include <cstdint>

using namespace std;

template <typename T>
struct Node {
	Node *left;
	Node *right;
	T data;
};

template <typename T>
class BinaryTree
{
private:
	Node<T>* root;
	int CountElements = 0;

public:
	BinaryTree();
	~BinaryTree();
	BinaryTree(const std::initializer_list<T>&);
	unsigned int count() const;
	void insert_node(const T&x);
	Node<T>* root_();
	Node<T> *find_node(const T&, Node<T>*)const;
	void deleteNode(Node<T>* temp);
	void writing(const std::string& filename)const;
	void output(std::ostream& ost, const Node<T>* temp);
	friend std::ostream& operator<< <> (std::ostream&, const BinaryTree<T>&);

};

template <typename T>
BinaryTree<T>::BinaryTree()
{
	root = nullptr;
}

template<typename T>
Node<T>* BinaryTree<T>::root_()
{
	return root;
}

template <typename T>
BinaryTree<T>::~BinaryTree()
{
	deleteNode(root);
}

template<typename T>
void BinaryTree<T>::insert_node(const T&x)
{
	if (find_node(x, root_())) return;
	Node<T>* MyTree = new Node<T>;
	MyTree->data = x;
	MyTree->left = MyTree->right = 0;
	Node<T>* buff = root;
	Node<T>* temp = root;
	while (temp)
	{
		buff = temp;
		if (x < temp->data)
			temp = temp->left;
		else
			temp = temp->right;
	}
	if (!buff)
		root = MyTree;
	else
	{
		if (x < buff->data)
			buff->left = MyTree;
		else
			buff->right = MyTree;
	}
	++CountElements;
}

template<typename T>
Node<T>* BinaryTree<T>::find_node(const T& value, Node<T>* temp) const
{
	if (temp == 0 || value == temp->data)
		return temp;
	if (value > temp->data)
		return find_node(value, temp->right);
	else
		return find_node(value, temp->left);
}

template<typename T>
void BinaryTree<T>::output(std::ostream& ost, const Node<T>* temp)
{
	if (temp == nullptr)
	{
		throw "error";
		return;
	}
	else
	{
		ost << temp->data << "	";
		output(ost, temp->left);
		output(ost, temp->right);
	}
}

template<typename T>
void BinaryTree<T>::writing(const std::string& filename)const
{
	ofstream file_1(filename);
	file_1 << CountElements << "\t";
	output(file_1, root);
	file_1.close();
}

template <typename T>
std::ostream& show(std::ostream& ost, const Node<T>* node, unsigned int level)
{
	if (!node)
		return ost;
	show(ost, node->right, level + 1);
	for (unsigned int i = 0; i < level; i++)
		ost << "\t";
	ost << node->data << std::endl;
	show(ost, node->left, level + 1);
	return ost;
}

template <typename T>
std::ostream& operator<<(std::ostream& ost, const BinaryTree<T>& temp)
{
	if (!temp.root)
		throw "error";
	show(ost, temp.root, 0);
	return ost;
}
<|endoftext|>


<commit_before>/*
 * EntityUtil.hpp
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Ashley Davis
 *
 * 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.
 */
#ifndef INCLUDE_ENTITYUTIL_HPP_
#define INCLUDE_ENTITYUTIL_HPP_

namespace ashley {
class Engine;
class Entity;
}

namespace rgl {
class Item;

class EntityUtil {
public:
	static ashley::Entity *generateTigerEntity(ashley::Engine &engine, int x, int y);

	static ashley::Entity *generateChestEntity(ashley::Engine &engine, int x, int y, const Item &item);
};

}

#endif /* INCLUDE_ENTITYUTIL_HPP_ */
<commit_msg>Add sabretooth prototype<commit_after>/*
 * EntityUtil.hpp
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Ashley Davis
 *
 * 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.
 */
#ifndef INCLUDE_ENTITYUTIL_HPP_
#define INCLUDE_ENTITYUTIL_HPP_

namespace ashley {
class Engine;
class Entity;
}

namespace rgl {
class Item;

class EntityUtil {
public:
	static ashley::Entity *generateTigerEntity(ashley::Engine &engine, int x, int y);

	static ashley::Entity *generateChestEntity(ashley::Engine &engine, int x, int y, const Item &item);

	static ashley::Entity *generateSabretoothEntity(ashley::Engine &engine, int x, int y);
};

}

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


<commit_before>#pragma once

#include <cairo/cairo-ft.h>

#include "cairo/types.hpp"
#include "cairo/utils.hpp"
#include "common.hpp"
#include "errors.hpp"
#include "settings.hpp"
#include "utils/math.hpp"
#include "utils/scope.hpp"
#include "utils/string.hpp"

POLYBAR_NS

namespace cairo {
  /**
   * \brief Global pointer to the Freetype library handler
   */
  static FT_Library g_ftlib;

  /**
   * \brief Abstract font face
   */
  class font {
   public:
    explicit font(cairo_t* cairo, double offset) : m_cairo(cairo), m_offset(offset) {}
    virtual ~font(){};

    virtual string name() const = 0;
    virtual string file() const = 0;
    virtual double offset() const = 0;
    virtual double size(double dpi) const = 0;

    virtual cairo_font_extents_t extents() = 0;

    virtual void use() {
      cairo_set_font_face(m_cairo, cairo_font_face_reference(m_font_face));
    }

    virtual size_t match(utils::unicode_character& character) = 0;
    virtual size_t match(utils::unicode_charlist& charlist) = 0;
    virtual size_t render(const string& text, double x = 0.0, double y = 0.0) = 0;
    virtual void textwidth(const string& text, cairo_text_extents_t* extents) = 0;

   protected:
    cairo_t* m_cairo;
    cairo_font_face_t* m_font_face{nullptr};
    cairo_font_extents_t m_extents{};
    double m_offset{0.0};
  };

  /**
   * \brief Font based on fontconfig/freetype
   */
  class font_fc : public font {
   public:
    explicit font_fc(cairo_t* cairo, FcPattern* pattern, double offset, double dpi_x, double dpi_y) : font(cairo, offset), m_pattern(pattern) {
      cairo_matrix_t fm;
      cairo_matrix_t ctm;
      cairo_matrix_init_scale(&fm, size(dpi_x), size(dpi_y));
      cairo_get_matrix(m_cairo, &ctm);

      auto fontface = cairo_ft_font_face_create_for_pattern(m_pattern);
      auto opts = cairo_font_options_create();
      m_scaled = cairo_scaled_font_create(fontface, &fm, &ctm, opts);
      cairo_font_options_destroy(opts);
      cairo_font_face_destroy(fontface);

      auto status = cairo_scaled_font_status(m_scaled);
      if (status != CAIRO_STATUS_SUCCESS) {
        throw application_error(sstream() << "cairo_scaled_font_create(): " << cairo_status_to_string(status));
      }

      auto lock = make_unique<utils::ft_face_lock>(m_scaled);
      auto face = static_cast<FT_Face>(*lock);

      if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) == FT_Err_Ok) {
        return;
      } else if (FT_Select_Charmap(face, FT_ENCODING_BIG5) == FT_Err_Ok) {
        return;
      } else if (FT_Select_Charmap(face, FT_ENCODING_SJIS) == FT_Err_Ok) {
        return;
      }

      lock.reset();
    }

    ~font_fc() override {
      if (m_scaled != nullptr) {
        cairo_scaled_font_destroy(m_scaled);
      }
      if (m_pattern != nullptr) {
        FcPatternDestroy(m_pattern);
      }
    }

    cairo_font_extents_t extents() override {
      cairo_scaled_font_extents(m_scaled, &m_extents);
      return m_extents;
    }

    string name() const override {
      return property("family");
    }

    string file() const override {
      return property("file");
    }

    double offset() const override {
      return m_offset;
    }

    double size(double dpi) const override {
      bool scalable;
      double px;
      property(FC_SCALABLE, &scalable);
      if (scalable) {
        // convert from pt to px using the provided dpi
        property(FC_SIZE, &px);
        px = static_cast<int>(px * dpi / 72.0 + 0.5);
      } else {
        property(FC_PIXEL_SIZE, &px);
        px = static_cast<int>(px + 0.5);
      }
      return px;
    }

    void use() override {
      cairo_set_scaled_font(m_cairo, m_scaled);
    }

    size_t match(utils::unicode_character& character) override {
      auto lock = make_unique<utils::ft_face_lock>(m_scaled);
      auto face = static_cast<FT_Face>(*lock);
      return FT_Get_Char_Index(face, character.codepoint) ? 1 : 0;
    }

    size_t match(utils::unicode_charlist& charlist) override {
      auto lock = make_unique<utils::ft_face_lock>(m_scaled);
      auto face = static_cast<FT_Face>(*lock);
      size_t available_chars = 0;
      for (auto&& c : charlist) {
        if (FT_Get_Char_Index(face, c.codepoint)) {
          available_chars++;
        } else {
          break;
        }
      }

      return available_chars;
    }

    size_t render(const string& text, double x = 0.0, double y = 0.0) override {
      cairo_glyph_t* glyphs{nullptr};
      cairo_text_cluster_t* clusters{nullptr};
      cairo_text_cluster_flags_t cf{};
      int nglyphs = 0, nclusters = 0;

      string utf8 = string(text);
      auto status = cairo_scaled_font_text_to_glyphs(
          m_scaled, x, y, utf8.c_str(), utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf);

      if (status != CAIRO_STATUS_SUCCESS) {
        throw application_error(sstream() << "cairo_scaled_font_text_to_glyphs()" << cairo_status_to_string(status));
      }

      size_t bytes = 0;
      for (int g = 0; g < nglyphs; g++) {
        if (glyphs[g].index) {
          bytes += clusters[g].num_bytes;
        } else {
          break;
        }
      }

      if (bytes && bytes < text.size()) {
        cairo_glyph_free(glyphs);
        cairo_text_cluster_free(clusters);

        utf8 = text.substr(0, bytes);
        auto status = cairo_scaled_font_text_to_glyphs(
            m_scaled, x, y, utf8.c_str(), utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf);

        if (status != CAIRO_STATUS_SUCCESS) {
          throw application_error(sstream() << "cairo_scaled_font_text_to_glyphs()" << cairo_status_to_string(status));
        }
      }

      if (bytes) {
        // auto lock = make_unique<utils::device_lock>(cairo_surface_get_device(cairo_get_target(m_cairo)));
        // if (lock.get()) {
        //   cairo_glyph_path(m_cairo, glyphs, nglyphs);
        // }

        cairo_text_extents_t extents{};
        cairo_scaled_font_glyph_extents(m_scaled, glyphs, nglyphs, &extents);
        cairo_show_text_glyphs(m_cairo, utf8.c_str(), utf8.size(), glyphs, nglyphs, clusters, nclusters, cf);
        cairo_fill(m_cairo);
        cairo_move_to(m_cairo, x + extents.x_advance, 0.0);
      }

      cairo_glyph_free(glyphs);
      cairo_text_cluster_free(clusters);

      return bytes;
    }

    void textwidth(const string& text, cairo_text_extents_t* extents) override {
      cairo_scaled_font_text_extents(m_scaled, text.c_str(), extents);
    }

   protected:
    string property(string&& property) const {
      FcChar8* file;
      if (FcPatternGetString(m_pattern, property.c_str(), 0, &file) == FcResultMatch) {
        return string(reinterpret_cast<char*>(file));
      } else {
        return "";
      }
    }

    void property(string&& property, bool* dst) const {
      FcBool b;
      FcPatternGetBool(m_pattern, property.c_str(), 0, &b);
      *dst = b;
    }

    void property(string&& property, double* dst) const {
      FcPatternGetDouble(m_pattern, property.c_str(), 0, dst);
    }

    void property(string&& property, int* dst) const {
      FcPatternGetInteger(m_pattern, property.c_str(), 0, dst);
    }

   private:
    cairo_scaled_font_t* m_scaled{nullptr};
    FcPattern* m_pattern{nullptr};
  };

  /**
   * Match and create font from given fontconfig pattern
   */
  inline decltype(auto) make_font(cairo_t* cairo, string&& fontname, double offset, double dpi_x, double dpi_y) {
    static bool fc_init{false};
    if (!fc_init && !(fc_init = FcInit())) {
      throw application_error("Could not load fontconfig");
    } else if (FT_Init_FreeType(&g_ftlib) != FT_Err_Ok) {
      throw application_error("Could not load FreeType");
    }

    static auto fc_cleanup = scope_util::make_exit_handler([] {
      FT_Done_FreeType(g_ftlib);
      FcFini();
    });

    auto pattern = FcNameParse((FcChar8*)fontname.c_str());

    if(!pattern) {
      logger::make().err("Could not parse font \"%s\"", fontname);
      throw application_error("Could not parse font \"" + fontname + "\"");
    }

    FcDefaultSubstitute(pattern);
    FcConfigSubstitute(nullptr, pattern, FcMatchPattern);

    FcResult result;
    FcPattern* match = FcFontMatch(nullptr, pattern, &result);
    FcPatternDestroy(pattern);

    if (match == nullptr) {
      throw application_error("Could not load font \"" + fontname + "\"");
    }

#ifdef DEBUG_FONTCONFIG
    FcPatternPrint(match);
#endif

    return make_shared<font_fc>(cairo, match, offset, dpi_x, dpi_y);
  }
}

POLYBAR_NS_END
<commit_msg>refactor(font): More robust font size calculation<commit_after>#pragma once

#include <cairo/cairo-ft.h>

#include "cairo/types.hpp"
#include "cairo/utils.hpp"
#include "common.hpp"
#include "errors.hpp"
#include "settings.hpp"
#include "utils/math.hpp"
#include "utils/scope.hpp"
#include "utils/string.hpp"

POLYBAR_NS

namespace cairo {
  /**
   * \brief Global pointer to the Freetype library handler
   */
  static FT_Library g_ftlib;

  /**
   * \brief Abstract font face
   */
  class font {
   public:
    explicit font(cairo_t* cairo, double offset) : m_cairo(cairo), m_offset(offset) {}
    virtual ~font(){};

    virtual string name() const = 0;
    virtual string file() const = 0;
    virtual double offset() const = 0;
    virtual double size(double dpi) const = 0;

    virtual cairo_font_extents_t extents() = 0;

    virtual void use() {
      cairo_set_font_face(m_cairo, cairo_font_face_reference(m_font_face));
    }

    virtual size_t match(utils::unicode_character& character) = 0;
    virtual size_t match(utils::unicode_charlist& charlist) = 0;
    virtual size_t render(const string& text, double x = 0.0, double y = 0.0) = 0;
    virtual void textwidth(const string& text, cairo_text_extents_t* extents) = 0;

   protected:
    cairo_t* m_cairo;
    cairo_font_face_t* m_font_face{nullptr};
    cairo_font_extents_t m_extents{};
    double m_offset{0.0};
  };

  /**
   * \brief Font based on fontconfig/freetype
   */
  class font_fc : public font {
   public:
    explicit font_fc(cairo_t* cairo, FcPattern* pattern, double offset, double dpi_x, double dpi_y) : font(cairo, offset), m_pattern(pattern) {
      cairo_matrix_t fm;
      cairo_matrix_t ctm;
      cairo_matrix_init_scale(&fm, size(dpi_x), size(dpi_y));
      cairo_get_matrix(m_cairo, &ctm);

      auto fontface = cairo_ft_font_face_create_for_pattern(m_pattern);
      auto opts = cairo_font_options_create();
      m_scaled = cairo_scaled_font_create(fontface, &fm, &ctm, opts);
      cairo_font_options_destroy(opts);
      cairo_font_face_destroy(fontface);

      auto status = cairo_scaled_font_status(m_scaled);
      if (status != CAIRO_STATUS_SUCCESS) {
        throw application_error(sstream() << "cairo_scaled_font_create(): " << cairo_status_to_string(status));
      }

      auto lock = make_unique<utils::ft_face_lock>(m_scaled);
      auto face = static_cast<FT_Face>(*lock);

      if (FT_Select_Charmap(face, FT_ENCODING_UNICODE) == FT_Err_Ok) {
        return;
      } else if (FT_Select_Charmap(face, FT_ENCODING_BIG5) == FT_Err_Ok) {
        return;
      } else if (FT_Select_Charmap(face, FT_ENCODING_SJIS) == FT_Err_Ok) {
        return;
      }

      lock.reset();
    }

    ~font_fc() override {
      if (m_scaled != nullptr) {
        cairo_scaled_font_destroy(m_scaled);
      }
      if (m_pattern != nullptr) {
        FcPatternDestroy(m_pattern);
      }
    }

    cairo_font_extents_t extents() override {
      cairo_scaled_font_extents(m_scaled, &m_extents);
      return m_extents;
    }

    string name() const override {
      return property("family");
    }

    string file() const override {
      return property("file");
    }

    double offset() const override {
      return m_offset;
    }

    /**
     * Calculates the font size in pixels for the given dpi
     *
     * We use the two font properties size and pixelsize. size is in points and
     * needs to be scaled with the given dpi. pixelsize is not scaled.
     *
     * If both size properties are 0, we fall back to a default value of 10
     * points for scalable fonts or 10 pixel for non-scalable ones. This should
     * only happen if both properties are purposefully set to 0
     *
     * For scalable fonts we try to use the size property scaled according to
     * the dpi.
     * For non-scalable fonts we try to use the pixelsize property as-is
     */
    double size(double dpi) const override {
      bool scalable;
      double fc_pixelsize = 0, fc_size = 0;

      property(FC_SCALABLE, &scalable);

      // Size in points
      property(FC_SIZE, &fc_size);

      // Size in pixels
      property(FC_PIXEL_SIZE, &fc_pixelsize);

      // Fall back to a default value if the size is 0
      double pixelsize = fc_pixelsize == 0? 10 : fc_pixelsize;
      double size = fc_size == 0? 10 : fc_size;

      // Font size in pixels if we use the pixelsize property
      int px_pixelsize = pixelsize + 0.5;

      /*
       * Font size in pixels if we use the size property. Since the size
       * specifies the font size in points, this is converted to pixels
       * according to the dpi given.
       * One point is 1/72 inches, thus this gives us the number of 'dots'
       * (or pixels) for this font
       */
      int px_size = size / 72.0 * dpi + 0.5;

      if (fc_size == 0 && fc_pixelsize == 0) {
        return scalable? px_size : px_pixelsize;
      }

      if (scalable) {
        /*
         * Use the point size if it's not 0. The pixelsize is only used if the
         * size property is 0 and pixelsize is not
         */
        if (fc_size != 0) {
          return px_size;
        }
        else {
          return px_pixelsize;
        }
      } else {
        /*
         * Non-scalable fonts do it the other way around, here the size
         * property is only used if pixelsize is 0 and size is not
         */
        if (fc_pixelsize != 0) {
          return px_pixelsize;
        }
        else {
          return px_size;
        }
      }
    }

    void use() override {
      cairo_set_scaled_font(m_cairo, m_scaled);
    }

    size_t match(utils::unicode_character& character) override {
      auto lock = make_unique<utils::ft_face_lock>(m_scaled);
      auto face = static_cast<FT_Face>(*lock);
      return FT_Get_Char_Index(face, character.codepoint) ? 1 : 0;
    }

    size_t match(utils::unicode_charlist& charlist) override {
      auto lock = make_unique<utils::ft_face_lock>(m_scaled);
      auto face = static_cast<FT_Face>(*lock);
      size_t available_chars = 0;
      for (auto&& c : charlist) {
        if (FT_Get_Char_Index(face, c.codepoint)) {
          available_chars++;
        } else {
          break;
        }
      }

      return available_chars;
    }

    size_t render(const string& text, double x = 0.0, double y = 0.0) override {
      cairo_glyph_t* glyphs{nullptr};
      cairo_text_cluster_t* clusters{nullptr};
      cairo_text_cluster_flags_t cf{};
      int nglyphs = 0, nclusters = 0;

      string utf8 = string(text);
      auto status = cairo_scaled_font_text_to_glyphs(
          m_scaled, x, y, utf8.c_str(), utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf);

      if (status != CAIRO_STATUS_SUCCESS) {
        throw application_error(sstream() << "cairo_scaled_font_text_to_glyphs()" << cairo_status_to_string(status));
      }

      size_t bytes = 0;
      for (int g = 0; g < nglyphs; g++) {
        if (glyphs[g].index) {
          bytes += clusters[g].num_bytes;
        } else {
          break;
        }
      }

      if (bytes && bytes < text.size()) {
        cairo_glyph_free(glyphs);
        cairo_text_cluster_free(clusters);

        utf8 = text.substr(0, bytes);
        auto status = cairo_scaled_font_text_to_glyphs(
            m_scaled, x, y, utf8.c_str(), utf8.size(), &glyphs, &nglyphs, &clusters, &nclusters, &cf);

        if (status != CAIRO_STATUS_SUCCESS) {
          throw application_error(sstream() << "cairo_scaled_font_text_to_glyphs()" << cairo_status_to_string(status));
        }
      }

      if (bytes) {
        // auto lock = make_unique<utils::device_lock>(cairo_surface_get_device(cairo_get_target(m_cairo)));
        // if (lock.get()) {
        //   cairo_glyph_path(m_cairo, glyphs, nglyphs);
        // }

        cairo_text_extents_t extents{};
        cairo_scaled_font_glyph_extents(m_scaled, glyphs, nglyphs, &extents);
        cairo_show_text_glyphs(m_cairo, utf8.c_str(), utf8.size(), glyphs, nglyphs, clusters, nclusters, cf);
        cairo_fill(m_cairo);
        cairo_move_to(m_cairo, x + extents.x_advance, 0.0);
      }

      cairo_glyph_free(glyphs);
      cairo_text_cluster_free(clusters);

      return bytes;
    }

    void textwidth(const string& text, cairo_text_extents_t* extents) override {
      cairo_scaled_font_text_extents(m_scaled, text.c_str(), extents);
    }

   protected:
    string property(string&& property) const {
      FcChar8* file;
      if (FcPatternGetString(m_pattern, property.c_str(), 0, &file) == FcResultMatch) {
        return string(reinterpret_cast<char*>(file));
      } else {
        return "";
      }
    }

    void property(string&& property, bool* dst) const {
      FcBool b;
      FcPatternGetBool(m_pattern, property.c_str(), 0, &b);
      *dst = b;
    }

    void property(string&& property, double* dst) const {
      FcPatternGetDouble(m_pattern, property.c_str(), 0, dst);
    }

    void property(string&& property, int* dst) const {
      FcPatternGetInteger(m_pattern, property.c_str(), 0, dst);
    }

   private:
    cairo_scaled_font_t* m_scaled{nullptr};
    FcPattern* m_pattern{nullptr};
  };

  /**
   * Match and create font from given fontconfig pattern
   */
  inline decltype(auto) make_font(cairo_t* cairo, string&& fontname, double offset, double dpi_x, double dpi_y) {
    static bool fc_init{false};
    if (!fc_init && !(fc_init = FcInit())) {
      throw application_error("Could not load fontconfig");
    } else if (FT_Init_FreeType(&g_ftlib) != FT_Err_Ok) {
      throw application_error("Could not load FreeType");
    }

    static auto fc_cleanup = scope_util::make_exit_handler([] {
      FT_Done_FreeType(g_ftlib);
      FcFini();
    });

    auto pattern = FcNameParse((FcChar8*)fontname.c_str());

    if(!pattern) {
      logger::make().err("Could not parse font \"%s\"", fontname);
      throw application_error("Could not parse font \"" + fontname + "\"");
    }

    FcDefaultSubstitute(pattern);
    FcConfigSubstitute(nullptr, pattern, FcMatchPattern);

    FcResult result;
    FcPattern* match = FcFontMatch(nullptr, pattern, &result);
    FcPatternDestroy(pattern);

    if (match == nullptr) {
      throw application_error("Could not load font \"" + fontname + "\"");
    }

#ifdef DEBUG_FONTCONFIG
    FcPatternPrint(match);
#endif

    return make_shared<font_fc>(cairo, match, offset, dpi_x, dpi_y);
  }
}

POLYBAR_NS_END
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef CPM_RANDOM_HPP
#define CPM_RANDOM_HPP

#include <random>

namespace cpm {

#ifndef CPM_FAST_RANDOMIZE

template<typename T>
void randomize_double(T& container){
    static std::random_device rd;
    static std::mt19937_64 rand_engine(rd());
    static std::uniform_real_distribution<double> real_distribution(-10000.0, 10000.0);
    static auto generator = std::bind(real_distribution, rand_engine);

    for(auto& v : container){
        v = generator();
    }
}

#else

template<typename T>
void randomize_double(T& container){
    static std::random_device rd;
    static std::mt19937_64 rand_engine(rd());
    static std::uniform_real_distribution<double> real_distribution(-10000.0, 10000.0);
    static auto generator = std::bind(real_distribution, rand_engine);

    auto a = generator();
    auto b = generator();
    auto c = generator();

    std::size_t i = 0;
    for(auto& v : container){
        v = a + (i * b) + (-i * c);
        ++i;
    }
}

#endif

inline void randomize(){}

template<typename T1, typename std::enable_if_t<std::is_convertible<double, typename T1::value_type>::value, int> = 42 >
void randomize(T1& container){
    randomize_double(container);
}

template<typename T1, typename... TT>
void randomize(T1& value, TT&... values){
    randomize(value);
    randomize(values...);
}

template<typename Tuple, std::size_t... I>
void randomize_each(Tuple& data, std::index_sequence<I...> /*indices*/){
    using cpm::randomize;
    randomize(std::get<I>(data)...);
}

} //end of namespace cpm

#endif //CPM_RANDOM_HPP
<commit_msg>Add support for parallel randomization<commit_after>//=======================================================================
// Copyright (c) 2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef CPM_RANDOM_HPP
#define CPM_RANDOM_HPP

#include <random>

#ifdef CPM_PARALLEL_RANDOMIZE
#include <thread>
#include <future>
#endif

namespace cpm {

#ifndef CPM_PARALLEL_THRESHOLD
#define CPM_PARALLEL_THRESHOLD 10000
#endif

#ifndef CPM_PARALLEL_THREADS
//We are assuming Hyper-Threading by default
#define CPM_PARALLEL_THREADS std::thread::hardware_concurrency() / 2
#endif

#ifdef CPM_PARALLEL_RANDOMIZE

#ifndef CPM_FAST_RANDOMIZE

template<typename T>
void randomize_double(T& container){
    if(container.size() > CPM_PARALLEL_THRESHOLD){
        const std::size_t n = CPM_PARALLEL_THREADS; //We are assuming Hyper-Threading
        const std::size_t p = container.size() / n;

        std::vector<std::future<void>> futures;

        for(std::size_t i = 0; i < n; ++i){
            futures.push_back(std::async(std::launch::async, [&](std::size_t ii){
                static std::random_device rd;
                static std::mt19937_64 rand_engine(rd());
                static std::uniform_real_distribution<double> real_distribution(-10000.0, 10000.0);
                static auto generator = std::bind(real_distribution, rand_engine);

                for(std::size_t j = p * ii; j < p * (ii + 1); ++j){
                    container[j] = generator();
                }
                }, i));
        }

        static std::random_device rd;
        static std::mt19937_64 rand_engine(rd());
        static std::uniform_real_distribution<double> real_distribution(-10000.0, 10000.0);
        static auto generator = std::bind(real_distribution, rand_engine);

        for(std::size_t j = container.size() - container.size() % p; j < container.size(); ++j){
            container[j] = generator();
        }
    } else {
        static std::random_device rd;
        static std::mt19937_64 rand_engine(rd());
        static std::uniform_real_distribution<double> real_distribution(-10000.0, 10000.0);
        static auto generator = std::bind(real_distribution, rand_engine);

        for(auto& v : container){
            v = generator();
        }
    }
}

#else

template<typename T>
void randomize_double(T& container){
    static std::random_device rd;
    static std::mt19937_64 rand_engine(rd());
    static std::uniform_real_distribution<double> real_distribution(-10000.0, 10000.0);
    static auto generator = std::bind(real_distribution, rand_engine);

    const auto a = generator();
    const auto b = generator();
    const auto c = generator();

    if(container.size() > CPM_PARALLEL_THRESHOLD){
        const std::size_t n = CPM_PARALLEL_THREADS; //We are assuming Hyper-Threading
        const std::size_t p = container.size() / n;

        std::vector<std::future<void>> futures;

        for(std::size_t i = 0; i < n; ++i){
            futures.push_back(std::async(std::launch::async, [&](std::size_t ii){
                for(std::size_t j = p * ii; j < p * (ii + 1); ++j){
                    container[j] = a + (j * b) + (-j * c);
                }
                }, i));
        }

        for(std::size_t j = container.size() - container.size() % p; j < container.size(); ++j){
            container[j] = a + (j * b) + (-j * c);
        }
    } else {
        std::size_t i = 0;
        for(auto& v : container){
            v = a + (i * b) + (-i * c);
            ++i;
        }
    }
}

#endif //CPM_FAST_RANDOMIZE

#else

#ifndef CPM_FAST_RANDOMIZE

template<typename T>
void randomize_double(T& container){
    static std::random_device rd;
    static std::mt19937_64 rand_engine(rd());
    static std::uniform_real_distribution<double> real_distribution(-10000.0, 10000.0);
    static auto generator = std::bind(real_distribution, rand_engine);

    for(auto& v : container){
        v = generator();
    }
}

#else

template<typename T>
void randomize_double(T& container){
    static std::random_device rd;
    static std::mt19937_64 rand_engine(rd());
    static std::uniform_real_distribution<double> real_distribution(-10000.0, 10000.0);
    static auto generator = std::bind(real_distribution, rand_engine);

    auto a = generator();
    auto b = generator();
    auto c = generator();

    std::size_t i = 0;
    for(auto& v : container){
        v = a + (i * b) + (-i * c);
        ++i;
    }
}

#endif //CPM_FAST_RANDOMIZE

#endif //CPM_PARALLEL_RANDOMIZE

inline void randomize(){}

template<typename T1, typename std::enable_if_t<std::is_convertible<double, typename T1::value_type>::value, int> = 42 >
void randomize(T1& container){
    randomize_double(container);
}

template<typename T1, typename... TT>
void randomize(T1& value, TT&... values){
    randomize(value);
    randomize(values...);
}

template<typename Tuple, std::size_t... I>
void randomize_each(Tuple& data, std::index_sequence<I...> /*indices*/){
    using cpm::randomize;
    randomize(std::get<I>(data)...);
}

} //end of namespace cpm

#endif //CPM_RANDOM_HPP
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011, Willow Garage, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Willow Garage, Inc. nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#pragma once
#include <boost/python.hpp>
#include <boost/python/type_id.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>

#include <ecto/util.hpp> //name_of
#include <ecto/tendril.hpp>
#include <stdexcept>
#include <string>
#include <set>
#include <sstream>
#include <cstring>

namespace ecto
{
  /**
   * \class spore
   * \brief The spore is a typed handle for tendrils, making holding onto tendrils a bit easier.
   */
  template<typename T>
  struct spore
  {
    /**
     * Allocates a spore that doesn't point to anything.
     */
    spore()
    {
    }

    /**
     * implicit constructor from a tendril ptr. Needs to be a shared_ptr, as the spore holds a
     * weak_ptr, and uses this to ensure that the spore always points to valid tendril.
     */
    spore(tendril::ptr t) :
        tendril_(t)
    {
      t->enforce_type<T>();
    }

    /**
     * Grab a pointer to the tendril that gave birth to this spore.
     * @return non const pointer to tendril
     */
    inline tendril::ptr p()
    {
      tendril::ptr _p = tendril_.lock();
      if (!_p)
        throw std::logic_error("This spore points to nothing.");
      return _p;
    }
    /**
     * Grab a pointer to the tendril that gave birth to this spore. const overload.
     * @return const pointer to tendril
     */
    inline tendril::const_ptr p() const
    {
      tendril::const_ptr _p = tendril_.lock();
      if (!_p)
        throw std::logic_error("This spore points to nothing.");
      return _p;
    }

    /**
     * Set a typed callback, that will be called when ever the tendril value is changed by the
     * user.
     * @param cb The callback
     * @return ref to this spore, for chaining.
     */
    spore<T>& set_callback(boost::function<void(T)> cb)
    {
      p()->set_callback(cb);
      return *this;
    }

    spore<T>& notify()
    {
      p()->notify();
      return *this;
    }

    spore<T>& set_doc(const std::string& doc)
    {
      p()->set_doc(doc);
      return *this;
    }

    spore<T>& set_default_val(const T& val)
    {
      p()->set_default_val(val);
      return *this;
    }

    bool dirty() const
    {
      return p()->dirty();
    }

    bool user_supplied() const
    {
      return p()->user_supplied();
    }

    bool has_default() const
    {
      return p()->has_default();
    }

    void required(bool b)
    {
      p()->required(b);
    }

    bool required() const
    {
      return p()->required();
    }

    T* operator->()
    {
      tendril::ptr _p = p();
      return &(_p->get<T>());
    }
    const T* operator->() const
    {
      tendril::const_ptr _p = p();
      return &(_p->read<T>());
    }
    const T& operator*() const
    {
      tendril::const_ptr _p = p();
      return _p->read<T>();
    }
    T& operator*()
    {
      tendril::ptr _p = p();
      return _p->get<T>();
    }
    /**
     * This is the const read operation, as opposed to the derefence which is not necessarily const.
     * @return const ref, no copies...
     */
    const T& operator()() const
    {
      tendril::const_ptr _p = p();
      return _p->read<T>();
    }
    /**
     * Cast operator for convenience.
     */
    operator tendril::ptr()
    {
      return p();
    }
    /**
     * Cast operator for convenience.
     */
    operator tendril::const_ptr() const
    {
      return p();
    }

    tendril::ptr tendril_ptr()
    {
      return p();
    }

    tendril::const_ptr tendril_ptr() const
    {
      return p();
    }

  private:
    boost::weak_ptr<tendril> tendril_;
  };
}
<commit_msg>A bit more verbosity in exception.<commit_after>/*
 * Copyright (c) 2011, Willow Garage, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Willow Garage, Inc. nor the names of its
 *       contributors may be used to endorse or promote products derived from
 *       this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#pragma once
#include <boost/python.hpp>
#include <boost/python/type_id.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>

#include <ecto/util.hpp> //name_of
#include <ecto/tendril.hpp>
#include <stdexcept>
#include <string>
#include <set>
#include <sstream>
#include <cstring>

namespace ecto
{
  /**
   * \class spore
   * \brief The spore is a typed handle for tendrils, making holding onto tendrils a bit easier.
   */
  template<typename T>
  struct spore
  {
    /**
     * Allocates a spore that doesn't point to anything.
     */
    spore()
    {
    }

    /**
     * implicit constructor from a tendril ptr. Needs to be a shared_ptr, as the spore holds a
     * weak_ptr, and uses this to ensure that the spore always points to valid tendril.
     */
    spore(tendril::ptr t) :
        tendril_(t)
    {
      t->enforce_type<T>();
    }

    /**
     * Grab a pointer to the tendril that gave birth to this spore.
     * @return non const pointer to tendril
     */
    inline tendril::ptr p()
    {
      tendril::ptr _p = tendril_.lock();
      if (!_p)
        throw std::logic_error("This spore points to nothing.");
      return _p;
    }
    /**
     * Grab a pointer to the tendril that gave birth to this spore. const overload.
     * @return const pointer to tendril
     */
    inline tendril::const_ptr p() const
    {
      tendril::const_ptr _p = tendril_.lock();
      if (!_p)
        throw std::logic_error("This spore points to nothing. Type name:" + name_of<T>());
      return _p;
    }

    /**
     * Set a typed callback, that will be called when ever the tendril value is changed by the
     * user.
     * @param cb The callback
     * @return ref to this spore, for chaining.
     */
    spore<T>& set_callback(boost::function<void(T)> cb)
    {
      p()->set_callback(cb);
      return *this;
    }

    spore<T>& notify()
    {
      p()->notify();
      return *this;
    }

    spore<T>& set_doc(const std::string& doc)
    {
      p()->set_doc(doc);
      return *this;
    }

    spore<T>& set_default_val(const T& val)
    {
      p()->set_default_val(val);
      return *this;
    }

    bool dirty() const
    {
      return p()->dirty();
    }

    bool user_supplied() const
    {
      return p()->user_supplied();
    }

    bool has_default() const
    {
      return p()->has_default();
    }

    void required(bool b)
    {
      p()->required(b);
    }

    bool required() const
    {
      return p()->required();
    }

    T* operator->()
    {
      tendril::ptr _p = p();
      return &(_p->get<T>());
    }
    const T* operator->() const
    {
      tendril::const_ptr _p = p();
      return &(_p->read<T>());
    }
    const T& operator*() const
    {
      tendril::const_ptr _p = p();
      return _p->read<T>();
    }
    T& operator*()
    {
      tendril::ptr _p = p();
      return _p->get<T>();
    }
    /**
     * This is the const read operation, as opposed to the derefence which is not necessarily const.
     * @return const ref, no copies...
     */
    const T& operator()() const
    {
      tendril::const_ptr _p = p();
      return _p->read<T>();
    }
    /**
     * Cast operator for convenience.
     */
    operator tendril::ptr()
    {
      return p();
    }
    /**
     * Cast operator for convenience.
     */
    operator tendril::const_ptr() const
    {
      return p();
    }

    tendril::ptr tendril_ptr()
    {
      return p();
    }

    tendril::const_ptr tendril_ptr() const
    {
      return p();
    }

  private:
    boost::weak_ptr<tendril> tendril_;
  };
}
<|endoftext|>


<commit_before>/* BSD 2-Clause License

Copyright (c) 2016, Doi Yusuke
All rights reserved.

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

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

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

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

#include "ics3/check_invalid.hpp"

namespace ics
{
class ICS3;

class Angle
{
  friend ICS3; // for touch rawData
public:
  using rawType = uint16_t;
  using type = double;
  static constexpr Angle newDegree(type = 0.0);
  static constexpr Angle newRadian(type = 0.0);
  static constexpr Angle newSameUnit(const Angle&, type = 0.0);
  static constexpr Angle newCalibration(type, type = 0.0);
  static constexpr rawType MIN {3500};
  static constexpr rawType MID {7500};
  static constexpr rawType MAX {11500};
  static constexpr type PI {3.141592653589793};

  Angle(const Angle&) noexcept = default;
  Angle& operator=(const Angle&) noexcept;
  constexpr type get() const noexcept;
  constexpr operator type() const noexcept;
  void set(type);
  Angle& operator=(type);
  constexpr rawType getRaw() const noexcept;
  void setRaw(rawType);
private:
  constexpr Angle(type, type); // non explicit, user cannot touch this
  static constexpr rawType castToRaw(type, type) noexcept;
  static constexpr rawType checkValidAngle(rawType);

  rawType rawData;
  const type rawCalibration;
};

constexpr Angle Angle::newDegree(type angle)
{
  return {800.0 / 27.0, angle};
}

constexpr Angle Angle::newRadian(type angle)
{
  return {16000.0 / 3.0 / PI, angle};
}

constexpr Angle Angle::newSameUnit(const Angle& unit, type angle)
{
  return {unit.rawCalibration, angle};
}

constexpr Angle Angle::newCalibration(type calibration, type angle)
{
  return {calibration, angle};
}

inline Angle& Angle::operator=(const Angle& rhs) noexcept
{
  rawData = rhs.rawData;
  return *this;
}

constexpr Angle::type Angle::get() const noexcept
{
  return (rawData - MID) / rawCalibration;
}

constexpr Angle::operator type() const noexcept
{
  return get();
}

inline void Angle::set(type angle)
{
  setRaw(castToRaw(rawCalibration, angle)); // throw std::out_of_range
}

inline Angle& Angle::operator=(type angle)
{
  set(angle);
  return *this;
}

constexpr Angle::rawType Angle::getRaw() const noexcept
{
  return rawData;
}

inline void Angle::setRaw(rawType raw)
{
  rawData = checkValidAngle(raw); // throw std::out_of_range
}

constexpr Angle::Angle(type calibration, type angle)
  : rawData {checkValidAngle(castToRaw(calibration, angle))}, // throw std::out_of_range
    rawCalibration {calibration}
{
}

constexpr Angle::rawType Angle::castToRaw(type calibration, type angle) noexcept
{
  return (calibration * angle) + MID;
}

constexpr Angle::rawType Angle::checkValidAngle(rawType raw)
{
  return checkValidRange(raw, MIN, MAX);
}
}

#endif // LIBICS3_ICS3_ANGLE_H
<commit_msg>Reformat header file of Angle<commit_after>/* BSD 2-Clause License

Copyright (c) 2016, Doi Yusuke
All rights reserved.

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

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

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

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

#include "ics3/check_invalid.hpp"

namespace ics
{
class ICS3;

class Angle
{
  friend ICS3; // for touch rawData
public:
  using rawType = uint16_t;
  using type = double;

  static constexpr Angle newDegree(type = 0.0);
  static constexpr Angle newRadian(type = 0.0);
  static constexpr Angle newSameUnit(const Angle&, type = 0.0);
  static constexpr Angle newCalibration(type, type = 0.0);
  static constexpr rawType MIN {3500};
  static constexpr rawType MID {7500};
  static constexpr rawType MAX {11500};
  static constexpr type PI {3.141592653589793};

  Angle(const Angle&) noexcept = default;
  Angle& operator=(const Angle&) noexcept;

  constexpr type get() const noexcept;
  constexpr operator type() const noexcept;
  void set(type);
  Angle& operator=(type);
  constexpr rawType getRaw() const noexcept;
  void setRaw(rawType);
private:
  constexpr Angle(type, type); // non explicit, user cannot touch this

  static constexpr rawType castToRaw(type, type) noexcept;
  static constexpr rawType checkValidAngle(rawType);

  rawType rawData;
  const type rawCalibration;
};

constexpr Angle Angle::newDegree(type angle)
{
  return {800.0 / 27.0, angle};
}

constexpr Angle Angle::newRadian(type angle)
{
  return {16000.0 / 3.0 / PI, angle};
}

constexpr Angle Angle::newSameUnit(const Angle& unit, type angle)
{
  return {unit.rawCalibration, angle};
}

constexpr Angle Angle::newCalibration(type calibration, type angle)
{
  return {calibration, angle};
}

inline Angle& Angle::operator=(const Angle& rhs) noexcept
{
  rawData = rhs.rawData;
  return *this;
}

constexpr Angle::type Angle::get() const noexcept
{
  return (rawData - MID) / rawCalibration;
}

constexpr Angle::operator type() const noexcept
{
  return get();
}

inline void Angle::set(type angle)
{
  setRaw(castToRaw(rawCalibration, angle)); // throw std::out_of_range
}

inline Angle& Angle::operator=(type angle)
{
  set(angle);
  return *this;
}

constexpr Angle::rawType Angle::getRaw() const noexcept
{
  return rawData;
}

inline void Angle::setRaw(rawType raw)
{
  rawData = checkValidAngle(raw); // throw std::out_of_range
}

constexpr Angle::Angle(type calibration, type angle)
  : rawData {checkValidAngle(castToRaw(calibration, angle))}, // throw std::out_of_range
    rawCalibration {calibration}
{
}

constexpr Angle::rawType Angle::castToRaw(type calibration, type angle) noexcept
{
  return (calibration * angle) + MID;
}

constexpr Angle::rawType Angle::checkValidAngle(rawType raw)
{
  return checkValidRange(raw, MIN, MAX);
}
}

#endif // LIBICS3_ICS3_ANGLE_H
<|endoftext|>


<commit_before>#pragma once

#include "c/struct stat.h"
#include "Result.hxx"

namespace os {

static inline
auto
fstatat(int dirfd,
        const char* pathname,
        struct stat* buf,
        int flags) noexcept
{
#if defined(__linux__)
#  include "c/EACCES.h"
#  include "c/EBADF.h"
#  include "c/EFAULT.h"
#  include "c/EINVAL.h"
#  include "c/ELOOP.h"
#  include "c/ENAMETOOLONG.h"
#  include "c/ENOMEM.h"
#  include "c/ENOTDIR.h"
#  include "c/EOVERFLOW.h"
#  define _(name) _##name = name

    enum Error
    {
        _(EACCES),
        _(EBADF),
        _(EFAULT),
        _(EINVAL),
        _(ELOOP),
        _(ENAMETOOLONG),
        _(ENOMEM),
        _(ENOTDIR),
        _(EOVERFLOW),
    };

#  undef _
#  include "c/SYS_fstat.h"

    return Result<void, Error>(SYS_fstatat, dirfd, pathname, buf, flags);

#else
#  error
#endif
}

}
<commit_msg>Fix include<commit_after>#pragma once

#include "c/struct stat.h"
#include "Result.hxx"

namespace os {

static inline
auto
fstatat(int dirfd,
        const char* pathname,
        struct stat* buf,
        int flags) noexcept
{
#if defined(__linux__)
#  include "c/EACCES.h"
#  include "c/EBADF.h"
#  include "c/EFAULT.h"
#  include "c/EINVAL.h"
#  include "c/ELOOP.h"
#  include "c/ENAMETOOLONG.h"
#  include "c/ENOMEM.h"
#  include "c/ENOTDIR.h"
#  include "c/EOVERFLOW.h"
#  define _(name) _##name = name

    enum Error
    {
        _(EACCES),
        _(EBADF),
        _(EFAULT),
        _(EINVAL),
        _(ELOOP),
        _(ENAMETOOLONG),
        _(ENOMEM),
        _(ENOTDIR),
        _(EOVERFLOW),
    };

#  undef _
#  include "c/SYS_fstatat.h"

    return Result<void, Error>(SYS_fstatat, dirfd, pathname, buf, flags);

#else
#  error
#endif
}

}
<|endoftext|>