<commit_before>/*
 * Copyright (C) 2002-2007 Novamente LLC
 * Copyright (C) 2008 by Singularity Institute for Artificial Intelligence
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/util/platform.h>
#include <opencog/atomspace/utils.h>
#include "../../PLN.h"

#include "../Rule.h"
#include "../Rules.h"
#include "../../AtomSpaceWrapper.h"
#include "../../PLNatom.h"
#include "../../BackInferenceTreeNode.h"

namespace opencog { namespace pln {

unsigned long now_interval_len = 50000;
bool ExpandEvaluationLinks(vtree& target, AtomSpaceWrapper* asw)
{
    bool is_changed = false;

    for(vtree::iterator i = target.begin(); i != target.end(); i++)
        if (asw->isSubType(_v2h(*i), CONCEPT_NODE) && !asw->isType(_v2h(*i))) {
            std::string name = asw->getName(_v2h(*i));
            if (name == "!whileago" || name == "!now") {
#ifndef WIN32
                /*  timeval currentTime;
                    gettimeofday(&currentTime, NULL);
                    long now_stamp = currentTime.tv_sec*1000 + currentTime.tv_usec/1000;*/
                signed long now_stamp = (signed long)getElapsedMillis();
                signed long now_interval = now_interval_len;
#else
                signed long now_stamp = 3000;
                signed long now_interval = 1000;
#endif
                char end_stamp_s[100], begin_stamp_s[100];
                sprintf(begin_stamp_s, "%f", max(0,now_stamp-now_interval));
                sprintf(end_stamp_s, "%ld", now_stamp);

                if (name == "!whileago")
                    target.replace(i, Vertex(asw->addNode(NUMBER_NODE,
                                                          begin_stamp_s,
                                                          TruthValue::TRUE_TV(),
                                                          false)));
                //  target.replace(i, Vertex(NewNode(NUMBER_NODE, begin_stamp_s)));
                if (name == "!now")
                    target.replace(i, Vertex(asw->addNode(NUMBER_NODE,
                                                          end_stamp_s,
                                                          TruthValue::TRUE_TV(),
                                                          false)));
                //  target.replace(i, Vertex(NewNode(NUMBER_NODE, end_stamp_s)));

                is_changed = true;
            }
        }

    return is_changed;
}

Btr<std::set<BoundVertex> > LookupRule::attemptDirectProduction(meta outh,
                                                                bool fresh) const
{
    vtree target(*outh);

    Btr<std::set<BoundVertex> > ret(new TableGather(target, asw));

    if (ExpandEvaluationLinks(target, asw)) {
        TableGather dynamic_lookup(target, asw);
        copy(dynamic_lookup.begin(), dynamic_lookup.end(),
             inserter(*ret, ret->begin()));

        //      puts("Lookup macros!");
        //      NMPrinter()(NMPrintable(target), -3);
        Btr<std::set<BoundVertex> > ret(new TableGather(target, asw));

        /*foreach(const BoundVertex& bv, *ret)
        {
            NMPrinter()(v2h(bv.value), -3);
        }
        if (!ret->empty())
        {
            puts("results above!");
            getc(stdin);
        }*/
    }

    return ret;
}

Rule::setOfMPs LookupRule::o2iMetaExtra(meta outh,
                                        bool& overrideInputFilter) const
{
    assert(0);
    return setOfMPs();
}

}} // namespace opencog { namespace pln {
<commit_msg>Fix compile issue<commit_after>/*
 * Copyright (C) 2002-2007 Novamente LLC
 * Copyright (C) 2008 by Singularity Institute for Artificial Intelligence
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/util/platform.h>
#include <opencog/util/octime.h>

#include "../../PLN.h"

#include "../Rule.h"
#include "../Rules.h"
#include "../../AtomSpaceWrapper.h"
#include "../../PLNatom.h"
#include "../../BackInferenceTreeNode.h"

namespace opencog { namespace pln {

unsigned long now_interval_len = 50000;
bool ExpandEvaluationLinks(vtree& target, AtomSpaceWrapper* asw)
{
    bool is_changed = false;

    for(vtree::iterator i = target.begin(); i != target.end(); i++)
        if (asw->isSubType(_v2h(*i), CONCEPT_NODE) && !asw->isType(_v2h(*i))) {
            std::string name = asw->getName(_v2h(*i));
            if (name == "!whileago" || name == "!now") {
#ifndef WIN32
                /*  timeval currentTime;
                    gettimeofday(&currentTime, NULL);
                    long now_stamp = currentTime.tv_sec*1000 + currentTime.tv_usec/1000;*/
                signed long now_stamp = (signed long)getElapsedMillis();
                signed long now_interval = now_interval_len;
#else
                signed long now_stamp = 3000;
                signed long now_interval = 1000;
#endif
                char end_stamp_s[100], begin_stamp_s[100];
                sprintf(begin_stamp_s, "%f", max(0,now_stamp-now_interval));
                sprintf(end_stamp_s, "%ld", now_stamp);

                if (name == "!whileago")
                    target.replace(i, Vertex(asw->addNode(NUMBER_NODE,
                                                          begin_stamp_s,
                                                          TruthValue::TRUE_TV(),
                                                          false)));
                //  target.replace(i, Vertex(NewNode(NUMBER_NODE, begin_stamp_s)));
                if (name == "!now")
                    target.replace(i, Vertex(asw->addNode(NUMBER_NODE,
                                                          end_stamp_s,
                                                          TruthValue::TRUE_TV(),
                                                          false)));
                //  target.replace(i, Vertex(NewNode(NUMBER_NODE, end_stamp_s)));

                is_changed = true;
            }
        }

    return is_changed;
}

Btr<std::set<BoundVertex> > LookupRule::attemptDirectProduction(meta outh,
                                                                bool fresh) const
{
    vtree target(*outh);

    Btr<std::set<BoundVertex> > ret(new TableGather(target, asw));

    if (ExpandEvaluationLinks(target, asw)) {
        TableGather dynamic_lookup(target, asw);
        copy(dynamic_lookup.begin(), dynamic_lookup.end(),
             inserter(*ret, ret->begin()));

        //      puts("Lookup macros!");
        //      NMPrinter()(NMPrintable(target), -3);
        Btr<std::set<BoundVertex> > ret(new TableGather(target, asw));

        /*foreach(const BoundVertex& bv, *ret)
        {
            NMPrinter()(v2h(bv.value), -3);
        }
        if (!ret->empty())
        {
            puts("results above!");
            getc(stdin);
        }*/
    }

    return ret;
}

Rule::setOfMPs LookupRule::o2iMetaExtra(meta outh,
                                        bool& overrideInputFilter) const
{
    assert(0);
    return setOfMPs();
}

}} // namespace opencog { namespace pln {
<|endoftext|>


<commit_before>/*
  RTQL8, Copyright (c) 2011 Georgia Tech Graphics Lab
  All rights reserved.

  Author	Sehoon Ha
  Date		06/12/2011
*/

#ifndef DART_KINEMATICS_FILEINFO_SKEL_H
#define DART_KINEMATICS_FILEINFO_SKEL_H

#include <fstream>
#include <iomanip>
#include <string>
#include <iostream>
#include <sstream>

#include <Eigen/Dense>

#include "renderer/RenderInterface.h"
#include "Skeleton.h"
#include "BodyNode.h"
#include "ParserVsk.h"
#include "Marker.h"
#include "Dof.h"
#include "Joint.h"
#include "Marker.h"
#include "Transformation.h"
#include "ShapeEllipsoid.h"
#include "ShapeBox.h"

int readSkelFile( const char* const filename, kinematics::Skeleton* skel );

namespace kinematics {

    class BodyNode;
    class Skeleton;

    enum SkeletonFileType {
        VSK,
        SKEL
    };

    template <class SkeletonType>
    class FileInfoSkel {
    public:
        FileInfoSkel();
        virtual ~FileInfoSkel();

        void draw(renderer::RenderInterface* _ri = NULL, const Eigen::Vector4d& _color=Eigen::Vector4d::Ones(), bool _useDefaultColor = true) const; ///< Note: _color is not used when _useDefaultColor=false
        bool loadFile(const char* _filename);
        bool loadFile(const char* _filename, SkeletonFileType _type);
        bool saveFile(const char* _filename) const;

        SkeletonType* getSkel() const { return mSkel; }

    protected:
        SkeletonType* mSkel;
        char mFileName[256]; // could use string instead

        // used in saveFile to write the subtree of _b
        void saveBodyNodeTree(BodyNode* _b, std::ofstream &_outfile, int _numLinks) const;
    };

    template <class SkeletonType>
    FileInfoSkel<SkeletonType>::FileInfoSkel() : mSkel(NULL){
    }

    template <class SkeletonType>
    FileInfoSkel<SkeletonType>::~FileInfoSkel(){
        if(mSkel){
            delete mSkel;
            mSkel = NULL;
        }
    }

    template <class SkeletonType>
    void FileInfoSkel<SkeletonType>::draw(renderer::RenderInterface* _ri, const Eigen::Vector4d& _color, bool _useDefaultColor) const {
        mSkel->draw(_ri, _color, _useDefaultColor);
    }

    template <class SkeletonType>
    bool FileInfoSkel<SkeletonType>::loadFile( const char* _fName ) {

        std::string ext( _fName );
        ext = ext.substr(ext.length() - 4);

        if (ext == ".vsk") {
            return loadFile(_fName, VSK);
        } else if (ext == "skel") {
            return loadFile(_fName, SKEL);
        } else {
            std::cout << "[VLOG(1)]" << "invalid skeleton ext: " << ext;
            return false;
        }
    }

    template <class SkeletonType>
    bool FileInfoSkel<SkeletonType>::loadFile( const char* _fName, SkeletonFileType _type ) {
        if( mSkel )
            delete mSkel;
        // mSkel = new Skeleton;
        mSkel = new SkeletonType;

        bool success = false;
        if(_type == SKEL)
            success = !readSkelFile( _fName, mSkel);
        else if(_type == VSK)
            success = (readVSKFile(_fName, mSkel) == VSK_OK);
        if(success){
            std::string text = _fName;
            int lastSlash = text.find_last_of("/");
            text = text.substr(lastSlash+1);
            strcpy(mFileName, text.c_str());
        }
        return success;
    }

    const static std::string unitlength = "unitlength";

    template <class SkeletonType>
    bool FileInfoSkel<SkeletonType>::saveFile( const char* _fName) const {
        using namespace std;
        ofstream output(_fName);
        if(output.fail()){
            cout<<"Unable to save file "<<_fName<<endl;
            return false;
        }
        output<<fixed<<setprecision(6);

        int _numLinks = mSkel->mNumNodes;

        output<<"dofs {\n";
        for(int i=0; i<mSkel->getNumDofs(); i++){
            Dof *d = mSkel->getDof(i);
            if(d->getJoint()->getChildNode()->getSkelIndex() >= _numLinks) break;
            output<<'\t'<<d->getName()<<" { "<<d->getValue()<<", "<<d->getMin()<<", "<<d->getMax()<<" }\n";
        }
        output<<unitlength<<" { 1.0, 1.0, 1.0 }\n";
        output<<"}\n";

        // masses
        output<<"\nmass {\n";
        for(int i=0; i<mSkel->mNumNodes; i++){
            if(i>=_numLinks) break;
            string massname = mSkel->getNode(i)->getName();
            massname += "_mass";
            output<<massname<<" { "<<mSkel->getNode(i)->getMass()<<" }\n";

        }
        output<<"}\n";

        // nodes
        saveBodyNodeTree(mSkel->mRoot, output, _numLinks);

        // markers
        output<<"\nmarkers {\n";
        for(int i=0; i<mSkel->getNumMarkers(); i++){
            if(mSkel->getMarker(i)->getNode()->getSkelIndex()>=_numLinks) break;
            string hname = mSkel->getMarker(i)->getName();
            if(hname.empty()){
                ostringstream ss;
                ss<<"marker"<<i;
                hname = ss.str();
            }
            Eigen::Vector3d lc = mSkel->getMarker(i)->getLocalCoords();
            output<<hname<<" { "<<"<"<<lc[0]<<", "<<lc[1]<<", "<<lc[2]<<">, "<<i<<", "<<mSkel->getMarker(i)->getNode()->getName()<<" } "<<endl;

        }
        output<<"}\n";

        cout<<"\n";

        return true;
    }

    template <class SkeletonType>
    void FileInfoSkel<SkeletonType>::saveBodyNodeTree(BodyNode *_b, std::ofstream &_outfile, int _numLinks) const {
        // save the current one
        _outfile<<"\nnode "<<_b->getName()<<" { "<<_b->getSkelIndex()<<"\n";
        // write the trans
        _outfile<<"chain { "<<_b->getParentJoint()->getNumTransforms()<<"\n";
        for(int i=0; i<_b->getParentJoint()->getNumTransforms(); i++){
            Transformation *tr = _b->getParentJoint()->getTransform(i);
            if(!tr->isVariable()){	// constant
                if(tr->getType()==Transformation::T_TRANSLATE){
                    _outfile<<"telescope { <"<<tr->getDof(0)->getValue()<<", "<<tr->getDof(1)->getValue()<<", "<<tr->getDof(2)->getValue()<<">, "<<unitlength<<" }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEX){
                    _outfile<<"rotate_cons { "<<tr->getDof(0)->getValue()<<", "<<" x }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEY){
                    _outfile<<"rotate_cons { "<<tr->getDof(0)->getValue()<<", "<<" y }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEZ){
                    _outfile<<"rotate_cons { "<<tr->getDof(0)->getValue()<<", "<<" z }\n";
                }
                else {
                    _outfile<<"unknown trans\n";
                }

            }
            else {	// variable
                if(tr->getType()==Transformation::T_TRANSLATE){
                    _outfile<<"translate { <"<<tr->getDof(0)->getName()<<", "<<tr->getDof(1)->getName()<<", "<<tr->getDof(2)->getName()<<"> }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEX){
                    _outfile<<"rotate_euler { "<<tr->getDof(0)->getName()<<", "<<" x }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEY){
                    _outfile<<"rotate_euler { "<<tr->getDof(0)->getName()<<", "<<" y }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEZ){
                    _outfile<<"rotate_euler { "<<tr->getDof(0)->getName()<<", "<<" z }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEEXPMAP){
                    _outfile<<"rotate_expmap { <"<<tr->getDof(0)->getName()<<", "<<tr->getDof(1)->getName()<<", "<<tr->getDof(2)->getName()<<"> }\n";
                }
                else {
                    _outfile<<"unknown trans\n";
                }
            }
        }
        _outfile<<"}\n";	// chain

        // primitive
        Eigen::Vector3d pdim = _b->getShape()->getDim(); // Default to VizShape in graphics context
        Eigen::Vector3d off = _b->getLocalCOM();
        _outfile<<"primitive { <"<<pdim[0]<<", "<<pdim[1]<<", "<<pdim[2]<<">, <"<<off[0]<<", "<<off[1]<<", "<<off[2]<<">, "<<unitlength;
        // different types

        Shape* prim = _b->getShape();
        ShapeEllipsoid* elp = dynamic_cast<ShapeEllipsoid*>(prim);
        ShapeBox* box = dynamic_cast<ShapeBox*>(prim);

        if(elp) _outfile<<", SPHERE";
        else if(box) _outfile<<", CUBE";

        _outfile<<", "<<std::string(_b->getName())+std::string("_mass");
        _outfile<<" }\n";

        for(int i=0; i<_b->getNumChildJoints(); i++){
            if(_b->getChildNode(i)->getSkelIndex()>=_numLinks) continue;
            saveBodyNodeTree(_b->getChildNode(i), _outfile, _numLinks);
        }

        _outfile<<"}\n";	//node

    }

} // namespace kinematics

#endif // #ifndef DART_KINEMATICS_FILEINFO_SKEL_H

<commit_msg>Fix last commit (again)<commit_after>/*
  RTQL8, Copyright (c) 2011 Georgia Tech Graphics Lab
  All rights reserved.

  Author	Sehoon Ha
  Date		06/12/2011
*/

#ifndef DART_KINEMATICS_FILEINFO_SKEL_H
#define DART_KINEMATICS_FILEINFO_SKEL_H

#include <fstream>
#include <iomanip>
#include <string>
#include <iostream>
#include <sstream>

#include <Eigen/Dense>

#include "renderer/RenderInterface.h"
#include "Skeleton.h"
#include "BodyNode.h"
#include "ParserVsk.h"
#include "Marker.h"
#include "Dof.h"
#include "Joint.h"
#include "Marker.h"
#include "Transformation.h"
#include "ShapeEllipsoid.h"
#include "ShapeBox.h"

int readSkelFile( const char* const filename, kinematics::Skeleton* skel );

namespace kinematics {

    class BodyNode;
    class Skeleton;

    enum SkeletonFileType {
        VSK,
        SKEL
    };

    template <class SkeletonType>
    class FileInfoSkel {
    public:
        FileInfoSkel();
        virtual ~FileInfoSkel();

        void draw(renderer::RenderInterface* _ri = NULL, const Eigen::Vector4d& _color=Eigen::Vector4d::Ones(), bool _useDefaultColor = true) const; ///< Note: _color is not used when _useDefaultColor=false
        bool loadFile(const char* _filename);
        bool loadFile(const char* _filename, SkeletonFileType _type);
        bool saveFile(const char* _filename) const;

        SkeletonType* getSkel() const { return mSkel; }

    protected:
        SkeletonType* mSkel;
        char mFileName[256]; // could use string instead

        // used in saveFile to write the subtree of _b
        void saveBodyNodeTree(BodyNode* _b, std::ofstream &_outfile, int _numLinks) const;
    };

    template <class SkeletonType>
    FileInfoSkel<SkeletonType>::FileInfoSkel() : mSkel(NULL){
    }

    template <class SkeletonType>
    FileInfoSkel<SkeletonType>::~FileInfoSkel(){
        if(mSkel){
            delete mSkel;
            mSkel = NULL;
        }
    }

    template <class SkeletonType>
    void FileInfoSkel<SkeletonType>::draw(renderer::RenderInterface* _ri, const Eigen::Vector4d& _color, bool _useDefaultColor) const {
        mSkel->draw(_ri, _color, _useDefaultColor);
    }

    template <class SkeletonType>
    bool FileInfoSkel<SkeletonType>::loadFile( const char* _fName ) {

        std::string ext( _fName );
        ext = ext.substr(ext.length() - 4);

        if (ext == ".vsk") {
            return loadFile(_fName, VSK);
        } else if (ext == "skel") {
            return loadFile(_fName, SKEL);
        } else {
            std::cout << "[VLOG(1)]" << "invalid skeleton ext: " << ext;
            return false;
        }
    }

    template <class SkeletonType>
    bool FileInfoSkel<SkeletonType>::loadFile( const char* _fName, SkeletonFileType _type ) {
        if( mSkel )
            delete mSkel;
        // mSkel = new Skeleton;
        mSkel = new SkeletonType;

        bool success = false;
        if(_type == SKEL)
            success = !readSkelFile( _fName, mSkel);
        else if(_type == VSK)
            success = (readVSKFile(_fName, mSkel) == VSK_OK);
        if(success){
            std::string text = _fName;
            int lastSlash = text.find_last_of("/");
            text = text.substr(lastSlash+1);
            strcpy(mFileName, text.c_str());
        }
        return success;
    }

    const static std::string unitlength = "unitlength";

    template <class SkeletonType>
    bool FileInfoSkel<SkeletonType>::saveFile( const char* _fName) const {
        using namespace std;
        ofstream output(_fName);
        if(output.fail()){
            cout<<"Unable to save file "<<_fName<<endl;
            return false;
        }
        output<<fixed<<setprecision(6);

        int _numLinks = mSkel->mNumNodes;

        output<<"dofs {\n";
        for(int i=0; i<mSkel->getNumDofs(); i++){
            Dof *d = mSkel->getDof(i);
            if(d->getJoint()->getChildNode()->getSkelIndex() >= _numLinks) break;
            output<<'\t'<<d->getName()<<" { "<<d->getValue()<<", "<<d->getMin()<<", "<<d->getMax()<<" }\n";
        }
        output<<unitlength<<" { 1.0, 1.0, 1.0 }\n";
        output<<"}\n";

        // masses
        output<<"\nmass {\n";
        for(int i=0; i<mSkel->mNumNodes; i++){
            if(i>=_numLinks) break;
            string massname = mSkel->getNode(i)->getName();
            massname += "_mass";
            output<<massname<<" { "<<mSkel->getNode(i)->getMass()<<" }\n";

        }
        output<<"}\n";

        // nodes
        saveBodyNodeTree(mSkel->mRoot, output, _numLinks);

        // markers
        output<<"\nmarkers {\n";
        for(int i=0; i<mSkel->getNumMarkers(); i++){
            if(mSkel->getMarker(i)->getNode()->getSkelIndex()>=_numLinks) break;
            string hname = mSkel->getMarker(i)->getName();
            if(hname.empty()){
                ostringstream ss;
                ss<<"marker"<<i;
                hname = ss.str();
            }
            Eigen::Vector3d lc = mSkel->getMarker(i)->getLocalCoords();
            output<<hname<<" { "<<"<"<<lc[0]<<", "<<lc[1]<<", "<<lc[2]<<">, "<<i<<", "<<mSkel->getMarker(i)->getNode()->getName()<<" } "<<endl;

        }
        output<<"}\n";

        cout<<"\n";

        return true;
    }

    template <class SkeletonType>
    void FileInfoSkel<SkeletonType>::saveBodyNodeTree(BodyNode *_b, std::ofstream &_outfile, int _numLinks) const {
        // save the current one
        _outfile<<"\nnode "<<_b->getName()<<" { "<<_b->getSkelIndex()<<"\n";
        // write the trans
        _outfile<<"chain { "<<_b->getParentJoint()->getNumTransforms()<<"\n";
        for(int i=0; i<_b->getParentJoint()->getNumTransforms(); i++){
            Transformation *tr = _b->getParentJoint()->getTransform(i);
            if(!tr->isVariable()){	// constant
                if(tr->getType()==Transformation::T_TRANSLATE){
                    _outfile<<"telescope { <"<<tr->getDof(0)->getValue()<<", "<<tr->getDof(1)->getValue()<<", "<<tr->getDof(2)->getValue()<<">, "<<unitlength<<" }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEX){
                    _outfile<<"rotate_cons { "<<tr->getDof(0)->getValue()<<", "<<" x }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEY){
                    _outfile<<"rotate_cons { "<<tr->getDof(0)->getValue()<<", "<<" y }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEZ){
                    _outfile<<"rotate_cons { "<<tr->getDof(0)->getValue()<<", "<<" z }\n";
                }
                else {
                    _outfile<<"unknown trans\n";
                }

            }
            else {	// variable
                if(tr->getType()==Transformation::T_TRANSLATE){
                    _outfile<<"translate { <"<<tr->getDof(0)->getName()<<", "<<tr->getDof(1)->getName()<<", "<<tr->getDof(2)->getName()<<"> }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEX){
                    _outfile<<"rotate_euler { "<<tr->getDof(0)->getName()<<", "<<" x }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEY){
                    _outfile<<"rotate_euler { "<<tr->getDof(0)->getName()<<", "<<" y }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEZ){
                    _outfile<<"rotate_euler { "<<tr->getDof(0)->getName()<<", "<<" z }\n";
                }
                else if (tr->getType()==Transformation::T_ROTATEEXPMAP){
                    _outfile<<"rotate_expmap { <"<<tr->getDof(0)->getName()<<", "<<tr->getDof(1)->getName()<<", "<<tr->getDof(2)->getName()<<"> }\n";
                }
                else {
                    _outfile<<"unknown trans\n";
                }
            }
        }
        _outfile<<"}\n";	// chain

        // primitive
        Eigen::Vector3d pdim = _b->getShape(0)->getDim(); // Default to VizShape in graphics context
        Eigen::Vector3d off = _b->getLocalCOM();
        _outfile<<"primitive { <"<<pdim[0]<<", "<<pdim[1]<<", "<<pdim[2]<<">, <"<<off[0]<<", "<<off[1]<<", "<<off[2]<<">, "<<unitlength;
        // different types

        Shape* prim = _b->getShape(0);
        ShapeEllipsoid* elp = dynamic_cast<ShapeEllipsoid*>(prim);
        ShapeBox* box = dynamic_cast<ShapeBox*>(prim);

        if(elp) _outfile<<", SPHERE";
        else if(box) _outfile<<", CUBE";

        _outfile<<", "<<std::string(_b->getName())+std::string("_mass");
        _outfile<<" }\n";

        for(int i=0; i<_b->getNumChildJoints(); i++){
            if(_b->getChildNode(i)->getSkelIndex()>=_numLinks) continue;
            saveBodyNodeTree(_b->getChildNode(i), _outfile, _numLinks);
        }

        _outfile<<"}\n";	//node

    }

} // namespace kinematics

#endif // #ifndef DART_KINEMATICS_FILEINFO_SKEL_H

<|endoftext|>


<commit_before>#include "../checkpoint/checkpoint.h"
#include "myrandom/myrand.h"
#include <algorithm>                            // for std::shuffle
#include <cstdint>                              // for std::int32_t
#include <iostream>                             // for std::cout
#include <random>                               // for std::mt19937
#include <utility>                              // for std::make_pair
#include <vector>                               // for std::vector
#include <boost/algorithm/cxx11/iota.hpp>       // for boost::algorithm::iota
#include <boost/format.hpp>                     // for boost::format
#include <boost/range/algorithm.hpp>            // for boost::find, boost::transform
#include <tbb/concurrent_vector.h>              // for tbb::concurrent_vector
#include <tbb/parallel_for.h>                   // for tbb::parallel_for

namespace {
    // ビンゴボードのマス数
    static auto constexpr BOARDSIZE = 25U;

    // モンテカルロシミュレーションの試行回数
    static auto constexpr MCMAX = 1000000U;

    // 行・列の総数
    static auto constexpr ROWCOLUMNSIZE = 10U;

    //! A typedef.
    /*!
        そのマスに書かれてある番号と、そのマスが当たったかどうかを示すフラグ
        のstd::pair
    */
    using mypair = std::pair<std::int32_t, bool>;

    //! A typedef.
    /*!
        行・列が埋まるまでに要した回数と、その時点で埋まったマスのstd::pair
    */
    using mypair2 = std::pair<std::int32_t, std::int32_t>;

    //! A function.
    /*!
        ビンゴボードを生成する
        \return ビンゴボードが格納された可変長配列
    */
    auto makeBoard();

    //! A function.
    /*!
        モンテカルロ・シミュレーションを行う
        \return モンテカルロ法の結果が格納された二次元可変長配列
    */
    std::vector< std::vector<mypair2> > montecarlo();

    //! A function.
    /*!
        モンテカルロ・シミュレーションの実装
        \return モンテカルロ法の結果が格納された可変長配列
    */
    std::vector<mypair2> montecarloImpl();

    //! A function.
    /*!
        モンテカルロ・シミュレーションをTBBで並列化して行う
        \return モンテカルロ法の結果が格納された可変長配列
    */
    tbb::concurrent_vector< std::vector<mypair2> > montecarloTBB();
}

int main()
{
    checkpoint::CheckPoint cp;

    cp.checkpoint("処理開始", __LINE__);

    // モンテカルロ・シミュレーションの結果を代入
    auto const mcresult(montecarlo());

    cp.checkpoint("並列化無効", __LINE__);

    // TBBで並列化したモンテカルロ・シミュレーションの結果を代入
    auto const mcresult2(montecarloTBB());

    cp.checkpoint("並列化有効", __LINE__);

    // モンテカルロ・シミュレーションの平均試行回数の結果を格納した可変長配列
    std::vector<double> trialavg(ROWCOLUMNSIZE);

    // モンテカルロ・シミュレーションのi回目の試行で、埋まっているマスの数を格納した可変長配列
    std::vector<double> fillavg(ROWCOLUMNSIZE);

    // 行・列の総数分繰り返す
    for (auto i = 0U; i < ROWCOLUMNSIZE; i++) {
        // 総和を0で初期化
        auto trialsum = 0;
        auto fillsum = 0;

        // 試行回数分繰り返す
        for (auto j = 0U; j < MCMAX; j++) {
            // j回目の結果を加える
            trialsum += mcresult[j][i].first;
            fillsum += mcresult[j][i].second;
        }

        // 平均を算出してi行・列目のtrialavg、fillavgに代入
        trialavg[i] = static_cast<double>(trialsum) / static_cast<double>(MCMAX);
        fillavg[i] = static_cast<double>(fillsum) / static_cast<double>(MCMAX);
    }

    for (auto i = 0U; i < ROWCOLUMNSIZE; i++) {
        auto const efficiency = trialavg[i] / static_cast<double>(i + 1);
        std::cout
            << boost::format("%d個目に必要な平均試行回数：%.1f回, 効率 = %.1f（回/個）, ")
            % (i + 1) % trialavg[i] % efficiency
            << boost::format("埋まっているマスの平均個数：%.1f個\n")
            % fillavg[i];
    }

    cp.checkpoint_print();

    return 0;
}

namespace {
    auto makeBoard()
    {
        // 仮のビンゴボードを生成
        std::vector<std::int32_t> boardtmp(BOARDSIZE);

        // 仮のビンゴボードに1～25の数字を代入
        boost::algorithm::iota(boardtmp, 1);

        // 仮のビンゴボードの数字をシャッフル
        std::shuffle(boardtmp.begin(), boardtmp.end(), std::mt19937());

        // ビンゴボードを生成
        std::vector<mypair> board(BOARDSIZE);

        // 仮のビンゴボードからビンゴボードを生成する
        boost::transform(
            boardtmp,
            board.begin(),
            [](auto n) { return std::make_pair(n, false); });

        // ビンゴボードを返す
        return board;
    }

    std::vector< std::vector<mypair2> > montecarlo()
    {
        // モンテカルロ・シミュレーションの結果を格納するための二次元可変長配列
        std::vector< std::vector<mypair2> > mcresult;

        // MCMAX個の容量を確保
        mcresult.reserve(MCMAX);

        // 試行回数分繰り返す
        for (auto i = 0U; i < MCMAX; i++) {
            // モンテカルロ・シミュレーションの結果を代入
            mcresult.push_back(montecarloImpl());
        }

        // モンテカルロ・シミュレーションの結果を返す
        return mcresult;
    }

    std::vector<mypair2> montecarloImpl()
    {
        // ビンゴボードを生成
        auto board(makeBoard());

        // 自作乱数クラスを初期化
        myrandom::MyRand mr(1, BOARDSIZE);

        // その行・列が既に埋まっているかどうかを格納する可変長配列
        // ROWCOLUMNSIZE個の要素をfalseで初期化
        std::vector<bool> rcfill(ROWCOLUMNSIZE, false);

        // 行・列が埋まるまでに要した回数と、その時点で埋まったマスを格納した
        // 可変長配列
        std::vector< mypair2 > fillnum;

        // ROWCOLUMNSIZE個の容量を確保
        fillnum.reserve(ROWCOLUMNSIZE);

        // その時点で埋まっているマスを計算するためのラムダ式
        auto const sum = [](auto const & vec)
        {
            auto cnt = 0;
            for (auto & e : vec) {
                if (e.second) {
                    cnt++;
                }
            }

            return cnt;
        };

        // 無限ループ
        for (auto i = 1; ; i++) {
            // 乱数で得た数字で、かつまだ当たってないマスを検索
            auto itr = boost::find(board, std::make_pair(mr.myrand(), false));

            // そのようなマスがあった
            if (itr != board.end()) {
                // そのマスは当たったとし、フラグをtrueにする
                itr->second = true;
            }
            // そのようなマスがなかった
            else {
                //ループ続行
                continue;
            }

            // 各行・列が埋まったかどうかをチェック
            for (auto j = 0; j < 5; j++) {
                // 行をチェック
                if (board[5 * j].second &&
                    board[5 * j + 1].second &&
                    board[5 * j + 2].second &&
                    board[5 * j + 3].second &&
                    board[5 * j + 4].second &&
                    // その行は既に埋まっているかどうか
                    !rcfill[j]) {

                    // その行は埋まったとして、フラグをtrueにする
                    rcfill[j] = true;

                    // 要した試行回数と、その時点で埋まったマスの数を格納
                    fillnum.push_back(std::make_pair(i, sum(board)));
                }

                // 列をチェック
                if (board[j].second &&
                    board[j + 5].second &&
                    board[j + 10].second &&
                    board[j + 15].second &&
                    board[j + 20].second &&
                    // その列は既に埋まっているかどうか
                    !rcfill[j + 5]) {

                    // その列は埋まったとして、フラグをtrueにする
                    rcfill[j + 5] = true;

                    // 要した試行回数と、その時点で埋まったマスの数を格納
                    fillnum.push_back(std::make_pair(i, sum(board)));
                }
            }

            // 全ての行・列が埋まったかどうか
            if (fillnum.size() == ROWCOLUMNSIZE) {
                // 埋まったのでループ脱出
                break;
            }
        }

        // 要した試行関数の可変長配列を返す
        return fillnum;
    }

    tbb::concurrent_vector< std::vector<mypair2> > montecarloTBB()
    {
        // モンテカルロ・シミュレーションの結果を格納するための二次元可変長配列
        // 複数のスレッドが同時にアクセスする可能性があるためtbb::concurrent_vectorを使う
        tbb::concurrent_vector< std::vector<mypair2> > mcresult;

        // MCMAX個の容量を確保
        mcresult.reserve(MCMAX);

        // MCMAX回のループを並列化して実行
        tbb::parallel_for(
            std::uint32_t(0),
            MCMAX,
            std::uint32_t(1),
            [&mcresult](auto) { mcresult.push_back(montecarloImpl()); });

        // モンテカルロ・シミュレーションの結果を返す
        return mcresult;
    }
}
<commit_msg>中央値、最頻値、標準偏差を求めるようにした<commit_after>#include "../checkpoint/checkpoint.h"
#include "myrandom/myrand.h"
#include <algorithm>                            // for std::shuffle
#include <cstdint>                              // for std::int32_t
#include <cmath>                                // for std::sqrt
#include <iostream>                             // for std::cout
#include <random>                               // for std::mt19937
#include <unordered_map>                        // for std::unordered_map
#include <utility>                              // for std::make_pair
#include <vector>                               // for std::vector
#include <boost/algorithm/cxx11/iota.hpp>       // for boost::algorithm::iota
#include <boost/format.hpp>                     // for boost::format
#include <boost/range/algorithm.hpp>            // for boost::find, boost::for_each, boost::max_element, boost::transform
#include <boost/range/numeric.hpp>              // for boost::accumulate
#include <tbb/concurrent_vector.h>              // for tbb::concurrent_vector
#include <tbb/parallel_for.h>                   // for tbb::parallel_for

namespace {
    //! A global variable (constant expression).
    /*!
        列のサイズ
    */
    static auto constexpr COLUMN = 5U;

    //! A global variable (constant expression).
    /*!
        行のサイズ
    */
    static auto constexpr ROW = 5U;

    //! A global variable (constant expression).
    /*!
        ビンゴボードのマス数
    */
    static auto constexpr BOARDSIZE = ROW * COLUMN;

    //! A global variable (constant expression).
    /*!
        モンテカルロシミュレーションの試行回数
    */
    static auto constexpr MCMAX = 1000000U;

    //! A global variable (constant expression).
    /*!
        行・列の総数
    */
    static auto constexpr ROWCOLUMN = ROW + COLUMN;

    //! A typedef.
    /*!
        そのマスに書かれてある番号と、そのマスが当たったかどうかを示すフラグ
        のstd::pair
    */
    using mypair = std::pair<std::int32_t, bool>;

    //! A typedef.
    /*!
        行・列が埋まるまでに要した回数と、その時点で埋まったマスのstd::pair
    */
    using mypair2 = std::pair<std::int32_t, std::int32_t>;

    //! A function.
    /*!
        10個目の行・列が埋まったときの中央値を求める
        \param mcresult モンテカルロ・シミュレーションの結果が格納された二次元可変長配列
        \return 10個目の行・列が埋まったときの中央値
    */
    std::int32_t eval_median(std::vector< std::vector<mypair2> > const & mcresult);

    //! A function.
    /*!
        10個目の行・列が埋まったときの最頻値を求める
        \param mcresult モンテカルロ・シミュレーションの結果が格納された二次元可変長配列
        \return 10個目の行・列が埋まったときの最頻値
    */
    std::int32_t eval_mode(std::vector< std::vector<mypair2> > const & mcresult);

    //! A function.
    /*!
        10個目の行・列が埋まったときの最頻値を求める
        \param avgten 10個目の行・列が埋まったときの平均試行回数
        \param mcresult モンテカルロ・シミュレーションの結果が格納された二次元可変長配列
        \return 10個目の行・列が埋まったときの標準偏差
    */
    double eval_std_deviation(double avgten, std::vector< std::vector<mypair2> > const & mcresult);

    //! A function.
    /*!
        ビンゴボードを生成する
        \return ビンゴボードが格納された可変長配列
    */
    auto makeBoard();

    //! A function.
    /*!
        モンテカルロ・シミュレーションを行う
        \return モンテカルロ・シミュレーションの結果が格納された二次元可変長配列
    */
    std::vector< std::vector<mypair2> > montecarlo();

    //! A function.
    /*!
        モンテカルロ・シミュレーションの実装
        \return モンテカルロ法の結果が格納された可変長配列
    */
    std::vector<mypair2> montecarloImpl();

    //! A function.
    /*!
        モンテカルロ・シミュレーションをTBBで並列化して行う
        \return モンテカルロ・シミュレーションの結果が格納された二次元可変長配列
    */
    tbb::concurrent_vector< std::vector<mypair2> > montecarloTBB();
}

int main()
{
    checkpoint::CheckPoint cp;

    cp.checkpoint("処理開始", __LINE__);

    // モンテカルロ・シミュレーションの結果を代入
    auto const mcresult(montecarlo());

    cp.checkpoint("並列化無効", __LINE__);

    // TBBで並列化したモンテカルロ・シミュレーションの結果を代入
    auto const mcresult2(montecarloTBB());

    cp.checkpoint("並列化有効", __LINE__);

    // モンテカルロ・シミュレーションの平均試行回数の結果を格納した可変長配列
    std::vector<double> trialavg(ROWCOLUMN);

    // モンテカルロ・シミュレーションのi回目の試行で、埋まっているマスの数を格納した可変長配列
    std::vector<double> fillavg(ROWCOLUMN);

    // 行・列の総数分繰り返す
    for (auto i = 0U; i < ROWCOLUMN; i++) {
        // 総和を0で初期化
        auto trialsum = 0;
        auto fillsum = 0;

        // 試行回数分繰り返す
        for (auto j = 0U; j < MCMAX; j++) {
            // j回目の結果を加える
            trialsum += mcresult[j][i].first;
            fillsum += mcresult[j][i].second;
        }

        // 平均を算出してi行・列目のtrialavg、fillavgに代入
        trialavg[i] = static_cast<double>(trialsum) / static_cast<double>(MCMAX);
        fillavg[i] = static_cast<double>(fillsum) / static_cast<double>(MCMAX);
    }

    for (auto i = 0U; i < ROWCOLUMN; i++) {
        auto const efficiency = trialavg[i] / static_cast<double>(i + 1);
        std::cout
            << boost::format("%d個目に必要な平均試行回数：%.1f回, 効率：%.1f(回/個), ")
            % (i + 1) % trialavg[i] % efficiency
            << boost::format("埋まっているマスの平均個数：%.1f個\n")
            % fillavg[i];
    }

    std::cout <<
        boost::format("10個目に必要な中央値：%d回, 最頻値：%d回, 標準偏差：%.1f")
            % eval_median(mcresult)
            % eval_mode(mcresult)
            % eval_std_deviation(trialavg[ROWCOLUMN - 1], mcresult) << std::endl;

    cp.checkpoint("それ以外の処理", __LINE__);

    cp.checkpoint_print();

    return 0;
}

namespace {
    std::int32_t eval_median(std::vector< std::vector<mypair2> > const & mcresult)
    {
        std::vector<std::int32_t> medtmp(MCMAX);

        boost::transform(
            mcresult,
            medtmp.begin(),
            [](auto const & res) { return res[ROWCOLUMN - 1].first; });

        boost::sort(medtmp);

        if (MCMAX % 2) {
            return medtmp[(MCMAX - 1) / 2];
        }
        else {
            return (medtmp[(MCMAX / 2) - 1] + medtmp[MCMAX / 2]) / 2;
        }
    }

    std::int32_t eval_mode(std::vector< std::vector<mypair2> > const & mcresult)
    {
        std::unordered_map<std::int32_t, std::int32_t> modetmp;

        boost::for_each(
            mcresult,
            [&modetmp](auto const & res) {
                auto const val = res[ROWCOLUMN - 1].first;
                if (modetmp.find(val) == modetmp.end()) {
                    modetmp.emplace(val, 1);
                }
                else {
                    modetmp[val]++;
                }
        });

        auto const res = boost::max_element(
            modetmp,
            [](auto const & p1, auto const & p2) { return p1.second < p2.second; });

        return res->first;
    }

    double eval_std_deviation(double avgten, std::vector< std::vector<mypair2> > const & mcresult)
    {
        std::vector<double> devtmp(MCMAX);

        boost::transform(
            mcresult,
            devtmp.begin(),
            [avgten](auto const & res) {
                auto const val = static_cast<double>(res[ROWCOLUMN - 1].first);
                return (val - avgten) * (val - avgten);
        });

        return std::sqrt(boost::accumulate(devtmp, 0.0) / static_cast<double>(MCMAX));
    }

    auto makeBoard()
    {
        // 仮のビンゴボードを生成
        std::vector<std::int32_t> boardtmp(BOARDSIZE);

        // 仮のビンゴボードに1～25の数字を代入
        boost::algorithm::iota(boardtmp, 1);

        // 仮のビンゴボードの数字をシャッフル
        std::shuffle(boardtmp.begin(), boardtmp.end(), std::mt19937());

        // ビンゴボードを生成
        std::vector<mypair> board(BOARDSIZE);

        // 仮のビンゴボードからビンゴボードを生成する
        boost::transform(
            boardtmp,
            board.begin(),
            [](auto n) { return std::make_pair(n, false); });

        // ビンゴボードを返す
        return board;
    }

    std::vector< std::vector<mypair2> > montecarlo()
    {
        // モンテカルロ・シミュレーションの結果を格納するための二次元可変長配列
        std::vector< std::vector<mypair2> > mcresult;

        // MCMAX個の容量を確保
        mcresult.reserve(MCMAX);

        // 試行回数分繰り返す
        for (auto i = 0U; i < MCMAX; i++) {
            // モンテカルロ・シミュレーションの結果を代入
            mcresult.push_back(montecarloImpl());
        }

        // モンテカルロ・シミュレーションの結果を返す
        return mcresult;
    }

    std::vector<mypair2> montecarloImpl()
    {
        // ビンゴボードを生成
        auto board(makeBoard());

        // 自作乱数クラスを初期化
        myrandom::MyRand mr(1, BOARDSIZE);

        // その行・列が既に埋まっているかどうかを格納する可変長配列
        // ROWCOLUMN個の要素をfalseで初期化
        std::vector<bool> rcfill(ROWCOLUMN, false);

        // 行・列が埋まるまでに要した回数と、その時点で埋まったマスを格納した
        // 可変長配列
        std::vector<mypair2> fillnum;

        // ROWCOLUMN個の容量を確保
        fillnum.reserve(ROWCOLUMN);

        // その時点で埋まっているマスを計算するためのラムダ式
        auto const sum = [](auto const & vec) {
            auto cnt = 0;
            for (auto & e : vec) {
                if (e.second) {
                    cnt++;
                }
            }

            return cnt;
        };

        // 無限ループ
        for (auto i = 1; ; i++) {
            // 乱数で得た数字で、かつまだ当たってないマスを検索
            auto itr = boost::find(board, std::make_pair(mr.myrand(), false));

            // そのようなマスがあった
            if (itr != board.end()) {
                // そのマスは当たったとし、フラグをtrueにする
                itr->second = true;
            }
            // そのようなマスがなかった
            else {
                //ループ続行
                continue;
            }

            // 各行・列が埋まったかどうかをチェック
            for (auto j = 0U; j < ROW; j++) {
                // 各行が埋まったかどうかのフラグ
                auto rowflag = true;

                // 各行が埋まったかどうかをチェック
                for (auto k = 0U; k < COLUMN; k++) {
                    rowflag &= board[COLUMN * j + k].second;
                }

                // 行の処理
                if (rowflag &&
                    // その行は既に埋まっているかどうか
                    !rcfill[j]) {
                    // その行は埋まったとして、フラグをtrueにする
                    rcfill[j] = true;

                    // 要した試行回数と、その時点で埋まったマスの数を格納
                    fillnum.push_back(std::make_pair(i, sum(board)));
                }

                // 各列が埋まったかどうかのフラグ
                auto columnflag = true;

                // 各列が埋まったかどうかをチェック
                for (auto k = 0U; k < ROW; k++) {
                    columnflag &= board[j + COLUMN * k].second;
                }

                // 列の処理
                if (columnflag &&
                    // その列は既に埋まっているかどうか
                    !rcfill[j + ROW]) {

                    // その列は埋まったとして、フラグをtrueにする
                    rcfill[j + ROW] = true;

                    // 要した試行回数と、その時点で埋まったマスの数を格納
                    fillnum.push_back(std::make_pair(i, sum(board)));
                }
            }

            // 全ての行・列が埋まったかどうか
            if (fillnum.size() == ROWCOLUMN) {
                // 埋まったのでループ脱出
                break;
            }
        }

        // 要した試行関数の可変長配列を返す
        return fillnum;
    }

    tbb::concurrent_vector< std::vector<mypair2> > montecarloTBB()
    {
        // モンテカルロ・シミュレーションの結果を格納するための二次元可変長配列
        // 複数のスレッドが同時にアクセスする可能性があるためtbb::concurrent_vectorを使う
        tbb::concurrent_vector< std::vector<mypair2> > mcresult;

        // MCMAX個の容量を確保
        mcresult.reserve(MCMAX);

        // MCMAX回のループを並列化して実行
        tbb::parallel_for(
            std::uint32_t(0),
            MCMAX,
            std::uint32_t(1),
            [&mcresult](auto) { mcresult.push_back(montecarloImpl()); });

        // モンテカルロ・シミュレーションの結果を返す
        return mcresult;
    }
}
<|endoftext|>


<commit_before>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkColorPriv.h"
#include "SkColorFilter.h"
#include "SkPicture.h"
#include "SkTypeface.h"

// effects
#include "SkGradientShader.h"
#include "SkUnitMappers.h"
#include "SkBlurMask.h"
#include "SkBlurDrawLooper.h"

static void makebm(SkBitmap* bm, SkColorType ct, int w, int h) {
    bm->allocPixels(SkImageInfo::Make(w, h, ct, kPremul_SkAlphaType));
    bm->eraseColor(SK_ColorTRANSPARENT);

    SkCanvas    canvas(*bm);
    SkPoint     pts[] = { { 0, 0 }, { SkIntToScalar(w), SkIntToScalar(h) } };
    SkColor     colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
    SkScalar    pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
    SkPaint     paint;

    SkUnitMapper*   um = NULL;

    um = new SkCosineMapper;
//    um = new SkDiscreteMapper(12);

    SkAutoUnref au(um);

    paint.setDither(true);
    paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos,
                SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode, um))->unref();
    canvas.drawPaint(paint);
}

static void setup(SkPaint* paint, const SkBitmap& bm, bool filter,
                  SkShader::TileMode tmx, SkShader::TileMode tmy) {
    SkShader* shader = SkShader::CreateBitmapShader(bm, tmx, tmy);
    paint->setShader(shader)->unref();
    paint->setFilterLevel(filter ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
}

static const SkColorType gColorTypes[] = {
    kN32_SkColorType,
    kRGB_565_SkColorType,
};
static const int gWidth = 32;
static const int gHeight = 32;

class TilingView : public SampleView {
    SkAutoTUnref<SkPicture>        fTextPicture;
    SkAutoTUnref<SkBlurDrawLooper> fLooper;
public:
    TilingView()
            : fLooper(SkBlurDrawLooper::Create(0x88000000,
                                               SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(1)),
                                               SkIntToScalar(2), SkIntToScalar(2))) {
        for (size_t i = 0; i < SK_ARRAY_COUNT(gColorTypes); i++) {
            makebm(&fTexture[i], gColorTypes[i], gWidth, gHeight);
        }
    }

    virtual ~TilingView() {
    }

    SkBitmap    fTexture[SK_ARRAY_COUNT(gColorTypes)];

protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "Tiling");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    virtual void onDrawContent(SkCanvas* canvas) {
        SkRect r = { 0, 0, SkIntToScalar(gWidth*2), SkIntToScalar(gHeight*2) };

        static const char* gConfigNames[] = { "8888", "565", "4444" };

        static const bool           gFilters[] = { false, true };
        static const char*          gFilterNames[] = {     "point",                     "bilinear" };

        static const SkShader::TileMode gModes[] = { SkShader::kClamp_TileMode, SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode };
        static const char*          gModeNames[] = {    "C",                    "R",                   "M" };

        SkScalar y = SkIntToScalar(24);
        SkScalar x = SkIntToScalar(10);

        SkPictureRecorder recorder;
        SkCanvas* textCanvas = NULL;
        if (fTextPicture->width() == 0) {
            textCanvas = recorder.beginRecording(1000, 1000);
        }

        if (NULL != textCanvas) {
            for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
                for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
                    SkPaint p;
                    SkString str;
                    p.setAntiAlias(true);
                    p.setDither(true);
                    p.setLooper(fLooper);
                    str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);

                    p.setTextAlign(SkPaint::kCenter_Align);
                    textCanvas->drawText(str.c_str(), str.size(), x + r.width()/2, y, p);

                    x += r.width() * 4 / 3;
                }
            }
        }

        y += SkIntToScalar(16);

        for (size_t i = 0; i < SK_ARRAY_COUNT(gColorTypes); i++) {
            for (size_t j = 0; j < SK_ARRAY_COUNT(gFilters); j++) {
                x = SkIntToScalar(10);
                for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
                    for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
                        SkPaint paint;
                        setup(&paint, fTexture[i], gFilters[j], gModes[kx], gModes[ky]);
                        paint.setDither(true);

                        canvas->save();
                        canvas->translate(x, y);
                        canvas->drawRect(r, paint);
                        canvas->restore();

                        x += r.width() * 4 / 3;
                    }
                }
                if (textCanvas) {
                    SkPaint p;
                    SkString str;
                    p.setAntiAlias(true);
                    p.setLooper(fLooper);
                    str.printf("%s, %s", gConfigNames[i], gFilterNames[j]);
                    textCanvas->drawText(str.c_str(), str.size(), x, y + r.height() * 2 / 3, p);
                }

                y += r.height() * 4 / 3;
            }
        }

        fTextPicture.reset(recorder.endRecording());

        canvas->drawPicture(*fTextPicture);
    }

private:
    typedef SampleView INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static SkView* MyFactory() { return new TilingView; }
static SkViewRegister reg(MyFactory);
<commit_msg>Fix bug in SampleApp's Tiling View<commit_after>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkColorPriv.h"
#include "SkColorFilter.h"
#include "SkPicture.h"
#include "SkTypeface.h"

// effects
#include "SkGradientShader.h"
#include "SkUnitMappers.h"
#include "SkBlurMask.h"
#include "SkBlurDrawLooper.h"

static void makebm(SkBitmap* bm, SkColorType ct, int w, int h) {
    bm->allocPixels(SkImageInfo::Make(w, h, ct, kPremul_SkAlphaType));
    bm->eraseColor(SK_ColorTRANSPARENT);

    SkCanvas    canvas(*bm);
    SkPoint     pts[] = { { 0, 0 }, { SkIntToScalar(w), SkIntToScalar(h) } };
    SkColor     colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
    SkScalar    pos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
    SkPaint     paint;

    SkUnitMapper*   um = NULL;

    um = new SkCosineMapper;
//    um = new SkDiscreteMapper(12);

    SkAutoUnref au(um);

    paint.setDither(true);
    paint.setShader(SkGradientShader::CreateLinear(pts, colors, pos,
                SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode, um))->unref();
    canvas.drawPaint(paint);
}

static void setup(SkPaint* paint, const SkBitmap& bm, bool filter,
                  SkShader::TileMode tmx, SkShader::TileMode tmy) {
    SkShader* shader = SkShader::CreateBitmapShader(bm, tmx, tmy);
    paint->setShader(shader)->unref();
    paint->setFilterLevel(filter ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
}

static const SkColorType gColorTypes[] = {
    kN32_SkColorType,
    kRGB_565_SkColorType,
};
static const int gWidth = 32;
static const int gHeight = 32;

class TilingView : public SampleView {
    SkAutoTUnref<SkPicture>        fTextPicture;
    SkAutoTUnref<SkBlurDrawLooper> fLooper;
public:
    TilingView()
            : fLooper(SkBlurDrawLooper::Create(0x88000000,
                                               SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(1)),
                                               SkIntToScalar(2), SkIntToScalar(2))) {
        for (size_t i = 0; i < SK_ARRAY_COUNT(gColorTypes); i++) {
            makebm(&fTexture[i], gColorTypes[i], gWidth, gHeight);
        }
    }

    virtual ~TilingView() {
    }

    SkBitmap    fTexture[SK_ARRAY_COUNT(gColorTypes)];

protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "Tiling");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    virtual void onDrawContent(SkCanvas* canvas) {
        SkRect r = { 0, 0, SkIntToScalar(gWidth*2), SkIntToScalar(gHeight*2) };

        static const char* gConfigNames[] = { "8888", "565", "4444" };

        static const bool           gFilters[] = { false, true };
        static const char*          gFilterNames[] = {     "point",                     "bilinear" };

        static const SkShader::TileMode gModes[] = { SkShader::kClamp_TileMode, SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode };
        static const char*          gModeNames[] = {    "C",                    "R",                   "M" };

        SkScalar y = SkIntToScalar(24);
        SkScalar x = SkIntToScalar(10);

        SkPictureRecorder recorder;
        SkCanvas* textCanvas = NULL;
        if (NULL == fTextPicture) {
            textCanvas = recorder.beginRecording(1000, 1000);
        }

        if (NULL != textCanvas) {
            for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
                for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
                    SkPaint p;
                    SkString str;
                    p.setAntiAlias(true);
                    p.setDither(true);
                    p.setLooper(fLooper);
                    str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]);

                    p.setTextAlign(SkPaint::kCenter_Align);
                    textCanvas->drawText(str.c_str(), str.size(), x + r.width()/2, y, p);

                    x += r.width() * 4 / 3;
                }
            }
        }

        y += SkIntToScalar(16);

        for (size_t i = 0; i < SK_ARRAY_COUNT(gColorTypes); i++) {
            for (size_t j = 0; j < SK_ARRAY_COUNT(gFilters); j++) {
                x = SkIntToScalar(10);
                for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) {
                    for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) {
                        SkPaint paint;
                        setup(&paint, fTexture[i], gFilters[j], gModes[kx], gModes[ky]);
                        paint.setDither(true);

                        canvas->save();
                        canvas->translate(x, y);
                        canvas->drawRect(r, paint);
                        canvas->restore();

                        x += r.width() * 4 / 3;
                    }
                }
                if (NULL != textCanvas) {
                    SkPaint p;
                    SkString str;
                    p.setAntiAlias(true);
                    p.setLooper(fLooper);
                    str.printf("%s, %s", gConfigNames[i], gFilterNames[j]);
                    textCanvas->drawText(str.c_str(), str.size(), x, y + r.height() * 2 / 3, p);
                }

                y += r.height() * 4 / 3;
            }
        }

        if (NULL != textCanvas) {
            SkASSERT(NULL == fTextPicture);
            fTextPicture.reset(recorder.endRecording());
        }

        SkASSERT(NULL != fTextPicture);
        canvas->drawPicture(*fTextPicture);
    }

private:
    typedef SampleView INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static SkView* MyFactory() { return new TilingView; }
static SkViewRegister reg(MyFactory);
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015-2017 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * For use for simulation and test purposes only
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder 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 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 __ARCH_GCN3_REGISTERS_HH__
#define __ARCH_GCN3_REGISTERS_HH__

#include <array>
#include <cstdint>
#include <string>

#include "arch/generic/vec_reg.hh"
#include "base/intmath.hh"
#include "base/logging.hh"

namespace gem5
{

namespace Gcn3ISA
{
    enum OpSelector : int
    {
        REG_SGPR_MIN = 0,
        REG_SGPR_MAX = 101,
        REG_FLAT_SCRATCH_LO = 102,
        REG_FLAT_SCRATCH_HI = 103,
        REG_XNACK_MASK_LO = 104,
        REG_XNACK_MASK_HI = 105,
        REG_VCC_LO = 106,
        REG_VCC_HI = 107,
        REG_TBA_LO = 108,
        REG_TBA_HI = 109,
        REG_TMA_LO = 110,
        REG_TMA_HI = 111,
        REG_TTMP_0 = 112,
        REG_TTMP_1 = 113,
        REG_TTMP_2 = 114,
        REG_TTMP_3 = 115,
        REG_TTMP_4 = 116,
        REG_TTMP_5 = 117,
        REG_TTMP_6 = 118,
        REG_TTMP_7 = 119,
        REG_TTMP_8 = 120,
        REG_TTMP_9 = 121,
        REG_TTMP_10 = 122,
        REG_TTMP_11 = 123,
        REG_M0 = 124,
        REG_RESERVED_1 = 125,
        REG_EXEC_LO = 126,
        REG_EXEC_HI = 127,
        REG_ZERO = 128,
        REG_INT_CONST_POS_MIN = 129,
        REG_INT_CONST_POS_MAX = 192,
        REG_INT_CONST_NEG_MIN = 193,
        REG_INT_CONST_NEG_MAX = 208,
        REG_RESERVED_2 = 209,
        REG_RESERVED_3 = 210,
        REG_RESERVED_4 = 211,
        REG_RESERVED_5 = 212,
        REG_RESERVED_6 = 213,
        REG_RESERVED_7 = 214,
        REG_RESERVED_8 = 215,
        REG_RESERVED_9 = 216,
        REG_RESERVED_10 = 217,
        REG_RESERVED_11 = 218,
        REG_RESERVED_12 = 219,
        REG_RESERVED_13 = 220,
        REG_RESERVED_14 = 221,
        REG_RESERVED_15 = 222,
        REG_RESERVED_16 = 223,
        REG_RESERVED_17 = 224,
        REG_RESERVED_18 = 225,
        REG_RESERVED_19 = 226,
        REG_RESERVED_20 = 227,
        REG_RESERVED_21 = 228,
        REG_RESERVED_22 = 229,
        REG_RESERVED_23 = 230,
        REG_RESERVED_24 = 231,
        REG_RESERVED_25 = 232,
        REG_RESERVED_26 = 233,
        REG_RESERVED_27 = 234,
        REG_RESERVED_28 = 235,
        REG_RESERVED_29 = 236,
        REG_RESERVED_30 = 237,
        REG_RESERVED_31 = 238,
        REG_RESERVED_32 = 239,
        REG_POS_HALF = 240,
        REG_NEG_HALF = 241,
        REG_POS_ONE = 242,
        REG_NEG_ONE = 243,
        REG_POS_TWO = 244,
        REG_NEG_TWO = 245,
        REG_POS_FOUR = 246,
        REG_NEG_FOUR = 247,
        REG_PI = 248,
        /* NOTE: SDWA and SWDA both refer to sub d-word addressing */
        REG_SRC_SWDA = 249,
        REG_SRC_DPP = 250,
        REG_VCCZ = 251,
        REG_EXECZ = 252,
        REG_SCC = 253,
        REG_LDS_DIRECT = 254,
        REG_SRC_LITERAL = 255,
        REG_VGPR_MIN = 256,
        REG_VGPR_MAX = 511
    };

    constexpr size_t MaxOperandDwords(16);
    const int NumVecElemPerVecReg(64);
    // op selector values 129 - 192 correspond to const values 1 - 64
    const int NumPosConstRegs = REG_INT_CONST_POS_MAX
        - REG_INT_CONST_POS_MIN + 1;
    // op selector values 193 - 208 correspond to const values -1 - 16
    const int NumNegConstRegs = REG_INT_CONST_NEG_MAX
        - REG_INT_CONST_NEG_MIN + 1;
    const int BITS_PER_BYTE = 8;
    const int BITS_PER_WORD = 16;
    const int MSB_PER_BYTE = (BITS_PER_BYTE - 1);
    const int MSB_PER_WORD = (BITS_PER_WORD - 1);

    // typedefs for the various sizes/types of scalar regs
    typedef uint8_t ScalarRegU8;
    typedef int8_t ScalarRegI8;
    typedef uint16_t ScalarRegU16;
    typedef int16_t ScalarRegI16;
    typedef uint32_t ScalarRegU32;
    typedef int32_t ScalarRegI32;
    typedef float ScalarRegF32;
    typedef uint64_t ScalarRegU64;
    typedef int64_t ScalarRegI64;
    typedef double ScalarRegF64;

    // typedefs for the various sizes/types of vector reg elements
    typedef uint8_t VecElemU8;
    typedef int8_t VecElemI8;
    typedef uint16_t VecElemU16;
    typedef int16_t VecElemI16;
    typedef uint32_t VecElemU32;
    typedef int32_t VecElemI32;
    typedef float VecElemF32;
    typedef uint64_t VecElemU64;
    typedef int64_t VecElemI64;
    typedef double VecElemF64;

    const int DWORDSize = sizeof(VecElemU32);
    /**
     * Size of a single-precision register in DWORDs.
     */
    const int RegSizeDWORDs = sizeof(VecElemU32) / DWORDSize;

    using VecRegContainerU32 =
        VecRegContainer<sizeof(VecElemU32) * NumVecElemPerVecReg>;

    struct StatusReg
    {
        StatusReg() : SCC(0), SPI_PRIO(0), USER_PRIO(0), PRIV(0), TRAP_EN(0),
            TTRACE_EN(0), EXPORT_RDY(0), EXECZ(0), VCCZ(0), IN_TG(0),
            IN_BARRIER(0), HALT(0), TRAP(0), TTRACE_CU_EN(0), VALID(0),
            ECC_ERR(0), SKIP_EXPORT(0), PERF_EN(0), COND_DBG_USER(0),
            COND_DBG_SYS(0), ALLOW_REPLAY(0), INSTRUCTION_ATC(0), RESERVED(0),
            MUST_EXPORT(0), RESERVED_1(0)
        {
        }

        uint32_t SCC : 1;
        uint32_t SPI_PRIO : 2;
        uint32_t USER_PRIO : 2;
        uint32_t PRIV : 1;
        uint32_t TRAP_EN : 1;
        uint32_t TTRACE_EN : 1;
        uint32_t EXPORT_RDY : 1;
        uint32_t EXECZ : 1;
        uint32_t VCCZ : 1;
        uint32_t IN_TG : 1;
        uint32_t IN_BARRIER : 1;
        uint32_t HALT : 1;
        uint32_t TRAP : 1;
        uint32_t TTRACE_CU_EN : 1;
        uint32_t VALID : 1;
        uint32_t ECC_ERR : 1;
        uint32_t SKIP_EXPORT : 1;
        uint32_t PERF_EN : 1;
        uint32_t COND_DBG_USER : 1;
        uint32_t COND_DBG_SYS : 1;
        uint32_t ALLOW_REPLAY : 1;
        uint32_t INSTRUCTION_ATC : 1;
        uint32_t RESERVED : 3;
        uint32_t MUST_EXPORT : 1;
        uint32_t RESERVED_1 : 4;
    };

    std::string opSelectorToRegSym(int opIdx, int numRegs=0);
    int opSelectorToRegIdx(int opIdx, int numScalarRegs);
    bool isPosConstVal(int opIdx);
    bool isNegConstVal(int opIdx);
    bool isConstVal(int opIdx);
    bool isLiteral(int opIdx);
    bool isScalarReg(int opIdx);
    bool isVectorReg(int opIdx);
    bool isFlatScratchReg(int opIdx);
    bool isExecMask(int opIdx);
    bool isVccReg(int opIdx);
} // namespace Gcn3ISA
} // namespace gem5

#endif // __ARCH_GCN3_REGISTERS_HH__
<commit_msg>arch-gcn3: Delete extraneous registers header<commit_after><|endoftext|>


<commit_before>/*************************************************************************
    > File Name: connection.cpp
    > Author: sudoku.huang
    > Mail: sudoku.huang@gmail.com
    > Created Time: Monday, December 26, 2016 PM03:06:43 CST
 ************************************************************************/

#include "connection.h"
#include <ulog/ulog.h>
#include <utools/ustring.h>
#include <stdlib.h>
#include <string.h>
#include "lbsdb.h"

const CLbsConnection::handler_type CLbsConnection::handlers[] = {
    {"/favicon.ico",    &CLbsConnection::favicon},
    {"/tysetcpu",       &CLbsConnection::setcpu},
    {"/tyshowlive",     &CLbsConnection::dump},
    {NULL, NULL},
};

CLbsConnection::CLbsConnection(const LbsConf_t & config, CLbsMonitor & monitor,
        uschedule & schudule, int fd, const char * ip)
    : config_(config)
    , monitor_(monitor)
    , schudule_(schudule)
    , socket_(1024, fd, &schudule_)
    , peerip_(ip)
    , http_(socket_, *this, false, false, true)
{
    socket_.set_timeout(30 * 1000); // 60s
}

CLbsConnection::~CLbsConnection()
{
}

void CLbsConnection::run()
{
    http_.run();
    monitor_.onDisconnect(socket_.socket());
    ulog(ulog_debug, "disconnect to fd:%d, (%s)!\n",
        socket_.socket(), peerip_.c_str());
    ::close(socket_.socket());
    delete this;
}

int CLbsConnection::onhttp(const uhttprequest & request,
    uhttpresponse & response, int errcode)
{
    if (errcode == uhttp::en_socket_reset) {
        ulog(ulog_debug, "socket reset by peer(%s)!\n", peerip_.c_str());
        return -1;
    }

    if (request.method() == uhttp_method_unknown) {
        ulog(ulog_error, "unknown request from (%s)!\n", peerip_.c_str());
        return -1;
    }

    const std::string & path = request.uri().path();
    const CLbsConnection::handler_type * h;
    int ret = 0;

    for (h = handlers; h->cmd != NULL; h ++) {
        if (strcmp(h->cmd, path.c_str()) == 0) {
            ulog(ulog_debug, "find handler for path:%s\n", h->cmd);
            break;
        }
    }

    if (h->cmd == NULL) {
        if (get(request, response, errcode) != 0) {
            ulog(ulog_error, "unknown request from(%s):%s\n",
                peerip_.c_str(), path.c_str());
            ret = notfind(request, response, errcode);
        } else {
            ret = 0;
        }
    } else {
        handler hf = h->func;
        ret = (this->*hf)(request, response, errcode);
    }
    return ret;
}

int CLbsConnection::favicon(const uhttprequest & request,
    uhttpresponse & response, int errcode)
{
    ulog(ulog_debug, "favicon request!\n");
    response.set_statuscode(uhttp_status_ok);
    response.set_header(uhttpresponse::HEADER_CONTENT_TYPE, "text/html");

    return 0;
}

int CLbsConnection::notfind(const uhttprequest & request,
    uhttpresponse & response, int errcode)
{
    ulog(ulog_debug, "notfind!\n");
    response.set_statuscode(uhttp_status_not_found);

    response.set_header(uhttpresponse::HEADER_CONTENT_TYPE, "text/html");
    response.set_content("
404 Not Found!
");

    return -1;
}

int CLbsConnection::setcpu(const uhttprequest & request,
    uhttpresponse & response, int errcode)
{
    ulog(ulog_debug, "setcpu!\n");
    #if 0 //debug
    static std::vector<std::string> services;
    if (services.empty()) {
        services.resize(10);
        services[2] = "media";
        services[9] = "publisher";
    }
    #else
    const std::vector<std::string> & services = config_.services;
    #endif

    const uuri & uri = request.uri();

    std::map<std::string, std::string> limits = uri.query();

    std::string dxip = limits["dx"];
    std::string ltip = limits["lt"];
    std::string ydip = limits["yd"];
    std::string area = limits["area"];

    int band = atoi(limits["band"].c_str());;
    int net  = atoi(limits["net"].c_str());

    limits.erase("port");   //remove client listen port. no need!
    limits.erase("dx");
    limits.erase("lt");
    limits.erase("yd");
    limits.erase("area");
    limits.erase("band");
    limits.erase("net");
    if (net == 0 && band != 0) {
        limits["net"] = band;
    }

    if (area.empty()) {
        return -1;
    }

    std::map<std::string, std::string> service2port;
    typedef std::map<std::string, std::string>::iterator const_ssit;

    for (size_t i = 0; i < services.size(); i++) {
        if (services[i].empty()) {
            continue;
        }

        const_ssit it = limits.find(services[i]);
        if (it != limits.end()) {
            service2port[it->first] = it->second;
            limits.erase(it);
        }
    }

    std::map<std::string, int> limitsint;
    for (const_ssit it = limits.begin(); it != limits.end(); ++it) {
        ulog(ulog_debug, "limits, %s --> %s\n", it->first.c_str(), it->second.c_str());
        limitsint[it->first] = atoi(it->second.c_str());
    }

    uint32 dxuip = str2ip(dxip.c_str());
    uint32 ltuip = str2ip(ltip.c_str());
    uint32 yduip = str2ip(ydip.c_str());

    int flag1 = 0, flag2 = 0, flag3 = 0;
    if (dxuip != 0) {
        flag1 |= en_ctc_flag;
        if (ltuip == dxuip) {
            flag1 |= en_cuc_flag;
            ltuip = 0;
        }
        if (yduip == dxuip) {
            flag1 |= en_cmc_flag;
            yduip = 0;
        }
    }

    if (ltuip != 0) {
        flag2 |= en_cuc_flag;
        if (yduip == ltuip) {
            flag2 |= en_cmc_flag;
            yduip = 0;
        }
    }

    if (yduip != 0) {
        flag3 |= en_cmc_flag;
    }

    for (const_ssit it = service2port.begin(); it != service2port.end(); ++ it) {
        std::vector<std::string> vport;
        split(it->second.c_str(), ',', vport);

        for (size_t i = 0; i < vport.size(); i++) {
            int port = atoi(vport[i].c_str());
            if (port == 0) {
                continue;
            }

            if (dxuip != 0) {
                monitor_.onNewNode(it->first, dxuip, port, flag1, area, limitsint);
            }

            if (ltuip != 0) {
                monitor_.onNewNode(it->first, ltuip, port, flag2, area, limitsint);
            }

            if (yduip != 0) {
                monitor_.onNewNode(it->first, yduip, port, flag3, area, limitsint);
            }
        }
    }

    {
        char * rdbuf = (char *)malloc(1024);
        int net, cpu, id, port;
        std::map<std::string, int> loading;

        while (socket_.getline(rdbuf, 1024).good()) {
            loading.clear();

            ulog(ulog_debug, "contine(%s):%s\n", peerip_.c_str(), rdbuf);

            if (sscanf(rdbuf, "net%d", &net) == 1) {
                loading["net"] = net;

                for (const_ssit it = service2port.begin();
                    it != service2port.end(); ++ it) {
                    std::vector<std::string> vport;
                    split(it->second.c_str(), ',', vport);

                    for (size_t i = 0; i < vport.size(); i++) {
                        int port = atoi(vport[i].c_str());
                        if (port == 0) {
                            continue;
                        }

                        if (dxuip != 0) {
                            monitor_.onNewNode(it->first, dxuip, port, flag1,
                                area, limitsint);
                            monitor_.onUptNode(it->first, dxuip, port, loading);
                        }

                        if (ltuip != 0) {
                            monitor_.onNewNode(it->first, ltuip, port, flag2,
                                area, limitsint);
                            monitor_.onUptNode(it->first, ltuip, port, loading);
                        }

                        if (yduip != 0) {
                            monitor_.onNewNode(it->first, yduip, port, flag3,
                                area, limitsint);
                            monitor_.onUptNode(it->first, yduip, port, loading);
                        }
                    }
                }

            } else if (sscanf(rdbuf, "del%d %d", &id, &port) == 2) {
                std::string service = services[id];
                if (dxuip != 0) {
                    monitor_.onDelNode(service, dxuip, port);
                }

                if (ltuip != 0) {
                    monitor_.onDelNode(service, ltuip, port);
                }

                if (yduip != 0) {
                    monitor_.onDelNode(service, yduip, port);
                }
                continue;
            } else if (sscanf(rdbuf, "cpu%d %d %d", &id, &port, &cpu) == 3) {
                loading["cpu"] = cpu;
                std::string service = services[id];

                if (dxuip != 0) {
                    monitor_.onUptNode(service, dxuip, port, loading);
                }

                if (ltuip != 0) {
                    monitor_.onUptNode(service, ltuip, port, loading);
                }

                if (yduip != 0) {
                    monitor_.onUptNode(service, yduip, port, loading);
                }
            } else {
                continue;
            }
        }

        free(rdbuf);
    }

    //disconnect

    for (const_ssit it = service2port.begin(); it != service2port.end(); ++ it) {

        std::vector<std::string> vport;
        split(it->second.c_str(), ',', vport);

        for (size_t i = 0; i < vport.size(); i++) {
            int port = atoi(vport[i].c_str());
            if (port == 0) {
                continue;
            }

            if (dxuip != 0) {
                ulog(ulog_info, "service[%s] addr[%s:%d:%d] disconnect!\n",
                    it->first.c_str(), dxip.c_str(), port, flag1);
                monitor_.onDelNode(it->first, dxuip, port);
            }

            if (ltuip != 0) {
                ulog(ulog_info, "service[%s] addr[%s:%d:%d] disconnect!\n",
                    it->first.c_str(), ltip.c_str(), port, flag2);
                monitor_.onDelNode(it->first, ltuip, port);
            }

            if (yduip != 0) {
                ulog(ulog_info, "service[%s] addr[%s:%d:%d] disconnect!\n",
                    it->first.c_str(), ydip.c_str(), port, flag3);
                monitor_.onDelNode(it->first, yduip, port);
            }
        }
    }

    return -1;
}

int CLbsConnection::dump(const uhttprequest & request,
    uhttpresponse & response, int errcode)
{
    std::string out;
    monitor_.onDump(out);
    response.set_content(out);

    response.set_statuscode(uhttp_status_ok);

    response.set_header(uhttpresponse::HEADER_CONTENT_TYPE, "text/html");
    return 0;
}

int CLbsConnection::get(const uhttprequest & request,
    uhttpresponse & response, int errcode)
{
    // handle proxy ???
    std::string service;
    uint32 uip = str2ip(peerip_.c_str());
    const std::string & path = request.uri().path();

    ulog(ulog_debug, "get path:%s, prefix:%s\n", path.c_str(), config_.prefix.c_str());

    std::string match = path.substr(1); //skip /
    if (!config_.prefix.empty()) {
        std::string::size_type npos = path.find(config_.prefix);
        if (npos != 1) { //skip root path.
            return -1;
        }
        match = path.substr(npos + config_.prefix.size());
    }

    for (size_t i = 0; i < config_.services.size(); i++) {
        if (config_.services[i].empty()) {
            continue;
        }
        if (strcasecmp(match.c_str(), config_.services[i].c_str()) == 0) {
            service = config_.services[i];
            break;
        }
    }

    if (service.empty()) {
        return -1;
    }

    std::string out;
    monitor_.onGetNode(service, uip, out);
    response.set_content(out);

    //ulog(ulog_info, "service:[%s], client:[%s], out:[%s]\n",
    //    service.c_str(), peerip_.c_str(), out.c_str());

    response.set_statuscode(uhttp_status_ok);

    response.set_header(uhttpresponse::HEADER_CONTENT_TYPE, "text/plain");
    return 0;
}

<commit_msg>1. fix tcp timewait/fin_wait status.<commit_after>/*************************************************************************
    > File Name: connection.cpp
    > Author: sudoku.huang
    > Mail: sudoku.huang@gmail.com
    > Created Time: Monday, December 26, 2016 PM03:06:43 CST
 ************************************************************************/

#include "connection.h"
#include <ulog/ulog.h>
#include <utools/ustring.h>
#include <stdlib.h>
#include <string.h>
#include "lbsdb.h"

const CLbsConnection::handler_type CLbsConnection::handlers[] = {
    {"/favicon.ico",    &CLbsConnection::favicon},
    {"/tysetcpu",       &CLbsConnection::setcpu},
    {"/tyshowlive",     &CLbsConnection::dump},
    {NULL, NULL},
};

CLbsConnection::CLbsConnection(const LbsConf_t & config, CLbsMonitor & monitor,
        uschedule & schudule, int fd, const char * ip)
    : config_(config)
    , monitor_(monitor)
    , schudule_(schudule)
    , socket_(1024, fd, &schudule_)
    , peerip_(ip)
    , http_(socket_, *this, false, false, true)
{
    socket_.set_timeout(30 * 1000); // 60s
}

CLbsConnection::~CLbsConnection()
{
}

void CLbsConnection::run()
{
    http_.run();
    monitor_.onDisconnect(socket_.socket());
    ulog(ulog_debug, "disconnect to fd:%d, (%s)!\n",
        socket_.socket(), peerip_.c_str());

    if (socket_.good()) {
        // if connection is ok, wait 20ms.
        // if client don't close, server close it active.
        char buf;
        socket_.set_timeout(20);
        socket_.read(&buf, 1);
    }

    ::close(socket_.socket());
    delete this;
}

int CLbsConnection::onhttp(const uhttprequest & request,
    uhttpresponse & response, int errcode)
{
    if (errcode == uhttp::en_socket_reset) {
        ulog(ulog_debug, "socket reset by peer(%s)!\n", peerip_.c_str());
        return -1;
    }

    if (request.method() == uhttp_method_unknown) {
        ulog(ulog_error, "unknown request from (%s)!\n", peerip_.c_str());
        return -1;
    }

    const std::string & path = request.uri().path();
    const CLbsConnection::handler_type * h;
    int ret = 0;

    for (h = handlers; h->cmd != NULL; h ++) {
        if (strcmp(h->cmd, path.c_str()) == 0) {
            ulog(ulog_debug, "find handler for path:%s\n", h->cmd);
            break;
        }
    }

    if (h->cmd == NULL) {
        if (get(request, response, errcode) != 0) {
            ulog(ulog_error, "unknown request from(%s):%s\n",
                peerip_.c_str(), path.c_str());
            ret = notfind(request, response, errcode);
        } else {
            ret = 0;
        }
    } else {
        handler hf = h->func;
        ret = (this->*hf)(request, response, errcode);
    }

    return ret;
}

int CLbsConnection::favicon(const uhttprequest & request,
    uhttpresponse & response, int errcode)
{
    ulog(ulog_debug, "favicon request!\n");
    response.set_statuscode(uhttp_status_ok);
    response.set_header(uhttpresponse::HEADER_CONTENT_TYPE, "text/html");

    return 0;
}

int CLbsConnection::notfind(const uhttprequest & request,
    uhttpresponse & response, int errcode)
{
    ulog(ulog_debug, "notfind!\n");
    response.set_statuscode(uhttp_status_not_found);

    response.set_header(uhttpresponse::HEADER_CONTENT_TYPE, "text/html");
    response.set_content("
404 Not Found!
");

    return -1;
}

int CLbsConnection::setcpu(const uhttprequest & request,
    uhttpresponse & response, int errcode)
{
    ulog(ulog_debug, "setcpu!\n");
    #if 0 //debug
    static std::vector<std::string> services;
    if (services.empty()) {
        services.resize(10);
        services[2] = "media";
        services[9] = "publisher";
    }
    #else
    const std::vector<std::string> & services = config_.services;
    #endif

    const uuri & uri = request.uri();

    std::map<std::string, std::string> limits = uri.query();

    std::string dxip = limits["dx"];
    std::string ltip = limits["lt"];
    std::string ydip = limits["yd"];
    std::string area = limits["area"];

    int band = atoi(limits["band"].c_str());;
    int net  = atoi(limits["net"].c_str());

    limits.erase("port");   //remove client listen port. no need!
    limits.erase("dx");
    limits.erase("lt");
    limits.erase("yd");
    limits.erase("area");
    limits.erase("band");
    limits.erase("net");
    if (net == 0 && band != 0) {
        limits["net"] = band;
    }

    if (area.empty()) {
        return -1;
    }

    std::map<std::string, std::string> service2port;
    typedef std::map<std::string, std::string>::iterator const_ssit;

    for (size_t i = 0; i < services.size(); i++) {
        if (services[i].empty()) {
            continue;
        }

        const_ssit it = limits.find(services[i]);
        if (it != limits.end()) {
            service2port[it->first] = it->second;
            limits.erase(it);
        }
    }

    std::map<std::string, int> limitsint;
    for (const_ssit it = limits.begin(); it != limits.end(); ++it) {
        ulog(ulog_debug, "limits, %s --> %s\n", it->first.c_str(), it->second.c_str());
        limitsint[it->first] = atoi(it->second.c_str());
    }

    uint32 dxuip = str2ip(dxip.c_str());
    uint32 ltuip = str2ip(ltip.c_str());
    uint32 yduip = str2ip(ydip.c_str());

    int flag1 = 0, flag2 = 0, flag3 = 0;
    if (dxuip != 0) {
        flag1 |= en_ctc_flag;
        if (ltuip == dxuip) {
            flag1 |= en_cuc_flag;
            ltuip = 0;
        }
        if (yduip == dxuip) {
            flag1 |= en_cmc_flag;
            yduip = 0;
        }
    }

    if (ltuip != 0) {
        flag2 |= en_cuc_flag;
        if (yduip == ltuip) {
            flag2 |= en_cmc_flag;
            yduip = 0;
        }
    }

    if (yduip != 0) {
        flag3 |= en_cmc_flag;
    }

    for (const_ssit it = service2port.begin(); it != service2port.end(); ++ it) {
        std::vector<std::string> vport;
        split(it->second.c_str(), ',', vport);

        for (size_t i = 0; i < vport.size(); i++) {
            int port = atoi(vport[i].c_str());
            if (port == 0) {
                continue;
            }

            if (dxuip != 0) {
                monitor_.onNewNode(it->first, dxuip, port, flag1, area, limitsint);
            }

            if (ltuip != 0) {
                monitor_.onNewNode(it->first, ltuip, port, flag2, area, limitsint);
            }

            if (yduip != 0) {
                monitor_.onNewNode(it->first, yduip, port, flag3, area, limitsint);
            }
        }
    }

    {
        char * rdbuf = (char *)malloc(1024);
        int net, cpu, id, port;
        std::map<std::string, int> loading;

        while (socket_.getline(rdbuf, 1024).good()) {
            loading.clear();

            ulog(ulog_debug, "contine(%s):%s\n", peerip_.c_str(), rdbuf);

            if (sscanf(rdbuf, "net%d", &net) == 1) {
                loading["net"] = net;

                for (const_ssit it = service2port.begin();
                    it != service2port.end(); ++ it) {
                    std::vector<std::string> vport;
                    split(it->second.c_str(), ',', vport);

                    for (size_t i = 0; i < vport.size(); i++) {
                        int port = atoi(vport[i].c_str());
                        if (port == 0) {
                            continue;
                        }

                        if (dxuip != 0) {
                            monitor_.onNewNode(it->first, dxuip, port, flag1,
                                area, limitsint);
                            monitor_.onUptNode(it->first, dxuip, port, loading);
                        }

                        if (ltuip != 0) {
                            monitor_.onNewNode(it->first, ltuip, port, flag2,
                                area, limitsint);
                            monitor_.onUptNode(it->first, ltuip, port, loading);
                        }

                        if (yduip != 0) {
                            monitor_.onNewNode(it->first, yduip, port, flag3,
                                area, limitsint);
                            monitor_.onUptNode(it->first, yduip, port, loading);
                        }
                    }
                }

            } else if (sscanf(rdbuf, "del%d %d", &id, &port) == 2) {
                std::string service = services[id];
                if (dxuip != 0) {
                    monitor_.onDelNode(service, dxuip, port);
                }

                if (ltuip != 0) {
                    monitor_.onDelNode(service, ltuip, port);
                }

                if (yduip != 0) {
                    monitor_.onDelNode(service, yduip, port);
                }
                continue;
            } else if (sscanf(rdbuf, "cpu%d %d %d", &id, &port, &cpu) == 3) {
                loading["cpu"] = cpu;
                std::string service = services[id];

                if (dxuip != 0) {
                    monitor_.onUptNode(service, dxuip, port, loading);
                }

                if (ltuip != 0) {
                    monitor_.onUptNode(service, ltuip, port, loading);
                }

                if (yduip != 0) {
                    monitor_.onUptNode(service, yduip, port, loading);
                }
            } else {
                continue;
            }
        }

        free(rdbuf);
    }

    //disconnect

    for (const_ssit it = service2port.begin(); it != service2port.end(); ++ it) {

        std::vector<std::string> vport;
        split(it->second.c_str(), ',', vport);

        for (size_t i = 0; i < vport.size(); i++) {
            int port = atoi(vport[i].c_str());
            if (port == 0) {
                continue;
            }

            if (dxuip != 0) {
                ulog(ulog_info, "service[%s] addr[%s:%d:%d] disconnect!\n",
                    it->first.c_str(), dxip.c_str(), port, flag1);
                monitor_.onDelNode(it->first, dxuip, port);
            }

            if (ltuip != 0) {
                ulog(ulog_info, "service[%s] addr[%s:%d:%d] disconnect!\n",
                    it->first.c_str(), ltip.c_str(), port, flag2);
                monitor_.onDelNode(it->first, ltuip, port);
            }

            if (yduip != 0) {
                ulog(ulog_info, "service[%s] addr[%s:%d:%d] disconnect!\n",
                    it->first.c_str(), ydip.c_str(), port, flag3);
                monitor_.onDelNode(it->first, yduip, port);
            }
        }
    }

    return -1;
}

int CLbsConnection::dump(const uhttprequest & request,
    uhttpresponse & response, int errcode)
{
    std::string out;
    monitor_.onDump(out);
    response.set_content(out);

    response.set_statuscode(uhttp_status_ok);

    response.set_header(uhttpresponse::HEADER_CONTENT_TYPE, "text/html");
    return 0;
}

int CLbsConnection::get(const uhttprequest & request,
    uhttpresponse & response, int errcode)
{
    // handle proxy ???
    std::string service;
    uint32 uip = str2ip(peerip_.c_str());
    const std::string & path = request.uri().path();

    ulog(ulog_debug, "get path:%s, prefix:%s\n", path.c_str(), config_.prefix.c_str());

    std::string match = path.substr(1); //skip /
    if (!config_.prefix.empty()) {
        std::string::size_type npos = path.find(config_.prefix);
        if (npos != 1) { //skip root path.
            return -1;
        }
        match = path.substr(npos + config_.prefix.size());
    }

    for (size_t i = 0; i < config_.services.size(); i++) {
        if (config_.services[i].empty()) {
            continue;
        }
        if (strcasecmp(match.c_str(), config_.services[i].c_str()) == 0) {
            service = config_.services[i];
            break;
        }
    }

    if (service.empty()) {
        return -1;
    }

    std::string out;
    monitor_.onGetNode(service, uip, out);
    response.set_content(out);

    //ulog(ulog_info, "service:[%s], client:[%s], out:[%s]\n",
    //    service.c_str(), peerip_.c_str(), out.c_str());

    response.set_statuscode(uhttp_status_ok);

    response.set_header(uhttpresponse::HEADER_CONTENT_TYPE, "text/plain");
    return 0;
}

<|endoftext|>