<commit_before>#ifdef WIN32
/////////////////////////////////////////////////////////////////////////////
// Disable unavoidable warning messages:

//  4103: used #pragma pack to change alignment
//  4114: same type qualifier used more than once
//  4201: nonstandard extension used : nameless struct/union
//  4237: "keyword" reserved for future use
//  4251: class needs to have dll-interface to export class
//  4275: non DLL-interface class used as base for DLL-interface class
//  4290: C++ Exception Specification ignored
//  4503: decorated name length exceeded, name was truncated
//  4786: string too long - truncated to 255 characters

#pragma warning(disable : 4103 4114 4201 4237 4251 4275 4290 4503 4335 4786)

#endif // WIN32

#include <osgViewer/Viewer>
#include <osgViewer/StatsHandler>
#include <osgViewer/HelpHandler>
#include <osgViewer/ViewerEventHandlers>

#include <osg/Group>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osg/Texture2D>
#include <osg/PositionAttitudeTransform>
#include <osg/MatrixTransform>
#include <osg/CoordinateSystemNode>

#include <osgDB/FileUtils>
#include <osgDB/ReadFile>

#include <osgText/Text>

#include <osg/CoordinateSystemNode>

#include <osgSim/OverlayNode>
#include <osgSim/SphereSegment>

#include <osgGA/NodeTrackerManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>

#include <iostream>

osg::Node* createEarth()
{
    osg::TessellationHints* hints = new osg::TessellationHints;
    hints->setDetailRatio(5.0f);

    osg::ShapeDrawable* sd = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0,0.0,0.0), osg::WGS_84_RADIUS_POLAR), hints);

    osg::Geode* geode = new osg::Geode;
    geode->addDrawable(sd);

    std::string filename = osgDB::findDataFile("Images/land_shallow_topo_2048.jpg");
    geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, new osg::Texture2D(osgDB::readImageFile(filename)));

    osg::CoordinateSystemNode* csn = new osg::CoordinateSystemNode;
    csn->setEllipsoidModel(new osg::EllipsoidModel());
    csn->addChild(geode);

    return csn;

}

class ModelPositionCallback : public osg::NodeCallback
{
public:

    ModelPositionCallback(double speed):
        _latitude(0.0),
        _longitude(0.0),
        _height(100000.0),
        _speed(speed)
    {
        _rotation.makeRotate(osg::DegreesToRadians(90.0),0.0,0.0,1.0);
    }

    void updateParameters()
    {
        _longitude += _speed * ((2.0*osg::PI)/360.0)/20.0;
    }

    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
    {
        updateParameters();

        osg::NodePath nodePath = nv->getNodePath();

        osg::MatrixTransform* mt = nodePath.empty() ? 0 : dynamic_cast<osg::MatrixTransform*>(nodePath.back());
        if (mt)
        {
            osg::CoordinateSystemNode* csn = 0;

            // find coordinate system node from our parental chain
            unsigned int i;
            for(i=0; i<nodePath.size() && csn==0; ++i)
            {
                csn = dynamic_cast<osg::CoordinateSystemNode*>(nodePath[i]);
            }

            if (csn)
            {

                osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
                if (ellipsoid)
                {
                    osg::Matrix inheritedMatrix;
                    for(i+=1; i<nodePath.size()-1; ++i)
                    {
                        osg::Transform* transform = nodePath[i]->asTransform();
                        if (transform) transform->computeLocalToWorldMatrix(inheritedMatrix, nv);
                    }

                    osg::Matrixd matrix(inheritedMatrix);

                    //osg::Matrixd matrix;
                    ellipsoid->computeLocalToWorldTransformFromLatLongHeight(_latitude,_longitude,_height,matrix);
                    matrix.preMult(osg::Matrix::rotate(_rotation));

                    mt->setMatrix(matrix);
                }

            }
        }

        traverse(node,nv);
    }

    double                  _latitude;
    double                  _longitude;
    double                  _height;
    osg::Quat               _rotation;
    double                  _speed;
};

class FindNamedNodeVisitor : public osg::NodeVisitor
{
public:
    FindNamedNodeVisitor(const std::string& name):
        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
        _name(name) {}

    virtual void apply(osg::Node& node)
    {
        if (node.getName()==_name)
        {
            _foundNodes.push_back(&node);
        }
        traverse(node);
    }

    typedef std::vector< osg::ref_ptr<osg::Node> > NodeList;

    std::string _name;
    NodeList _foundNodes;
};

int main(int argc, char **argv)
{
    // use an ArgumentParser object to manage the program arguments.
    osg::ArgumentParser arguments(&argc,argv);

    // set up the usage document, in case we need to print out how to use this program.
    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of node tracker.");
    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName());
    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");

    // construct the viewer.
    osgViewer::Viewer viewer;

    // add the state manipulator
    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );

    // add the thread model handler
    viewer.addEventHandler(new osgViewer::ThreadingHandler);

    // add the window size toggle handler
    viewer.addEventHandler(new osgViewer::WindowSizeHandler);

    // add the stats handler
    viewer.addEventHandler(new osgViewer::StatsHandler);

    // add the record camera path  handler
    viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);

    // add the help handler
    viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));

    // set the near far ration computation up.
    viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
    viewer.getCamera()->setNearFarRatio(0.000003f);

    double speed = 1.0;
    while (arguments.read("-f") || arguments.read("--fixed")) speed = 0.0;

    osg::Quat rotation;
    osg::Vec4 vec4;
    while (arguments.read("--rotate-model",vec4[0],vec4[1],vec4[2],vec4[3]))
    {
        osg::Quat local_rotate;
        local_rotate.makeRotate(osg::DegreesToRadians(vec4[0]),vec4[1],vec4[2],vec4[3]);

        rotation = rotation * local_rotate;
    }

    osg::NodeCallback* nc = 0;
    std::string flightpath_filename;
    while (arguments.read("--flight-path",flightpath_filename))
    {
        std::ifstream fin(flightpath_filename.c_str());
        if (fin)
        {
            osg::AnimationPath* path = new osg::AnimationPath;
            path->read(fin);
            nc = new osg::AnimationPathCallback(path);
        }
    }

    osgGA::NodeTrackerManipulator::TrackerMode trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION;
    std::string mode;
    while (arguments.read("--tracker-mode",mode))
    {
        if (mode=="NODE_CENTER_AND_ROTATION") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION;
        else if (mode=="NODE_CENTER_AND_AZIM") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_AZIM;
        else if (mode=="NODE_CENTER") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER;
        else
        {
            std::cout<<"Unrecognized --tracker-mode option "<<mode<<", valid options are:"<<std::endl;
            std::cout<<"    NODE_CENTER_AND_ROTATION"<<std::endl;
            std::cout<<"    NODE_CENTER_AND_AZIM"<<std::endl;
            std::cout<<"    NODE_CENTER"<<std::endl;
            return 1;
        }
    }

    osgGA::NodeTrackerManipulator::RotationMode rotationMode = osgGA::NodeTrackerManipulator::TRACKBALL;
    while (arguments.read("--rotation-mode",mode))
    {
        if (mode=="TRACKBALL") rotationMode = osgGA::NodeTrackerManipulator::TRACKBALL;
        else if (mode=="ELEVATION_AZIM") rotationMode = osgGA::NodeTrackerManipulator::ELEVATION_AZIM;
        else
        {
            std::cout<<"Unrecognized --rotation-mode option "<<mode<<", valid options are:"<<std::endl;
            std::cout<<"    TRACKBALL"<<std::endl;
            std::cout<<"    ELEVATION_AZIM"<<std::endl;
            return 1;
        }
    }

    bool useOverlay = true;
    while (arguments.read("--no-overlay") || arguments.read("-n")) useOverlay = false;

    osgSim::OverlayNode::OverlayTechnique technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
    while (arguments.read("--object")) technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
    while (arguments.read("--ortho") || arguments.read("--orthographic")) technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
    while (arguments.read("--persp") || arguments.read("--perspective")) technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY;

    unsigned int screenNum = 0;
    while (arguments.read("--screen", screenNum) || arguments.read("-s", screenNum)) viewer.setUpViewOnSingleScreen(screenNum);

    // if user request help write it out to cout.
    if (arguments.read("-h") || arguments.read("--help"))
    {
        arguments.getApplicationUsage()->write(std::cout);
        return 1;
    }

    // read the scene from the list of file specified commandline args.
    osg::ref_ptr<osg::Node> root = osgDB::readNodeFiles(arguments);

    if (!root) root = createEarth();

    if (!root) return 0;

    // add a viewport to the viewer and attach the scene graph.
    viewer.setSceneData(root.get());

    osg::ref_ptr<osgGA::NodeTrackerManipulator> tm;

    osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(root.get());
    if (csn)
    {

        osg::ref_ptr<osgSim::OverlayNode> overlayNode;
        if (useOverlay)
        {
            overlayNode = new osgSim::OverlayNode(technique);

            // insert the OverlayNode between the coordinate system node and its children.
            for(unsigned int i=0; i<csn->getNumChildren(); ++i)
            {
                overlayNode->addChild( csn->getChild(i) );
            }

            csn->removeChildren(0, csn->getNumChildren());
            csn->addChild(overlayNode.get());

            // tell the overlay node to continously update its overlay texture
            // as we know we'll be tracking a moving target.
            overlayNode->setContinuousUpdate(true);
        }

        osg::Node* cessna = osgDB::readNodeFile("cessna.osg");
        if (cessna)
        {
            double s = 200000.0 / cessna->getBound().radius();

            osg::MatrixTransform* scaler = new osg::MatrixTransform;
            scaler->addChild(cessna);
            scaler->setMatrix(osg::Matrixd::scale(s,s,s)*osg::Matrixd::rotate(rotation));
            scaler->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON);

            if (false)
            {
                osgSim::SphereSegment* ss = new osgSim::SphereSegment(
                                    osg::Vec3(0.0f,0.0f,0.0f), // center
                                    19.9f, // radius
                                    osg::DegreesToRadians(135.0f),
                                    osg::DegreesToRadians(240.0f),
                                    osg::DegreesToRadians(-10.0f),
                                    osg::DegreesToRadians(30.0f),
                                    60);

                scaler->addChild(ss);
            }

            osg::MatrixTransform* mt = new osg::MatrixTransform;
            mt->addChild(scaler);

            if (!nc) nc = new ModelPositionCallback(speed);

            mt->setUpdateCallback(nc);

            csn->addChild(mt);

            // if we are using an overaly node, use the cessna subgraph as the overlay subgraph
            if (overlayNode.valid())
            {
                overlayNode->setOverlaySubgraph(mt);
            }

            tm = new osgGA::NodeTrackerManipulator;
            tm->setTrackerMode(trackerMode);
            tm->setRotationMode(rotationMode);
            tm->setTrackNode(scaler);
        }
        else
        {
             std::cout<<"Failed to read cessna.osg"<<std::endl;
        }

    }

    // set up camera manipulators.
    {
        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;

        if (tm.valid()) keyswitchManipulator->addMatrixManipulator( '0', "NodeTracker", tm.get() );

        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
        keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
        keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );

        std::string pathfile;
        while (arguments.read("-p",pathfile))
        {
            osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
            if (apm || !apm->valid())
            {
                unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
                keyswitchManipulator->addMatrixManipulator( '5', "Path", apm );
                keyswitchManipulator->selectMatrixManipulator(num);
            }
        }

        viewer.setCameraManipulator( keyswitchManipulator.get() );
    }

    // viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);

    return viewer.run();
}
<commit_msg>Improved the handling of the -p path option<commit_after>#ifdef WIN32
/////////////////////////////////////////////////////////////////////////////
// Disable unavoidable warning messages:

//  4103: used #pragma pack to change alignment
//  4114: same type qualifier used more than once
//  4201: nonstandard extension used : nameless struct/union
//  4237: "keyword" reserved for future use
//  4251: class needs to have dll-interface to export class
//  4275: non DLL-interface class used as base for DLL-interface class
//  4290: C++ Exception Specification ignored
//  4503: decorated name length exceeded, name was truncated
//  4786: string too long - truncated to 255 characters

#pragma warning(disable : 4103 4114 4201 4237 4251 4275 4290 4503 4335 4786)

#endif // WIN32

#include <osgViewer/Viewer>
#include <osgViewer/StatsHandler>
#include <osgViewer/HelpHandler>
#include <osgViewer/ViewerEventHandlers>

#include <osg/Group>
#include <osg/Geode>
#include <osg/ShapeDrawable>
#include <osg/Texture2D>
#include <osg/PositionAttitudeTransform>
#include <osg/MatrixTransform>
#include <osg/CoordinateSystemNode>

#include <osgDB/FileUtils>
#include <osgDB/ReadFile>

#include <osgText/Text>

#include <osg/CoordinateSystemNode>

#include <osgSim/OverlayNode>
#include <osgSim/SphereSegment>

#include <osgGA/NodeTrackerManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>

#include <iostream>

osg::Node* createEarth()
{
    osg::TessellationHints* hints = new osg::TessellationHints;
    hints->setDetailRatio(5.0f);

    osg::ShapeDrawable* sd = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0,0.0,0.0), osg::WGS_84_RADIUS_POLAR), hints);

    osg::Geode* geode = new osg::Geode;
    geode->addDrawable(sd);

    std::string filename = osgDB::findDataFile("Images/land_shallow_topo_2048.jpg");
    geode->getOrCreateStateSet()->setTextureAttributeAndModes(0, new osg::Texture2D(osgDB::readImageFile(filename)));

    osg::CoordinateSystemNode* csn = new osg::CoordinateSystemNode;
    csn->setEllipsoidModel(new osg::EllipsoidModel());
    csn->addChild(geode);

    return csn;

}

class ModelPositionCallback : public osg::NodeCallback
{
public:

    ModelPositionCallback(double speed):
        _latitude(0.0),
        _longitude(0.0),
        _height(100000.0),
        _speed(speed)
    {
        _rotation.makeRotate(osg::DegreesToRadians(90.0),0.0,0.0,1.0);
    }

    void updateParameters()
    {
        _longitude += _speed * ((2.0*osg::PI)/360.0)/20.0;
    }

    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
    {
        updateParameters();

        osg::NodePath nodePath = nv->getNodePath();

        osg::MatrixTransform* mt = nodePath.empty() ? 0 : dynamic_cast<osg::MatrixTransform*>(nodePath.back());
        if (mt)
        {
            osg::CoordinateSystemNode* csn = 0;

            // find coordinate system node from our parental chain
            unsigned int i;
            for(i=0; i<nodePath.size() && csn==0; ++i)
            {
                csn = dynamic_cast<osg::CoordinateSystemNode*>(nodePath[i]);
            }

            if (csn)
            {

                osg::EllipsoidModel* ellipsoid = csn->getEllipsoidModel();
                if (ellipsoid)
                {
                    osg::Matrix inheritedMatrix;
                    for(i+=1; i<nodePath.size()-1; ++i)
                    {
                        osg::Transform* transform = nodePath[i]->asTransform();
                        if (transform) transform->computeLocalToWorldMatrix(inheritedMatrix, nv);
                    }

                    osg::Matrixd matrix(inheritedMatrix);

                    //osg::Matrixd matrix;
                    ellipsoid->computeLocalToWorldTransformFromLatLongHeight(_latitude,_longitude,_height,matrix);
                    matrix.preMult(osg::Matrix::rotate(_rotation));

                    mt->setMatrix(matrix);
                }

            }
        }

        traverse(node,nv);
    }

    double                  _latitude;
    double                  _longitude;
    double                  _height;
    osg::Quat               _rotation;
    double                  _speed;
};

class FindNamedNodeVisitor : public osg::NodeVisitor
{
public:
    FindNamedNodeVisitor(const std::string& name):
        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
        _name(name) {}

    virtual void apply(osg::Node& node)
    {
        if (node.getName()==_name)
        {
            _foundNodes.push_back(&node);
        }
        traverse(node);
    }

    typedef std::vector< osg::ref_ptr<osg::Node> > NodeList;

    std::string _name;
    NodeList _foundNodes;
};

int main(int argc, char **argv)
{
    // use an ArgumentParser object to manage the program arguments.
    osg::ArgumentParser arguments(&argc,argv);

    // set up the usage document, in case we need to print out how to use this program.
    arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates use of node tracker.");
    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName());
    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");

    // construct the viewer.
    osgViewer::Viewer viewer;

    // add the state manipulator
    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );

    // add the thread model handler
    viewer.addEventHandler(new osgViewer::ThreadingHandler);

    // add the window size toggle handler
    viewer.addEventHandler(new osgViewer::WindowSizeHandler);

    // add the stats handler
    viewer.addEventHandler(new osgViewer::StatsHandler);

    // add the record camera path  handler
    viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);

    // add the help handler
    viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));

    // set the near far ration computation up.
    viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
    viewer.getCamera()->setNearFarRatio(0.000003f);

    double speed = 1.0;
    while (arguments.read("-f") || arguments.read("--fixed")) speed = 0.0;

    osg::Quat rotation;
    osg::Vec4 vec4;
    while (arguments.read("--rotate-model",vec4[0],vec4[1],vec4[2],vec4[3]))
    {
        osg::Quat local_rotate;
        local_rotate.makeRotate(osg::DegreesToRadians(vec4[0]),vec4[1],vec4[2],vec4[3]);

        rotation = rotation * local_rotate;
    }

    osg::NodeCallback* nc = 0;
    std::string flightpath_filename;
    while (arguments.read("--flight-path",flightpath_filename))
    {
        std::ifstream fin(flightpath_filename.c_str());
        if (fin)
        {
            osg::AnimationPath* path = new osg::AnimationPath;
            path->read(fin);
            nc = new osg::AnimationPathCallback(path);
        }
    }

    osgGA::NodeTrackerManipulator::TrackerMode trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION;
    std::string mode;
    while (arguments.read("--tracker-mode",mode))
    {
        if (mode=="NODE_CENTER_AND_ROTATION") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_ROTATION;
        else if (mode=="NODE_CENTER_AND_AZIM") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER_AND_AZIM;
        else if (mode=="NODE_CENTER") trackerMode = osgGA::NodeTrackerManipulator::NODE_CENTER;
        else
        {
            std::cout<<"Unrecognized --tracker-mode option "<<mode<<", valid options are:"<<std::endl;
            std::cout<<"    NODE_CENTER_AND_ROTATION"<<std::endl;
            std::cout<<"    NODE_CENTER_AND_AZIM"<<std::endl;
            std::cout<<"    NODE_CENTER"<<std::endl;
            return 1;
        }
    }

    osgGA::NodeTrackerManipulator::RotationMode rotationMode = osgGA::NodeTrackerManipulator::TRACKBALL;
    while (arguments.read("--rotation-mode",mode))
    {
        if (mode=="TRACKBALL") rotationMode = osgGA::NodeTrackerManipulator::TRACKBALL;
        else if (mode=="ELEVATION_AZIM") rotationMode = osgGA::NodeTrackerManipulator::ELEVATION_AZIM;
        else
        {
            std::cout<<"Unrecognized --rotation-mode option "<<mode<<", valid options are:"<<std::endl;
            std::cout<<"    TRACKBALL"<<std::endl;
            std::cout<<"    ELEVATION_AZIM"<<std::endl;
            return 1;
        }
    }

    bool useOverlay = true;
    while (arguments.read("--no-overlay") || arguments.read("-n")) useOverlay = false;

    osgSim::OverlayNode::OverlayTechnique technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
    while (arguments.read("--object")) technique = osgSim::OverlayNode::OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
    while (arguments.read("--ortho") || arguments.read("--orthographic")) technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY;
    while (arguments.read("--persp") || arguments.read("--perspective")) technique = osgSim::OverlayNode::VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY;

    unsigned int screenNum = 0;
    while (arguments.read("--screen", screenNum) || arguments.read("-s", screenNum)) viewer.setUpViewOnSingleScreen(screenNum);

    std::string pathfile;
    while (arguments.read("-p",pathfile)) {}

    // if user request help write it out to cout.
    if (arguments.read("-h") || arguments.read("--help"))
    {
        arguments.getApplicationUsage()->write(std::cout);
        return 1;
    }

    // read the scene from the list of file specified commandline args.
    osg::ref_ptr<osg::Node> root = osgDB::readNodeFiles(arguments);

    if (!root) root = createEarth();

    if (!root) return 0;

    // add a viewport to the viewer and attach the scene graph.
    viewer.setSceneData(root.get());

    osg::ref_ptr<osgGA::NodeTrackerManipulator> tm;

    osg::CoordinateSystemNode* csn = dynamic_cast<osg::CoordinateSystemNode*>(root.get());
    if (csn)
    {

        osg::ref_ptr<osgSim::OverlayNode> overlayNode;
        if (useOverlay)
        {
            overlayNode = new osgSim::OverlayNode(technique);

            // insert the OverlayNode between the coordinate system node and its children.
            for(unsigned int i=0; i<csn->getNumChildren(); ++i)
            {
                overlayNode->addChild( csn->getChild(i) );
            }

            csn->removeChildren(0, csn->getNumChildren());
            csn->addChild(overlayNode.get());

            // tell the overlay node to continously update its overlay texture
            // as we know we'll be tracking a moving target.
            overlayNode->setContinuousUpdate(true);
        }

        osg::Node* cessna = osgDB::readNodeFile("cessna.osg");
        if (cessna)
        {
            double s = 200000.0 / cessna->getBound().radius();

            osg::MatrixTransform* scaler = new osg::MatrixTransform;
            scaler->addChild(cessna);
            scaler->setMatrix(osg::Matrixd::scale(s,s,s)*osg::Matrixd::rotate(rotation));
            scaler->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON);

            if (false)
            {
                osgSim::SphereSegment* ss = new osgSim::SphereSegment(
                                    osg::Vec3(0.0f,0.0f,0.0f), // center
                                    19.9f, // radius
                                    osg::DegreesToRadians(135.0f),
                                    osg::DegreesToRadians(240.0f),
                                    osg::DegreesToRadians(-10.0f),
                                    osg::DegreesToRadians(30.0f),
                                    60);

                scaler->addChild(ss);
            }

            osg::MatrixTransform* mt = new osg::MatrixTransform;
            mt->addChild(scaler);

            if (!nc) nc = new ModelPositionCallback(speed);

            mt->setUpdateCallback(nc);

            csn->addChild(mt);

            // if we are using an overaly node, use the cessna subgraph as the overlay subgraph
            if (overlayNode.valid())
            {
                overlayNode->setOverlaySubgraph(mt);
            }

            tm = new osgGA::NodeTrackerManipulator;
            tm->setTrackerMode(trackerMode);
            tm->setRotationMode(rotationMode);
            tm->setTrackNode(scaler);
        }
        else
        {
             std::cout<<"Failed to read cessna.osg"<<std::endl;
        }

    }

    // set up camera manipulators.
    {
        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;

        if (tm.valid()) keyswitchManipulator->addMatrixManipulator( '0', "NodeTracker", tm.get() );

        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
        keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
        keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );

        if (!pathfile.empty())
        {
            osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
            if (apm || !apm->valid())
            {
                unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
                keyswitchManipulator->addMatrixManipulator( '5', "Path", apm );
                keyswitchManipulator->selectMatrixManipulator(num);
            }
        }

        viewer.setCameraManipulator( keyswitchManipulator.get() );
    }

    // viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);

    return viewer.run();
}
<|endoftext|>


<commit_before>//
// Copyright Copyright 2009-2021, AMT – The Association For Manufacturing Technology (“AMT”)
// All rights reserved.
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
//

// Ensure that gtest is the first header otherwise Windows raises an error
#include <gtest/gtest.h>
// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!)

#include <chrono>

#include "observation/observation.hpp"
#include "pipeline/deliver.hpp"
#include "pipeline/delta_filter.hpp"
#include "pipeline/duplicate_filter.hpp"
#include "pipeline/period_filter.hpp"
#include "pipeline/pipeline.hpp"
#include "pipeline/shdr_token_mapper.hpp"

using namespace mtconnect;
using namespace mtconnect::pipeline;
using namespace mtconnect::observation;
using namespace mtconnect::asset;
using namespace device_model;
using namespace data_item;
using namespace entity;
using namespace std;
using namespace std::literals;
using namespace std::chrono_literals;

struct MockPipelineContract : public PipelineContract
{
  MockPipelineContract(std::map<string, DataItemPtr> &items) : m_dataItems(items) {}
  DevicePtr findDevice(const std::string &device) override { return nullptr; }
  DataItemPtr findDataItem(const std::string &device, const std::string &name) override
  {
    return m_dataItems[name];
  }
  void eachDataItem(EachDataItem fun) override {}
  void deliverObservation(observation::ObservationPtr obs) override
  {
    m_observations.push_back(obs);
  }
  void deliverAsset(AssetPtr) override {}
  void deliverAssetCommand(entity::EntityPtr) override {}
  void deliverCommand(entity::EntityPtr) override {}
  void deliverConnectStatus(entity::EntityPtr, const StringList &, bool) override {}

  std::map<string, DataItemPtr> &m_dataItems;

  std::vector<ObservationPtr> m_observations;
};

class PeriodFilterTest : public testing::Test
{
public:
  PeriodFilterTest() : m_strand(m_ioContext) {}

protected:
  void SetUp() override
  {
    m_context = make_shared<PipelineContext>();
    m_context->m_contract = make_unique<MockPipelineContract>(m_dataItems);
    m_mapper = make_shared<ShdrTokenMapper>(m_context);
    m_mapper->bind(make_shared<NullTransform>(TypeGuard<Observations>(RUN)));
  }

  void TearDown() override
  {
    m_dataItems.clear();
    m_context.reset();
    m_mapper.reset();
  }

  DataItemPtr makeDataItem(Properties attributes)
  {
    ErrorList errors;
    auto di = DataItem::make(attributes, errors);
    m_dataItems.emplace(di->getId(), di);

    return di;
  }

  const EntityPtr observe(TokenList tokens, Timestamp now = chrono::system_clock::now())
  {
    auto ts = make_shared<Timestamped>();
    ts->m_tokens = tokens;
    ts->m_timestamp = now;
    ts->setProperty("timestamp", ts->m_timestamp);

    return (*m_mapper)(ts);
  }

  void createDataItem(double rate)
  {
    ErrorList errors;
    auto f = Filter::getFactory()->create("Filter", {{"type", "PERIOD"s}, {"VALUE", rate}}, errors);
    EntityList list {f};
    auto filters = DataItem::getFactory()->factoryFor("DataItem")->create("Filters", list, errors);

    makeDataItem({{"id", "a"s},
                  {"type", "POSITION"s},
                  {"category", "SAMPLE"s},
                  {"units", "MILLIMETER"s},
                  {"Filters", filters}});
  }

  auto makeFilter()
  {
    auto rate = make_shared<PeriodFilter>(m_context, m_strand);
    m_mapper->bind(rate);

    auto delivery = make_shared<DeliverObservation>(m_context);
    rate->bind(delivery);

    return rate;
  }

  auto observations()
  {
    return static_cast<MockPipelineContract *>(m_context->m_contract.get())->m_observations;
  }

  shared_ptr<ShdrTokenMapper> m_mapper;
  std::map<string, DataItemPtr> m_dataItems;
  shared_ptr<PipelineContext> m_context;
  boost::asio::io_context m_ioContext;
  boost::asio::io_context::strand m_strand;
};

TEST_F(PeriodFilterTest, test_simple_time_series)
{
  createDataItem(10.0);
  makeFilter();

  Timestamp now = chrono::system_clock::now();

  {
    auto os = observe({"a", "1.5"}, now);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(1, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "1.5"}, now + 2s);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "1.5"}, now + 5s);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "1.5"}, now + 11s);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(1, list.size());
    ASSERT_EQ(2, observations().size());
  }
}

TEST_F(PeriodFilterTest, delayed_delivery)
{
  createDataItem(1.0);
  makeFilter();

  Timestamp now = chrono::system_clock::now();

  {
    auto os = observe({"a", "1"}, now);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(1, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "2"}, now + 500ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }

  m_ioContext.run_for(750ms);

  auto obs = observations();
  ASSERT_EQ(2, obs.size());
  auto end = obs.back();
  ASSERT_EQ(2.0, end->getValue<double>());
}

TEST_F(PeriodFilterTest, delayed_delivery_with_replace)
{
  createDataItem(1.0);
  makeFilter();

  Timestamp now = chrono::system_clock::now();

  {
    auto os = observe({"a", "1"}, now);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(1, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "2"}, now + 500ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "3"}, now + 750ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }

  m_ioContext.run_for(500ms);

  auto obs = observations();
  ASSERT_EQ(2, obs.size());
  auto end = obs.back();
  ASSERT_EQ(3.0, end->getValue<double>());
}

TEST_F(PeriodFilterTest, delayed_delivery_with_cancel)
{
  createDataItem(1.0);
  makeFilter();

  Timestamp now = chrono::system_clock::now();

  {
    auto os = observe({"a", "1"}, now);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(1, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "2"}, now + 500ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "3"}, now + 750ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "4"}, now + 1250ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(1, list.size());
    ASSERT_EQ(2, observations().size());
  }

  m_ioContext.run_for(500ms);

  auto obs = observations();
  ASSERT_EQ(2, obs.size());
  auto end = obs.back();
  ASSERT_EQ(4.0, end->getValue<double>());
}
<commit_msg>Minor cleanup<commit_after>//
// Copyright Copyright 2009-2021, AMT – The Association For Manufacturing Technology (“AMT”)
// All rights reserved.
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
//

// Ensure that gtest is the first header otherwise Windows raises an error
#include <gtest/gtest.h>
// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!)

#include <chrono>

#include "observation/observation.hpp"
#include "pipeline/deliver.hpp"
#include "pipeline/delta_filter.hpp"
#include "pipeline/duplicate_filter.hpp"
#include "pipeline/period_filter.hpp"
#include "pipeline/pipeline.hpp"
#include "pipeline/shdr_token_mapper.hpp"

using namespace mtconnect;
using namespace mtconnect::pipeline;
using namespace mtconnect::observation;
using namespace mtconnect::asset;
using namespace device_model;
using namespace data_item;
using namespace entity;
using namespace std;
using namespace std::literals;
using namespace std::chrono_literals;

struct MockPipelineContract : public PipelineContract
{
  MockPipelineContract(std::map<string, DataItemPtr> &items) : m_dataItems(items) {}
  DevicePtr findDevice(const std::string &device) override { return nullptr; }
  DataItemPtr findDataItem(const std::string &device, const std::string &name) override
  {
    return m_dataItems[name];
  }
  void eachDataItem(EachDataItem fun) override {}
  void deliverObservation(observation::ObservationPtr obs) override
  {
    m_observations.push_back(obs);
  }
  void deliverAsset(AssetPtr) override {}
  void deliverAssetCommand(entity::EntityPtr) override {}
  void deliverCommand(entity::EntityPtr) override {}
  void deliverConnectStatus(entity::EntityPtr, const StringList &, bool) override {}

  std::map<string, DataItemPtr> &m_dataItems;

  std::vector<ObservationPtr> m_observations;
};

class PeriodFilterTest : public testing::Test
{
public:
  PeriodFilterTest() : m_strand(m_ioContext) {}

protected:
  void SetUp() override
  {
    m_context = make_shared<PipelineContext>();
    m_context->m_contract = make_unique<MockPipelineContract>(m_dataItems);
    m_mapper = make_shared<ShdrTokenMapper>(m_context);
    m_mapper->bind(make_shared<NullTransform>(TypeGuard<Observations>(RUN)));
  }

  void TearDown() override
  {
    m_dataItems.clear();
    m_context.reset();
    m_mapper.reset();
  }

  DataItemPtr makeDataItem(Properties attributes)
  {
    ErrorList errors;
    auto di = DataItem::make(attributes, errors);
    m_dataItems.emplace(di->getId(), di);

    return di;
  }

  const EntityPtr observe(TokenList tokens, Timestamp now = chrono::system_clock::now())
  {
    auto ts = make_shared<Timestamped>();
    ts->m_tokens = tokens;
    ts->m_timestamp = now;
    ts->setProperty("timestamp", ts->m_timestamp);

    return (*m_mapper)(ts);
  }

  void createDataItem()
  {
    ErrorList errors;
    auto f = Filter::getFactory()->create("Filter", {{"type", "PERIOD"s}, {"VALUE", 1.0}}, errors);
    EntityList list {f};
    auto filters = DataItem::getFactory()->factoryFor("DataItem")->create("Filters", list, errors);

    makeDataItem({{"id", "a"s},
                  {"type", "POSITION"s},
                  {"category", "SAMPLE"s},
                  {"units", "MILLIMETER"s},
                  {"Filters", filters}});
  }

  auto makeFilter()
  {
    auto rate = make_shared<PeriodFilter>(m_context, m_strand);
    m_mapper->bind(rate);

    auto delivery = make_shared<DeliverObservation>(m_context);
    rate->bind(delivery);

    return rate;
  }

  auto observations()
  {
    return static_cast<MockPipelineContract *>(m_context->m_contract.get())->m_observations;
  }

  shared_ptr<ShdrTokenMapper> m_mapper;
  std::map<string, DataItemPtr> m_dataItems;
  shared_ptr<PipelineContext> m_context;
  boost::asio::io_context m_ioContext;
  boost::asio::io_context::strand m_strand;
};

TEST_F(PeriodFilterTest, test_simple_time_series)
{
  createDataItem();
  makeFilter();

  Timestamp now = chrono::system_clock::now();

  {
    auto os = observe({"a", "1.5"}, now);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(1, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "1.5"}, now + 200ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "1.5"}, now + 500ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "1.5"}, now + 1100ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(1, list.size());
    ASSERT_EQ(2, observations().size());
  }

  m_ioContext.run_for(1s);

  ASSERT_EQ(2, observations().size());
}

TEST_F(PeriodFilterTest, delayed_delivery)
{
  createDataItem();
  makeFilter();

  Timestamp now = chrono::system_clock::now();

  {
    auto os = observe({"a", "1"}, now);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(1, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "2"}, now + 500ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }

  m_ioContext.run_for(750ms);

  auto obs = observations();
  ASSERT_EQ(2, obs.size());
  auto end = obs.back();
  ASSERT_EQ(2.0, end->getValue<double>());
}

TEST_F(PeriodFilterTest, delayed_delivery_with_replace)
{
  createDataItem();
  makeFilter();

  Timestamp now = chrono::system_clock::now();

  {
    auto os = observe({"a", "1"}, now);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(1, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "2"}, now + 500ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "3"}, now + 750ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }

  m_ioContext.run_for(500ms);

  auto obs = observations();
  ASSERT_EQ(2, obs.size());
  auto end = obs.back();
  ASSERT_EQ(3.0, end->getValue<double>());
}

TEST_F(PeriodFilterTest, delayed_delivery_with_cancel)
{
  createDataItem();
  makeFilter();

  Timestamp now = chrono::system_clock::now();

  {
    auto os = observe({"a", "1"}, now);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(1, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "2"}, now + 500ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "3"}, now + 750ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(0, list.size());
    ASSERT_EQ(1, observations().size());
  }
  {
    auto os = observe({"a", "4"}, now + 1250ms);
    auto list = os->getValue<EntityList>();
    ASSERT_EQ(1, list.size());
    ASSERT_EQ(2, observations().size());
  }

  m_ioContext.run_for(500ms);

  auto obs = observations();
  ASSERT_EQ(2, obs.size());
  auto end = obs.back();
  ASSERT_EQ(4.0, end->getValue<double>());
}
<|endoftext|>


<commit_before>//*******************************************************************
//
// License:  See top level LICENSE.txt file.
//
// Author: Garrett Potts
//
//*******************************************************************
// $Id$

#include <ossim/base/ossimStreamFactoryRegistry.h>
#include <ossim/base/ossimStreamFactory.h>
#include <ossim/base/ossimIoStream.h>
#include <ossim/base/ossimFilename.h>

#include <fstream>
#include <algorithm>

ossim::StreamFactoryRegistry* ossim::StreamFactoryRegistry::m_instance = 0;

ossim::StreamFactoryRegistry::StreamFactoryRegistry()
{
}

ossim::StreamFactoryRegistry::~StreamFactoryRegistry()
{
}

ossim::StreamFactoryRegistry* ossim::StreamFactoryRegistry::instance()
{
   if(!m_instance)
   {
      m_instance = new ossim::StreamFactoryRegistry();

      // Add factory from the core.
      m_instance->registerFactory(ossim::StreamFactory::instance());
   }

   return m_instance;
}

std::shared_ptr<ossim::istream> ossim::StreamFactoryRegistry::createIstream(
   const ossimString& connectionString, std::ios_base::openmode openMode) const
{
   std::shared_ptr<ossim::istream> result(0);
   ossim_uint32 i = 0;
   for(i = 0; (i < (int)m_factoryList.size())&&(!result); ++i)
   {
      result = m_factoryList[i]->createIstream(connectionString, openMode);
   }
   return result;
}

std::shared_ptr<ossim::ostream> ossim::StreamFactoryRegistry::createOstream(
   const ossimString& /*connectionString*/, std::ios_base::openmode /*openMode*/) const
{
   std::shared_ptr<ossim::ostream> result(0);
   return result;
}

std::shared_ptr<ossim::iostream> ossim::StreamFactoryRegistry::createIOstream(
   const ossimString& /*connectionString*/, std::ios_base::openmode /*openMode*/) const
{
   std::shared_ptr<ossim::iostream> result(0);
   return result;
}

void ossim::StreamFactoryRegistry::registerFactory(ossim::StreamFactoryBase* factory)
{
   std::vector<ossim::StreamFactoryBase*>::iterator iter = std::find(
      m_factoryList.begin(), m_factoryList.end(), factory);
   if(iter == m_factoryList.end())
   {
      m_factoryList.push_back(factory);
   }
}

void ossim::StreamFactoryRegistry::unregisterFactory(StreamFactoryBase* factory)
{
   // OpenThreads::ScopedLock<OpenThreads::Mutex> lock(m_factoryListMutex);
   std::vector<ossim::StreamFactoryBase*>::iterator iter = std::find(
      m_factoryList.begin(), m_factoryList.end(), factory);
   if(iter != m_factoryList.end())
   {
      m_factoryList.erase( iter );
   }
}

// Deprecated code:
ossimStreamFactoryRegistry* ossimStreamFactoryRegistry::theInstance = 0;

ossimStreamFactoryRegistry::ossimStreamFactoryRegistry()
{
}

ossimStreamFactoryRegistry::~ossimStreamFactoryRegistry()
{
}

ossimStreamFactoryRegistry* ossimStreamFactoryRegistry::instance()
{
   if(!theInstance)
   {
      theInstance = new ossimStreamFactoryRegistry();
      theInstance->registerFactory(ossimStreamFactory::instance());
   }

   return theInstance;
}

std::shared_ptr<ossim::ifstream> ossimStreamFactoryRegistry::createIFStream(
   const ossimFilename& file, std::ios_base::openmode openMode) const
{
   std::shared_ptr<ossim::ifstream>result(0);

   for(ossim_uint32 idx = 0; ((idx < theFactoryList.size())&&(!result)); ++idx)
   {
      result = theFactoryList[idx]->createIFStream(file, openMode);
   }

   if(!result)
   {
      result = std::make_shared<ossim::ifstream>( ossim::ifstream(file.c_str(), openMode) );
   }

   return result;

}

ossimRefPtr<ossimIFStream>
ossimStreamFactoryRegistry::createNewIFStream(
   const ossimFilename& file,
   std::ios_base::openmode openMode) const
{
   ossim_uint32 idx = 0;
   ossimRefPtr<ossimIFStream> result = 0;
   for(idx = 0; ((idx < theFactoryList.size())&&(!result)); ++idx)
   {
      result = theFactoryList[idx]->createNewIFStream(file, openMode);
   }

   if(!result)
   {
      result = new ossimIFStream(file.c_str(),
                                 openMode);
//       result = new std::ifstream(file.c_str(),
//                                  openMode);
   }

   return result;
}

void ossimStreamFactoryRegistry::registerFactory(ossimStreamFactoryBase* factory)
{
   std::vector<ossimStreamFactoryBase*>::iterator iter = std::find(theFactoryList.begin(),
                                                                  theFactoryList.end(),
                                                                  factory);
   if(iter == theFactoryList.end())
   {
      theFactoryList.push_back(factory);
   }
}

ossimStreamFactoryRegistry::ossimStreamFactoryRegistry(const ossimStreamFactoryRegistry&)
{}
<commit_msg>Warning fix.<commit_after>//*******************************************************************
//
// License:  See top level LICENSE.txt file.
//
// Author: Garrett Potts
//
//*******************************************************************
// $Id$

#include <ossim/base/ossimStreamFactoryRegistry.h>
#include <ossim/base/ossimStreamFactory.h>
#include <ossim/base/ossimIoStream.h>
#include <ossim/base/ossimFilename.h>

#include <fstream>
#include <algorithm>

ossim::StreamFactoryRegistry* ossim::StreamFactoryRegistry::m_instance = 0;

ossim::StreamFactoryRegistry::StreamFactoryRegistry()
{
}

ossim::StreamFactoryRegistry::~StreamFactoryRegistry()
{
}

ossim::StreamFactoryRegistry* ossim::StreamFactoryRegistry::instance()
{
   if(!m_instance)
   {
      m_instance = new ossim::StreamFactoryRegistry();

      // Add factory from the core.
      m_instance->registerFactory(ossim::StreamFactory::instance());
   }

   return m_instance;
}

std::shared_ptr<ossim::istream> ossim::StreamFactoryRegistry::createIstream(
   const ossimString& connectionString, std::ios_base::openmode openMode) const
{
   std::shared_ptr<ossim::istream> result(0);
   ossim_uint32 i = 0;
   for(i = 0; (i < m_factoryList.size())&&(!result); ++i)
   {
      result = m_factoryList[i]->createIstream(connectionString, openMode);
   }
   return result;
}

std::shared_ptr<ossim::ostream> ossim::StreamFactoryRegistry::createOstream(
   const ossimString& /*connectionString*/, std::ios_base::openmode /*openMode*/) const
{
   std::shared_ptr<ossim::ostream> result(0);
   return result;
}

std::shared_ptr<ossim::iostream> ossim::StreamFactoryRegistry::createIOstream(
   const ossimString& /*connectionString*/, std::ios_base::openmode /*openMode*/) const
{
   std::shared_ptr<ossim::iostream> result(0);
   return result;
}

void ossim::StreamFactoryRegistry::registerFactory(ossim::StreamFactoryBase* factory)
{
   std::vector<ossim::StreamFactoryBase*>::iterator iter = std::find(
      m_factoryList.begin(), m_factoryList.end(), factory);
   if(iter == m_factoryList.end())
   {
      m_factoryList.push_back(factory);
   }
}

void ossim::StreamFactoryRegistry::unregisterFactory(StreamFactoryBase* factory)
{
   // OpenThreads::ScopedLock<OpenThreads::Mutex> lock(m_factoryListMutex);
   std::vector<ossim::StreamFactoryBase*>::iterator iter = std::find(
      m_factoryList.begin(), m_factoryList.end(), factory);
   if(iter != m_factoryList.end())
   {
      m_factoryList.erase( iter );
   }
}

// Deprecated code:
ossimStreamFactoryRegistry* ossimStreamFactoryRegistry::theInstance = 0;

ossimStreamFactoryRegistry::ossimStreamFactoryRegistry()
{
}

ossimStreamFactoryRegistry::~ossimStreamFactoryRegistry()
{
}

ossimStreamFactoryRegistry* ossimStreamFactoryRegistry::instance()
{
   if(!theInstance)
   {
      theInstance = new ossimStreamFactoryRegistry();
      theInstance->registerFactory(ossimStreamFactory::instance());
   }

   return theInstance;
}

std::shared_ptr<ossim::ifstream> ossimStreamFactoryRegistry::createIFStream(
   const ossimFilename& file, std::ios_base::openmode openMode) const
{
   std::shared_ptr<ossim::ifstream>result(0);

   for(ossim_uint32 idx = 0; ((idx < theFactoryList.size())&&(!result)); ++idx)
   {
      result = theFactoryList[idx]->createIFStream(file, openMode);
   }

   if(!result)
   {
      result = std::make_shared<ossim::ifstream>( ossim::ifstream(file.c_str(), openMode) );
   }

   return result;

}

ossimRefPtr<ossimIFStream>
ossimStreamFactoryRegistry::createNewIFStream(
   const ossimFilename& file,
   std::ios_base::openmode openMode) const
{
   ossim_uint32 idx = 0;
   ossimRefPtr<ossimIFStream> result = 0;
   for(idx = 0; ((idx < theFactoryList.size())&&(!result)); ++idx)
   {
      result = theFactoryList[idx]->createNewIFStream(file, openMode);
   }

   if(!result)
   {
      result = new ossimIFStream(file.c_str(),
                                 openMode);
//       result = new std::ifstream(file.c_str(),
//                                  openMode);
   }

   return result;
}

void ossimStreamFactoryRegistry::registerFactory(ossimStreamFactoryBase* factory)
{
   std::vector<ossimStreamFactoryBase*>::iterator iter = std::find(theFactoryList.begin(),
                                                                  theFactoryList.end(),
                                                                  factory);
   if(iter == theFactoryList.end())
   {
      theFactoryList.push_back(factory);
   }
}

ossimStreamFactoryRegistry::ossimStreamFactoryRegistry(const ossimStreamFactoryRegistry&)
{}
<|endoftext|>


<commit_before>#ifndef BNI_INFERENCE_LIKELIHOOD_WEIGHTING_HPP
#define BNI_INFERENCE_LIKELIHOOD_WEIGHTING_HPP

#include <algorithm>
#include <functional>
#include <random>
#include <bayesian/graph.hpp>
#include <bayesian/matrix.hpp>

namespace bn {
namespace inference {

class likelihood_weighting {
public:
    typedef std::unordered_map<vertex_type, int> evidence_list;
    typedef std::unordered_map<vertex_type, int> pattern_list;
    typedef std::unordered_map<bn::condition_t, std::size_t> newer_pattern_list;
    typedef std::unordered_map<vertex_type, matrix_type> return_type;

    explicit likelihood_weighting(graph_t const& graph)
        : graph_(graph)
    {
    }

    virtual ~likelihood_weighting() = default;

    // Run: Likelihood Weighting
    return_type operator() (evidence_list const& evidence, std::uint64_t const sample_num = 10000)
    {
        return_type ret;

        // Initialize
        for(auto const& node : graph_.vertex_list())
        {
            ret[node].resize(1, node->selectable_num, 0.0);
        }

        // Generate Sample
        for(std::uint64_t i = 0; i < sample_num; ++i)
        {
            auto const sample = weighted_sample(evidence);
            pattern_list const& pattern = sample.first;
            double const& w = sample.second;

            for(auto const& node : graph_.vertex_list())
            {
                auto const node_select = pattern.at(node);
                ret[node][0][node_select] += w;
            }
        }

        // Normalization
        for(auto const& node : graph_.vertex_list())
        {
            ret[node] = normalize(ret[node]);
        }

        return ret;
    }

    // Make: accurate sample
    std::pair<newer_pattern_list, return_type> make_samples_min(
        evidence_list const& evidence,
        std::uint64_t const unit_size/* = 1000000/* 1'000'000 */,
        double const epsilon/* = 0.001*/
        )
    {
        newer_pattern_list patterns;

        return_type w_list;
        return_type probabilities;

        // Initialize
        for(auto const& node : graph_.vertex_list())
        {
            w_list[node].resize(1, node->selectable_num, 0.0);
            probabilities[node].resize(1, node->selectable_num, 0.0);
        }

        while(true)
        {
            // Generate one unit
            for(std::uint64_t i = 0; i < unit_size; ++i)
            {
                auto const sample = weighted_sample(evidence);
                pattern_list const& pattern = sample.first;
                double const& w = sample.second;

                for(auto const& node : graph_.vertex_list())
                {
                    auto const node_select = pattern.at(node);
                    w_list[node][0][node_select] += w;
                }

                auto it = patterns.find(pattern);
                if(it != patterns.cend()) ++(it->second);
                else                      patterns[pattern] = 1;
            }

            double max_difference = std::numeric_limits<double>::min();
            for(auto const& node : graph_.vertex_list())
            {
                auto& old_probability = probabilities[node];
                auto next_probability = normalize(w_list[node]);
                for(std::size_t i = 0; i < next_probability.width(); ++i)
                {
                    max_difference = std::max(max_difference, std::abs(old_probability[0][i] - next_probability[0][i]));
                }

                old_probability = std::move(next_probability);
            }

            if(max_difference < epsilon) break;
        }

        return std::make_pair(std::move(patterns), std::move(probabilities));
    }

    // Make: accurate sample
    // 非推奨化する
    std::pair<std::vector<pattern_list>, return_type> make_samples(
        evidence_list const& evidence,
        std::uint64_t const unit_size/* = 1000000/* 1'000'000 */,
        double const epsilon/* = 0.001*/,
        std::function<void(std::vector<pattern_list>&)> handler
        )
    {
        std::vector<pattern_list> patterns;
        return_type w_list;
        return_type probabilities;

        // Initialize
        for(auto const& node : graph_.vertex_list())
        {
            w_list[node].resize(1, node->selectable_num, 0.0);
            probabilities[node].resize(1, node->selectable_num, 0.0);
        }

        while(true)
        {
            // Generate one unit
            patterns.reserve(unit_size + patterns.capacity());
            for(std::uint64_t i = 0; i < unit_size; ++i)
            {
                auto const sample = weighted_sample(evidence);
                pattern_list const& pattern = sample.first;
                double const& w = sample.second;

                for(auto const& node : graph_.vertex_list())
                {
                    auto const node_select = pattern.at(node);
                    w_list[node][0][node_select] += w;
                }

                patterns.push_back(pattern);
            }

            handler(patterns);

            double max_difference = std::numeric_limits<double>::min();
            for(auto const& node : graph_.vertex_list())
            {
                auto& old_probability = probabilities[node];
                auto next_probability = normalize(w_list[node]);
                for(std::size_t i = 0; i < next_probability.width(); ++i)
                {
                    max_difference = std::max(max_difference, std::abs(old_probability[0][i] - next_probability[0][i]));
                }

                old_probability = std::move(next_probability);
            }

            if(max_difference < epsilon) break;
        }

        return std::make_pair(patterns, probabilities);
    }

private:
    // Make a sample according to evidence node
    // evidenceノードに従って，1サンプルを作成する
    std::pair<pattern_list, double> weighted_sample(evidence_list const& evidence)
    {
        double w = 1.0;
        pattern_list pattern;

        // 再帰関数
        std::function<void(graph_t const&, vertex_type const&, std::vector<vertex_type>&)> recursion;
        recursion = [this, &recursion, &w, &pattern, &evidence](graph_t const& graph_, vertex_type const& target, std::vector<vertex_type>& remain_node)
            {
                condition_t parent_cond;

                for(auto const& parent : graph_.in_vertexes(target))
                {
                    // 親がまだ設定されていなければ再帰
                    auto const it = std::find(remain_node.cbegin(), remain_node.cend(), parent);
                    if(it != remain_node.cend())
                    {
                        remain_node.erase(it);
                        recursion(graph_, parent, remain_node);
                    }

                    // 条件追加
                    parent_cond[parent] = pattern[parent];
                }

                // evidenceに含まれれば or 含まれなければ乱数
                auto const evidence_it = evidence.find(target);
                if(evidence_it != evidence.end())
                {
                    w *= target->cpt[parent_cond].second.at(evidence_it->second);
                    pattern[target] = evidence_it->second;
                }
                else
                {
                    int const select = make_random_by_weight(probability_generator_(), target->cpt[parent_cond].second);
                    pattern[target] = select;
                }
            };

        // ノードがなくなるまで再帰関数を回す
        auto node_list = graph_.vertex_list();
        while(!node_list.empty())
        {
            // 最後尾のノードを対象とする
            auto const node = node_list.back();
            node_list.pop_back();

            recursion(graph_, node, node_list);
        }

        return std::make_pair(pattern, w);
    }

    // Using weight, select from random value
    // weightを使って，ランダム値からそれがどの選択値になるか判断する
    int make_random_by_weight(double const value, std::vector<double> const& weight) const
    {
        assert(0.0 <= value && value < 1.0);

        double total = 0.0;
        for(int i = 0; i < weight.size(); ++i)
        {
            auto const old_total = total;
            total += weight.at(i);
            if(old_total <= value && value < total)
            {
                return i;
            }
        }

        return weight.size() - 1;
    }

    // Normalization Σ[i,j](a_ij) = 1
    // (重複)
    matrix_type normalize(matrix_type target) const
    {
        double sum = 0;

        for(std::size_t i = 0; i < target.height(); ++i)
            for(std::size_t j = 0; j < target.width(); ++j)
                sum += target[i][j];

        for(std::size_t i = 0; i < target.height(); ++i)
            for(std::size_t j = 0; j < target.width(); ++j)
                target[i][j] /= sum;

        return target;
    }

    // 乱数生成器
    class probability_generator {
    public:
        probability_generator()
            : distribution_(0.0, 1.0)
        {
            std::random_device rand_dev;
            std::vector<std::uint_least32_t> vec(10);
            std::generate(vec.begin(), vec.end(), std::ref(rand_dev));
            std::seed_seq seed(vec.begin(), vec.end());
            engine_.reset(new std::mt19937(seed));
        }

        double operator() ()
        {
            return distribution_(*engine_);
        }

    private:
        std::unique_ptr<std::mt19937> engine_;
        std::uniform_real_distribution<double> distribution_;
    };

    graph_t const graph_;
    probability_generator probability_generator_;
};

} // namespace inference
} // namespace bn

#endif // #ifndef BNI_INFERENCE_LIKELIHOOD_WEIGHTING_HPP

<commit_msg>Delete "likelihood_weighting::make_samples" that is deprecated function, and rename "likelihood_weighting::make_samples_min" to "likelihood_weighting::make_samples".<commit_after>#ifndef BNI_INFERENCE_LIKELIHOOD_WEIGHTING_HPP
#define BNI_INFERENCE_LIKELIHOOD_WEIGHTING_HPP

#include <algorithm>
#include <functional>
#include <random>
#include <bayesian/graph.hpp>
#include <bayesian/matrix.hpp>

namespace bn {
namespace inference {

class likelihood_weighting {
public:
    typedef std::unordered_map<vertex_type, int> evidence_list;
    typedef std::unordered_map<vertex_type, int> pattern_list;
    typedef std::unordered_map<bn::condition_t, std::size_t> sample_list;
    typedef std::unordered_map<vertex_type, matrix_type> return_type;

    explicit likelihood_weighting(graph_t const& graph)
        : graph_(graph)
    {
    }

    virtual ~likelihood_weighting() = default;

    // Run: Likelihood Weighting
    return_type operator() (evidence_list const& evidence, std::uint64_t const sample_num = 10000)
    {
        return_type ret;

        // Initialize
        for(auto const& node : graph_.vertex_list())
        {
            ret[node].resize(1, node->selectable_num, 0.0);
        }

        // Generate Sample
        for(std::uint64_t i = 0; i < sample_num; ++i)
        {
            auto const sample = weighted_sample(evidence);
            pattern_list const& pattern = sample.first;
            double const& w = sample.second;

            for(auto const& node : graph_.vertex_list())
            {
                auto const node_select = pattern.at(node);
                ret[node][0][node_select] += w;
            }
        }

        // Normalization
        for(auto const& node : graph_.vertex_list())
        {
            ret[node] = normalize(ret[node]);
        }

        return ret;
    }

    // Make: accurate sample
    std::pair<sample_list, return_type> make_samples(
        evidence_list const& evidence,
        std::uint64_t const unit_size = 1000000/* 1'000'000 */,
        double const epsilon = 0.001
        )
    {
        sample_list patterns;

        return_type w_list;
        return_type probabilities;

        // Initialize
        for(auto const& node : graph_.vertex_list())
        {
            w_list[node].resize(1, node->selectable_num, 0.0);
            probabilities[node].resize(1, node->selectable_num, 0.0);
        }

        while(true)
        {
            // Generate one unit
            for(std::uint64_t i = 0; i < unit_size; ++i)
            {
                auto const sample = weighted_sample(evidence);
                pattern_list const& pattern = sample.first;
                double const& w = sample.second;

                for(auto const& node : graph_.vertex_list())
                {
                    auto const node_select = pattern.at(node);
                    w_list[node][0][node_select] += w;
                }

                auto it = patterns.find(pattern);
                if(it != patterns.cend()) ++(it->second);
                else                      patterns[pattern] = 1;
            }

            double max_difference = std::numeric_limits<double>::min();
            for(auto const& node : graph_.vertex_list())
            {
                auto& old_probability = probabilities[node];
                auto next_probability = normalize(w_list[node]);
                for(std::size_t i = 0; i < next_probability.width(); ++i)
                {
                    max_difference = std::max(max_difference, std::abs(old_probability[0][i] - next_probability[0][i]));
                }

                old_probability = std::move(next_probability);
            }

            if(max_difference < epsilon) break;
        }

        return std::make_pair(std::move(patterns), std::move(probabilities));
    }

private:
    // Make a sample according to evidence node
    // evidenceノードに従って，1サンプルを作成する
    std::pair<pattern_list, double> weighted_sample(evidence_list const& evidence)
    {
        double w = 1.0;
        pattern_list pattern;

        // 再帰関数
        std::function<void(graph_t const&, vertex_type const&, std::vector<vertex_type>&)> recursion;
        recursion = [this, &recursion, &w, &pattern, &evidence](graph_t const& graph_, vertex_type const& target, std::vector<vertex_type>& remain_node)
            {
                condition_t parent_cond;

                for(auto const& parent : graph_.in_vertexes(target))
                {
                    // 親がまだ設定されていなければ再帰
                    auto const it = std::find(remain_node.cbegin(), remain_node.cend(), parent);
                    if(it != remain_node.cend())
                    {
                        remain_node.erase(it);
                        recursion(graph_, parent, remain_node);
                    }

                    // 条件追加
                    parent_cond[parent] = pattern[parent];
                }

                // evidenceに含まれれば or 含まれなければ乱数
                auto const evidence_it = evidence.find(target);
                if(evidence_it != evidence.end())
                {
                    w *= target->cpt[parent_cond].second.at(evidence_it->second);
                    pattern[target] = evidence_it->second;
                }
                else
                {
                    int const select = make_random_by_weight(probability_generator_(), target->cpt[parent_cond].second);
                    pattern[target] = select;
                }
            };

        // ノードがなくなるまで再帰関数を回す
        auto node_list = graph_.vertex_list();
        while(!node_list.empty())
        {
            // 最後尾のノードを対象とする
            auto const node = node_list.back();
            node_list.pop_back();

            recursion(graph_, node, node_list);
        }

        return std::make_pair(pattern, w);
    }

    // Using weight, select from random value
    // weightを使って，ランダム値からそれがどの選択値になるか判断する
    int make_random_by_weight(double const value, std::vector<double> const& weight) const
    {
        assert(0.0 <= value && value < 1.0);

        double total = 0.0;
        for(int i = 0; i < weight.size(); ++i)
        {
            auto const old_total = total;
            total += weight.at(i);
            if(old_total <= value && value < total)
            {
                return i;
            }
        }

        return weight.size() - 1;
    }

    // Normalization Σ[i,j](a_ij) = 1
    // (重複)
    matrix_type normalize(matrix_type target) const
    {
        double sum = 0;

        for(std::size_t i = 0; i < target.height(); ++i)
            for(std::size_t j = 0; j < target.width(); ++j)
                sum += target[i][j];

        for(std::size_t i = 0; i < target.height(); ++i)
            for(std::size_t j = 0; j < target.width(); ++j)
                target[i][j] /= sum;

        return target;
    }

    // 乱数生成器
    class probability_generator {
    public:
        probability_generator()
            : distribution_(0.0, 1.0)
        {
            std::random_device rand_dev;
            std::vector<std::uint_least32_t> vec(10);
            std::generate(vec.begin(), vec.end(), std::ref(rand_dev));
            std::seed_seq seed(vec.begin(), vec.end());
            engine_.reset(new std::mt19937(seed));
        }

        double operator() ()
        {
            return distribution_(*engine_);
        }

    private:
        std::unique_ptr<std::mt19937> engine_;
        std::uniform_real_distribution<double> distribution_;
    };

    graph_t const graph_;
    probability_generator probability_generator_;
};

} // namespace inference
} // namespace bn

#endif // #ifndef BNI_INFERENCE_LIKELIHOOD_WEIGHTING_HPP

<|endoftext|>


<commit_before>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <fnord-base/exception.h>
#include <fnord-base/io/FileLock.h>

namespace fnord {

FileLock::FileLock(
    const String& filename) :
    filename_(filename),
    file_(File::openFile(filename, File::O_CREATEOROPEN | File::O_WRITE)),
    locked_(false) {}

FileLock::~FileLock() {
  if (locked_) {
    unlock();
  }
}

void FileLock::lock(bool block /* = false */) {
  if (locked_) {
    RAISEF(kRuntimeError, "File is already locked: $0", filename_);
  }

  auto flag = LOCK_EX;
  if (!block) {
    flag |= LOCK_NB;
  }

  if (flock(file_.fd(), flag) != 0) {
    RAISE_ERRNO(kRuntimeError, "can't lock file: %s", filename_.c_str());
  }

  locked_ = true;
}

void FileLock::unlock() {
  if (!locked_) {
    RAISEF(kRuntimeError, "File is not locked: $0", filename_);
  }

  if (flock(file_.fd(), LOCK_UN) != 0) {
    RAISE_ERRNO(kRuntimeError, "can't unlock file: %s", filename_.c_str());
  }

  locked_ = false;
}

}
<commit_msg>include fix<commit_after>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <sys/file.h>
#include <fnord-base/exception.h>
#include <fnord-base/io/FileLock.h>

namespace fnord {

FileLock::FileLock(
    const String& filename) :
    filename_(filename),
    file_(File::openFile(filename, File::O_CREATEOROPEN | File::O_WRITE)),
    locked_(false) {}

FileLock::~FileLock() {
  if (locked_) {
    unlock();
  }
}

void FileLock::lock(bool block /* = false */) {
  if (locked_) {
    RAISEF(kRuntimeError, "File is already locked: $0", filename_);
  }

  auto flag = LOCK_EX;
  if (!block) {
    flag |= LOCK_NB;
  }

  if (flock(file_.fd(), flag) != 0) {
    RAISE_ERRNO(kRuntimeError, "can't lock file: %s", filename_.c_str());
  }

  locked_ = true;
}

void FileLock::unlock() {
  if (!locked_) {
    RAISEF(kRuntimeError, "File is not locked: $0", filename_);
  }

  if (flock(file_.fd(), LOCK_UN) != 0) {
    RAISE_ERRNO(kRuntimeError, "can't unlock file: %s", filename_.c_str());
  }

  locked_ = false;
}

}
<|endoftext|>


<commit_before>/****************************************************************************
**
** This file is part of QtCompositor**
**
** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
**
** Contact:  Nokia Corporation qt-info@nokia.com
**
** You may use this file under the terms of the BSD license as follows:
**
** 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 Nokia Corporation and its Subsidiary(-ies) nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
****************************************************************************/

#include "waylandcompositor.h"

#include "waylandsurface.h"

#include <QApplication>
#include <QMainWindow>
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QWidget>
#include <QTimer>
#include <QPainter>
#include <QMouseEvent>

#include <QDebug>

// This has no GL support, meaning only readback-based GL clients will work.
// Others, e.g. xcomposite-glx, will typically crash the client as there is no
// corresponding integration on the compositor side.

class QSurfaceWidget : public QWidget
{
    Q_OBJECT
public:
    QSurfaceWidget(WaylandSurface *surface, QWidget *parent = 0) : QWidget(parent), m_surface(surface) {
	setMouseTracking(true);

	connect(m_surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &)));
    }

private slots:
    void surfaceDamaged(const QRect &rect) {

        // NB! This is dangerous. There may be no paintEvent() called, for
        // example if the mdi subwindow is completely covered by another one.
        // And in that case there is no frameFinished() -> the client may block
        // in its waitForFrameSync() for a long time...

	update(rect);
    }

protected:
    void paintEvent(QPaintEvent *) {
        QPainter p(this);

	if (m_surface->type() == WaylandSurface::Shm)
	    p.drawImage(0, 0, m_surface->image());
	else
	    qWarning() << "Can't draw surface of type" << m_surface->type();

        m_surface->frameFinished();
    }

    void mousePressEvent(QMouseEvent *e) {
	m_surface->sendMousePressEvent(e->pos(), e->button());
    }

    void mouseMoveEvent(QMouseEvent *e) {
	m_surface->sendMouseMoveEvent(e->pos());
    }

    void mouseReleaseEvent(QMouseEvent *e) {
	m_surface->sendMouseReleaseEvent(e->pos(), e->button());
    }

    void keyPressEvent(QKeyEvent *e) {
        m_surface->sendKeyPressEvent(e->nativeScanCode());
    }

    void keyReleaseEvent(QKeyEvent *e) {
        m_surface->sendKeyReleaseEvent(e->nativeScanCode());
    }

private:
    WaylandSurface *m_surface;
};

class QSurfaceSubWindow : public QMdiSubWindow
{
    Q_OBJECT
public:
    QSurfaceSubWindow(WaylandSurface *surface, QWidget *parent = 0) : QMdiSubWindow(parent), m_surface(surface) {
	QSurfaceWidget *widget = new QSurfaceWidget(surface, this);

	setContentsMargins(0, 0, 0, 0);
	setMouseTracking(true);
	setWidget(widget);

        connect(m_surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *)));
        connect(m_surface, SIGNAL(mapped()), this, SLOT(surfaceMapped()));
        connect(m_surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &)));
    }

private slots:
    void surfaceDestroyed(QObject *) {
	hide();
	deleteLater();
    }

    void surfaceMapped() {
        m_surface->setInputFocus();
        widget()->setMinimumSize(m_surface->size());
        resize(sizeHint());
        show();
    }

    void surfaceDamaged(const QRect &) {
    }

protected:
    void focusInEvent(QFocusEvent * e) {
	QMdiSubWindow::focusInEvent(e);
	widget()->setFocus();
	m_surface->setInputFocus();
    }

    void resizeEvent(QResizeEvent *e) {
	QMdiSubWindow::resizeEvent(e);
	m_surface->setGeometry(geometry());
    }

    void moveEvent(QMoveEvent *e) {
	QMdiSubWindow::moveEvent(e);
	m_surface->setGeometry(geometry());
    }

protected:
    WaylandSurface *m_surface;
};

class QWidgetCompositorMdi : public QMainWindow, public WaylandCompositor
{
    Q_OBJECT
public:
    QWidgetCompositorMdi() : WaylandCompositor(this->windowHandle()) {
	m_mdiArea = new QMdiArea(this);

	setCentralWidget(m_mdiArea);
    }

protected:
    void surfaceCreated(WaylandSurface *surface) {
	QMdiSubWindow *window = new QSurfaceSubWindow(surface);

	window->setAttribute(Qt::WA_DeleteOnClose);
	m_mdiArea->addSubWindow(window);
    }

private:
    QMdiArea *m_mdiArea;
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidgetCompositorMdi compositor;

    compositor.resize(800, 600);
    compositor.show();

    return app.exec();

}

#include "main.moc"
<commit_msg>Have a crack at fixing setGeometry calls.<commit_after>/****************************************************************************
**
** This file is part of QtCompositor**
**
** Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
**
** Contact:  Nokia Corporation qt-info@nokia.com
**
** You may use this file under the terms of the BSD license as follows:
**
** 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 Nokia Corporation and its Subsidiary(-ies) nor the
** names of its contributors may be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
****************************************************************************/

#include "waylandcompositor.h"

#include "waylandsurface.h"

#include <QApplication>
#include <QMainWindow>
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QWidget>
#include <QTimer>
#include <QPainter>
#include <QMouseEvent>

#include <QDebug>

// This has no GL support, meaning only readback-based GL clients will work.
// Others, e.g. xcomposite-glx, will typically crash the client as there is no
// corresponding integration on the compositor side.

class QSurfaceWidget : public QWidget
{
    Q_OBJECT
public:
    QSurfaceWidget(WaylandSurface *surface, QWidget *parent = 0) : QWidget(parent), m_surface(surface) {
	setMouseTracking(true);

	connect(m_surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &)));
    }

private slots:
    void surfaceDamaged(const QRect &rect) {

        // NB! This is dangerous. There may be no paintEvent() called, for
        // example if the mdi subwindow is completely covered by another one.
        // And in that case there is no frameFinished() -> the client may block
        // in its waitForFrameSync() for a long time...

	update(rect);
    }

protected:
    void paintEvent(QPaintEvent *) {
        QPainter p(this);

	if (m_surface->type() == WaylandSurface::Shm)
	    p.drawImage(0, 0, m_surface->image());
	else
	    qWarning() << "Can't draw surface of type" << m_surface->type();

        m_surface->frameFinished();
    }

    void mousePressEvent(QMouseEvent *e) {
	m_surface->sendMousePressEvent(e->pos(), e->button());
    }

    void mouseMoveEvent(QMouseEvent *e) {
	m_surface->sendMouseMoveEvent(e->pos());
    }

    void mouseReleaseEvent(QMouseEvent *e) {
	m_surface->sendMouseReleaseEvent(e->pos(), e->button());
    }

    void keyPressEvent(QKeyEvent *e) {
        m_surface->sendKeyPressEvent(e->nativeScanCode());
    }

    void keyReleaseEvent(QKeyEvent *e) {
        m_surface->sendKeyReleaseEvent(e->nativeScanCode());
    }

private:
    WaylandSurface *m_surface;
};

class QSurfaceSubWindow : public QMdiSubWindow
{
    Q_OBJECT
public:
    QSurfaceSubWindow(WaylandSurface *surface, QWidget *parent = 0) : QMdiSubWindow(parent), m_surface(surface) {
	QSurfaceWidget *widget = new QSurfaceWidget(surface, this);

	setContentsMargins(0, 0, 0, 0);
	setMouseTracking(true);
	setWidget(widget);

        connect(m_surface, SIGNAL(destroyed(QObject *)), this, SLOT(surfaceDestroyed(QObject *)));
        connect(m_surface, SIGNAL(mapped()), this, SLOT(surfaceMapped()));
        connect(m_surface, SIGNAL(damaged(const QRect &)), this, SLOT(surfaceDamaged(const QRect &)));
    }

private slots:
    void surfaceDestroyed(QObject *) {
	hide();
	deleteLater();
    }

    void surfaceMapped() {
        m_surface->setInputFocus();
        widget()->setMinimumSize(m_surface->size());
        resize(sizeHint());
        show();
    }

    void surfaceDamaged(const QRect &) {
    }

protected:
    void focusInEvent(QFocusEvent * e) {
	QMdiSubWindow::focusInEvent(e);
	widget()->setFocus();
	m_surface->setInputFocus();
    }

    void resizeEvent(QResizeEvent *e) {
        QMdiSubWindow::resizeEvent(e);
        m_surface->setPos(QPointF(geometry().topLeft()));
        m_surface->setSize(geometry().size());
    }

    void moveEvent(QMoveEvent *e) {
        QMdiSubWindow::moveEvent(e);
        m_surface->setPos(QPointF(geometry().topLeft()));
        m_surface->setSize(geometry().size());
    }

protected:
    WaylandSurface *m_surface;
};

class QWidgetCompositorMdi : public QMainWindow, public WaylandCompositor
{
    Q_OBJECT
public:
    QWidgetCompositorMdi() : WaylandCompositor(this->windowHandle()) {
	m_mdiArea = new QMdiArea(this);

	setCentralWidget(m_mdiArea);
    }

protected:
    void surfaceCreated(WaylandSurface *surface) {
	QMdiSubWindow *window = new QSurfaceSubWindow(surface);

	window->setAttribute(Qt::WA_DeleteOnClose);
	m_mdiArea->addSubWindow(window);
    }

private:
    QMdiArea *m_mdiArea;
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidgetCompositorMdi compositor;

    compositor.resize(800, 600);
    compositor.show();

    return app.exec();

}

#include "main.moc"
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2003-2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY, TITLE, NONINFRINGEMENT or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 * 02111-1307  USA
 */

#include "winsock2.h"

#include <objbase.h>
#include <initguid.h>
#include <connmgr.h>
#include <wininet.h>

#include "http/GPRSConnection.h"
#include "base/Log.h"

/*
* Method to test if connection is alive. If no one is found, it tries to establish
* default connection.
*/

BOOL EstablishConnection() {

    HANDLE  phWebConnection = NULL;

    // First we check if we might have a connection
    DWORD  pdwStatus = 0;
    LOG.info("Establish connection: test internet connection status...");
    ConnMgrConnectionStatus(phWebConnection, &pdwStatus);

    if (pdwStatus == CONNMGR_STATUS_CONNECTED) {
        LOG.info("Already connected");
        //We are already connected!
        return TRUE;
    }
#if _WIN32_WCE > 0x500
    else if (pdwStatus == CONNMGR_STATUS_PHONEOFF) {
        LOG.info("phone off");
        //We are already connected!
        return FALSE;
    }
#endif
    else {
        LOG.debug("Not connected: try to connect...");
        //We are not connected, so lets try:
        //The CONNECTIONINFO is the structure that
        //tells Connection Manager how we want
        //to connect

        CONNMGR_CONNECTIONINFO sConInfo;
        memset(&sConInfo,0, sizeof(CONNMGR_CONNECTIONINFO));
        sConInfo.cbSize = sizeof(CONNMGR_CONNECTIONINFO);
        // We want to use the "guidDestNet" parameter
        sConInfo.dwParams = CONNMGR_PARAM_GUIDDESTNET;
        // This is the highest data priority.
        sConInfo.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;
        // sConInfo.dwFlags = 0;
        sConInfo.dwFlags=CONNMGR_FLAG_PROXY_HTTP;
        // Lets be nice and share the connection with
        // other applications
        sConInfo.bExclusive = FALSE;
        sConInfo.bDisabled = FALSE;
        sConInfo.guidDestNet = IID_DestNetInternet;
        LOG.debug("Try to establish connection...");
        if (ConnMgrEstablishConnection(&sConInfo,&phWebConnection) == S_OK) {
            LOG.debug("Start internet connection process...");
            //We start successfully process!
            for (unsigned int k = 0; k < 6; k++) {
                ConnMgrConnectionStatus(phWebConnection,&pdwStatus);

                if (pdwStatus == CONNMGR_STATUS_CONNECTED) {
                    LOG.info("Internet connection succesfully completed.");
                    return TRUE;

                }
                else {
                    if (pdwStatus == CONNMGR_STATUS_CONNECTIONCANCELED || pdwStatus == CONNMGR_STATUS_WAITINGCONNECTIONABORT) {
                        LOG.debug("Internet connection not succeded.");
                        return FALSE;

                    }
                    Sleep(2000);

                    ConnMgrConnectionStatus(phWebConnection,&pdwStatus);
                    if (pdwStatus == CONNMGR_STATUS_WAITINGCONNECTION) {
                        // it is possible to do something...
                    }

                    if (pdwStatus == CONNMGR_STATUS_CONNECTIONCANCELED || pdwStatus == CONNMGR_STATUS_WAITINGCONNECTIONABORT) {
                        LOG.debug("Internet connection not succeded");
                        return FALSE;
                    }
                }
            }
            LOG.debug("Internet connection not succeded after connection process");
            return FALSE;
        }
        else {
            //Connection failed!
            LOG.info("Internet connection failed.");
            return FALSE;

        }

    }

}
<commit_msg>just changed log message<commit_after>/*
 * Copyright (C) 2003-2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY, TITLE, NONINFRINGEMENT or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 * 02111-1307  USA
 */

#include "winsock2.h"

#include <objbase.h>
#include <initguid.h>
#include <connmgr.h>
#include <wininet.h>

#include "http/GPRSConnection.h"
#include "base/Log.h"

/*
* Method to test if connection is alive. If no one is found, it tries to establish
* default connection.
*/

BOOL EstablishConnection() {

    HANDLE  phWebConnection = NULL;

    // First we check if we might have a connection
    DWORD  pdwStatus = 0;
    LOG.debug("Establish connection: test internet connection status...");
    ConnMgrConnectionStatus(phWebConnection, &pdwStatus);

    if (pdwStatus == CONNMGR_STATUS_CONNECTED) {
        LOG.info("Already connected");
        //We are already connected!
        return TRUE;
    }
#if _WIN32_WCE > 0x500
    else if (pdwStatus == CONNMGR_STATUS_PHONEOFF) {
        LOG.info("phone off");
        //We are already connected!
        return FALSE;
    }
#endif
    else {
        LOG.debug("Not connected: try to connect...");
        //We are not connected, so lets try:
        //The CONNECTIONINFO is the structure that
        //tells Connection Manager how we want
        //to connect

        CONNMGR_CONNECTIONINFO sConInfo;
        memset(&sConInfo,0, sizeof(CONNMGR_CONNECTIONINFO));
        sConInfo.cbSize = sizeof(CONNMGR_CONNECTIONINFO);
        // We want to use the "guidDestNet" parameter
        sConInfo.dwParams = CONNMGR_PARAM_GUIDDESTNET;
        // This is the highest data priority.
        sConInfo.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;
        // sConInfo.dwFlags = 0;
        sConInfo.dwFlags=CONNMGR_FLAG_PROXY_HTTP;
        // Lets be nice and share the connection with
        // other applications
        sConInfo.bExclusive = FALSE;
        sConInfo.bDisabled = FALSE;
        sConInfo.guidDestNet = IID_DestNetInternet;
        LOG.debug("Try to establish connection...");
        if (ConnMgrEstablishConnection(&sConInfo,&phWebConnection) == S_OK) {
            LOG.debug("Start internet connection process...");
            //We start successfully process!
            for (unsigned int k = 0; k < 6; k++) {
                ConnMgrConnectionStatus(phWebConnection,&pdwStatus);

                if (pdwStatus == CONNMGR_STATUS_CONNECTED) {
                    LOG.info("Internet connection succesfully completed.");
                    return TRUE;

                }
                else {
                    if (pdwStatus == CONNMGR_STATUS_CONNECTIONCANCELED || pdwStatus == CONNMGR_STATUS_WAITINGCONNECTIONABORT) {
                        LOG.debug("Internet connection not succeded.");
                        return FALSE;

                    }
                    Sleep(2000);

                    ConnMgrConnectionStatus(phWebConnection,&pdwStatus);
                    if (pdwStatus == CONNMGR_STATUS_WAITINGCONNECTION) {
                        // it is possible to do something...
                    }

                    if (pdwStatus == CONNMGR_STATUS_CONNECTIONCANCELED || pdwStatus == CONNMGR_STATUS_WAITINGCONNECTIONABORT) {
                        LOG.debug("Internet connection not succeded");
                        return FALSE;
                    }
                }
            }
            LOG.debug("Internet connection not succeded after connection process");
            return FALSE;
        }
        else {
            //Connection failed!
            LOG.info("Internet connection failed.");
            return FALSE;

        }

    }

}
<|endoftext|>