<commit_before>//
// Copyright (c) 2015 CNRS
//
// This file is part of Pinocchio
// Pinocchio is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// Pinocchio is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// Pinocchio If not, see
// <http://www.gnu.org/licenses/>.

#ifndef __se3_python_model_hpp__
#define __se3_python_model_hpp__

#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <eigenpy/exception.hpp>
#include <eigenpy/eigenpy.hpp>

#include "pinocchio/multibody/model.hpp"
#include "pinocchio/multibody/parser/sample-models.hpp"
#include "pinocchio/python/se3.hpp"
#include "pinocchio/python/eigen_container.hpp"
#include "pinocchio/python/handler.hpp"

namespace se3
{
  namespace python
  {
    namespace bp = boost::python;

    typedef Handler<Model> ModelHandler;

    struct ModelPythonVisitor
      : public boost::python::def_visitor< ModelPythonVisitor >
    {
    public:
      typedef Model::Index Index;
      typedef eigenpy::UnalignedEquivalent<Motion>::type Motion_fx;
      typedef eigenpy::UnalignedEquivalent<SE3>::type SE3_fx;
      typedef eigenpy::UnalignedEquivalent<Inertia>::type Inertia_fx;

      struct add_body_visitor : public boost::static_visitor<Model::Index>
      {
        ModelHandler & _model;
        Model::Index & _index;
        const SE3_fx & _placement;
        const Inertia_fx & _inertia;
        const std::string & _jName;
        const std::string & _bName;
        bool _visual;

        add_body_visitor( ModelHandler & model,
                          Model::Index & idx, const SE3_fx & placement,
                          const Inertia_fx & Y, const std::string & jointName,
                          const std::string & bodyName, bool visual)
                        : _model(model)
                        , _index(idx)
                        , _placement(placement)
                        , _inertia(Y)
                        , _jName(jointName)
                        , _bName(bodyName)
                        , _visual(visual)
        {}

        template <typename T> Model::Index operator()( T & operand ) const
        {
          return _model->addBody(_index, operand, _placement, _inertia, _jName, _bName, _visual);
        }
      };

    public:

      /* --- Convert From C++ to Python ------------------------------------- */
      // static PyObject* convert(Model const& modelConstRef)
      // {
      // 	Model * ptr = const_cast<Model*>(&modelConstRef);
      // 	return boost::python::incref(boost::python::object(ModelHandler(ptr)).ptr());
      // }
      static PyObject* convert(ModelHandler::SmartPtr_t const& ptr)
      {
	return boost::python::incref(boost::python::object(ModelHandler(ptr)).ptr());
      }

      /* --- Exposing C++ API to python through the handler ----------------- */
    template<class PyClass>
      void visit(PyClass& cl) const
      {
	cl
	  .def("getBodyId",&ModelPythonVisitor::getBodyId)
	  .def("createData",&ModelPythonVisitor::createData)

	  .def("__str__",&ModelPythonVisitor::toString)

	  .add_property("nq", &ModelPythonVisitor::nq)
	  .add_property("nv", &ModelPythonVisitor::nv)
	  .add_property("nbody", &ModelPythonVisitor::nbody)
	  .add_property("inertias",
			bp::make_function(&ModelPythonVisitor::inertias,
					  bp::return_internal_reference<>())  )
	  .add_property("jointPlacements",
			bp::make_function(&ModelPythonVisitor::jointPlacements,
					  bp::return_internal_reference<>())  )
    .add_property("joints",
      bp::make_function(&ModelPythonVisitor::joints,
            bp::return_internal_reference<>())  )
	  .add_property("parents",
			bp::make_function(&ModelPythonVisitor::parents,
					  bp::return_internal_reference<>())  )
	  .add_property("names",
			bp::make_function(&ModelPythonVisitor::names,
					  bp::return_internal_reference<>())  )
    .add_property("bodyNames",
		  bp::make_function(&ModelPythonVisitor::bodyNames,
            bp::return_internal_reference<>())  )
    .add_property("hasVisual",
      bp::make_function(&ModelPythonVisitor::hasVisual,
            bp::return_internal_reference<>())  )

    .def("addBody",&ModelPythonVisitor::addJointToModel)

      .add_property("nFixBody", &ModelPythonVisitor::nFixBody)
      .add_property("fix_lmpMi", bp::make_function(&ModelPythonVisitor::fix_lmpMi, bp::return_internal_reference<>()) )
      .add_property("fix_lastMovingParent",bp::make_function(&ModelPythonVisitor::fix_lastMovingParent,bp::return_internal_reference<>()) )
      .add_property("fix_hasVisual", bp::make_function(&ModelPythonVisitor::fix_hasVisual, bp::return_internal_reference<>())  )
      .add_property("fix_bodyNames", bp::make_function(&ModelPythonVisitor::fix_bodyNames, bp::return_internal_reference<>())  )

      .add_property("gravity",&ModelPythonVisitor::gravity,&ModelPythonVisitor::setGravity)
	  .def("BuildEmptyModel",&ModelPythonVisitor::maker_empty)
	  .staticmethod("BuildEmptyModel")
	  .def("BuildHumanoidSimple",&ModelPythonVisitor::maker_humanoidSimple)
	  .staticmethod("BuildHumanoidSimple")
	  ;
      }

      static Model::Index getBodyId( const ModelHandler & modelPtr, const std::string & name )
      { return  modelPtr->getBodyId(name); }
      static boost::shared_ptr<Data> createData(const ModelHandler& m )
      {	return boost::shared_ptr<Data>( new Data(*m) );      }

      static int nq( ModelHandler & m ) { return m->nq; }
      static int nv( ModelHandler & m ) { return m->nv; }
      static int nbody( ModelHandler & m ) { return m->nbody; }
      static std::vector<Inertia> & inertias( ModelHandler & m ) { return m->inertias; }
      static std::vector<SE3> & jointPlacements( ModelHandler & m ) { return m->jointPlacements; }
      static JointModelVector & joints( ModelHandler & m ) { return m->joints; }
      static std::vector<Model::Index> & parents( ModelHandler & m ) { return m->parents; }
      static std::vector<std::string> & names ( ModelHandler & m ) { return m->names; }
      static std::vector<std::string> & bodyNames ( ModelHandler & m ) { return m->bodyNames; }
      static std::vector<bool> & hasVisual ( ModelHandler & m ) { return m->hasVisual; }

      static Model::Index addJointToModel(  ModelHandler & modelPtr,
                                    Model::Index idx, bp::object joint,
                                    const SE3_fx & placement,
                                    const Inertia_fx & Y,
                                    const std::string & jointName,
                                    const std::string & bodyName,
                                    bool visual=false)
      {
        JointModelVariant variant = bp::extract<JointModelVariant> (joint);
        return boost::apply_visitor(add_body_visitor(modelPtr, idx, placement, Y, jointName, bodyName, visual), variant);
      }

      static int nFixBody( ModelHandler & m )                                     { return m->nFixBody; }
      static std::vector<SE3>          & fix_lmpMi           ( ModelHandler & m ) { return m->fix_lmpMi; }
      static std::vector<Model::Index> & fix_lastMovingParent( ModelHandler & m ) { return m->fix_lastMovingParent; }
      static std::vector<bool> & fix_hasVisual ( ModelHandler & m ) { return m->fix_hasVisual; }
      static std::vector<std::string> & fix_bodyNames ( ModelHandler & m ) { return m->fix_bodyNames; }

      static Motion gravity( ModelHandler & m ) { return m->gravity; }
      static void setGravity( ModelHandler & m,const Motion_fx & g ) { m->gravity = g; }

      static ModelHandler maker_empty()
      {
	return ModelHandler( new Model(),true );
      }
      static ModelHandler maker_humanoidSimple()
      {
	Model * model = new Model();
	buildModels::humanoidSimple(*model);
	return ModelHandler( model,true );
      }

      static std::string toString(const ModelHandler& m)
      {	  std::ostringstream s; s << *m; return s.str();       }

      /* --- Expose --------------------------------------------------------- */
      static void expose()
      {
	bp::class_< std::vector<Index> >("StdVec_Index")
	  .def(bp::vector_indexing_suite< std::vector<Index> >());
	bp::class_< std::vector<std::string> >("StdVec_StdString")
	  .def(bp::vector_indexing_suite< std::vector<std::string> >());
	bp::class_< std::vector<bool> >("StdVec_Bool")
	  .def(bp::vector_indexing_suite< std::vector<bool> >());
	bp::class_< std::vector<double> >("StdVec_double")
	  .def(bp::vector_indexing_suite< std::vector<double> >());
  bp::class_< JointModelVector >("StdVec_JointModelVector")
    .def(bp::vector_indexing_suite< JointModelVector, true >());

  bp::class_<ModelHandler>("Model",
         "Articulated rigid body model (const)",
         bp::no_init)
    .def(ModelPythonVisitor());

	/* Not sure if it is a good idea to enable automatic
	 * conversion. Prevent it for now */
	//bp::to_python_converter< Model,ModelPythonVisitor >();
	bp::to_python_converter< ModelHandler::SmartPtr_t,ModelPythonVisitor >();
      }

    };

  }} // namespace se3::python

#endif // ifndef __se3_python_model_hpp__

<commit_msg>[Python] Add StdVec::index binding to emulate python list behavior.<commit_after>//
// Copyright (c) 2015 CNRS
// Copyright (c) 2015 Wandercraft, 86 rue de Paris 91400 Orsay, France.
//
// This file is part of Pinocchio
// Pinocchio is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// Pinocchio is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// Pinocchio If not, see
// <http://www.gnu.org/licenses/>.

#ifndef __se3_python_model_hpp__
#define __se3_python_model_hpp__

#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <eigenpy/exception.hpp>
#include <eigenpy/eigenpy.hpp>

#include "pinocchio/multibody/model.hpp"
#include "pinocchio/multibody/parser/sample-models.hpp"
#include "pinocchio/python/se3.hpp"
#include "pinocchio/python/eigen_container.hpp"
#include "pinocchio/python/handler.hpp"

namespace se3
{
  namespace python
  {
    namespace bp = boost::python;

    typedef Handler<Model> ModelHandler;

    struct ModelPythonVisitor
      : public boost::python::def_visitor< ModelPythonVisitor >
    {
    public:
      typedef Model::Index Index;
      typedef eigenpy::UnalignedEquivalent<Motion>::type Motion_fx;
      typedef eigenpy::UnalignedEquivalent<SE3>::type SE3_fx;
      typedef eigenpy::UnalignedEquivalent<Inertia>::type Inertia_fx;

      struct add_body_visitor : public boost::static_visitor<Model::Index>
      {
        ModelHandler & _model;
        Model::Index & _index;
        const SE3_fx & _placement;
        const Inertia_fx & _inertia;
        const std::string & _jName;
        const std::string & _bName;
        bool _visual;

        add_body_visitor( ModelHandler & model,
                          Model::Index & idx, const SE3_fx & placement,
                          const Inertia_fx & Y, const std::string & jointName,
                          const std::string & bodyName, bool visual)
                        : _model(model)
                        , _index(idx)
                        , _placement(placement)
                        , _inertia(Y)
                        , _jName(jointName)
                        , _bName(bodyName)
                        , _visual(visual)
        {}

        template <typename T> Model::Index operator()( T & operand ) const
        {
          return _model->addBody(_index, operand, _placement, _inertia, _jName, _bName, _visual);
        }
      };

    public:

      /* --- Convert From C++ to Python ------------------------------------- */
      // static PyObject* convert(Model const& modelConstRef)
      // {
      // 	Model * ptr = const_cast<Model*>(&modelConstRef);
      // 	return boost::python::incref(boost::python::object(ModelHandler(ptr)).ptr());
      // }
      static PyObject* convert(ModelHandler::SmartPtr_t const& ptr)
      {
	return boost::python::incref(boost::python::object(ModelHandler(ptr)).ptr());
      }

      /* --- Exposing C++ API to python through the handler ----------------- */
    template<class PyClass>
      void visit(PyClass& cl) const
      {
	cl
	  .def("getBodyId",&ModelPythonVisitor::getBodyId)
	  .def("createData",&ModelPythonVisitor::createData)

	  .def("__str__",&ModelPythonVisitor::toString)

	  .add_property("nq", &ModelPythonVisitor::nq)
	  .add_property("nv", &ModelPythonVisitor::nv)
	  .add_property("nbody", &ModelPythonVisitor::nbody)
	  .add_property("inertias",
			bp::make_function(&ModelPythonVisitor::inertias,
					  bp::return_internal_reference<>())  )
	  .add_property("jointPlacements",
			bp::make_function(&ModelPythonVisitor::jointPlacements,
					  bp::return_internal_reference<>())  )
    .add_property("joints",
      bp::make_function(&ModelPythonVisitor::joints,
            bp::return_internal_reference<>())  )
	  .add_property("parents",
			bp::make_function(&ModelPythonVisitor::parents,
					  bp::return_internal_reference<>())  )
	  .add_property("names",
			bp::make_function(&ModelPythonVisitor::names,
					  bp::return_internal_reference<>())  )
    .add_property("bodyNames",
		  bp::make_function(&ModelPythonVisitor::bodyNames,
            bp::return_internal_reference<>())  )
    .add_property("hasVisual",
      bp::make_function(&ModelPythonVisitor::hasVisual,
            bp::return_internal_reference<>())  )

    .def("addBody",&ModelPythonVisitor::addJointToModel)

      .add_property("nFixBody", &ModelPythonVisitor::nFixBody)
      .add_property("fix_lmpMi", bp::make_function(&ModelPythonVisitor::fix_lmpMi, bp::return_internal_reference<>()) )
      .add_property("fix_lastMovingParent",bp::make_function(&ModelPythonVisitor::fix_lastMovingParent,bp::return_internal_reference<>()) )
      .add_property("fix_hasVisual", bp::make_function(&ModelPythonVisitor::fix_hasVisual, bp::return_internal_reference<>())  )
      .add_property("fix_bodyNames", bp::make_function(&ModelPythonVisitor::fix_bodyNames, bp::return_internal_reference<>())  )

      .add_property("gravity",&ModelPythonVisitor::gravity,&ModelPythonVisitor::setGravity)
	  .def("BuildEmptyModel",&ModelPythonVisitor::maker_empty)
	  .staticmethod("BuildEmptyModel")
	  .def("BuildHumanoidSimple",&ModelPythonVisitor::maker_humanoidSimple)
	  .staticmethod("BuildHumanoidSimple")
	  ;
      }

      static Model::Index getBodyId( const ModelHandler & modelPtr, const std::string & name )
      { return  modelPtr->getBodyId(name); }
      static boost::shared_ptr<Data> createData(const ModelHandler& m )
      {	return boost::shared_ptr<Data>( new Data(*m) );      }

      static int nq( ModelHandler & m ) { return m->nq; }
      static int nv( ModelHandler & m ) { return m->nv; }
      static int nbody( ModelHandler & m ) { return m->nbody; }
      static std::vector<Inertia> & inertias( ModelHandler & m ) { return m->inertias; }
      static std::vector<SE3> & jointPlacements( ModelHandler & m ) { return m->jointPlacements; }
      static JointModelVector & joints( ModelHandler & m ) { return m->joints; }
      static std::vector<Model::Index> & parents( ModelHandler & m ) { return m->parents; }
      static std::vector<std::string> & names ( ModelHandler & m ) { return m->names; }
      static std::vector<std::string> & bodyNames ( ModelHandler & m ) { return m->bodyNames; }
      static std::vector<bool> & hasVisual ( ModelHandler & m ) { return m->hasVisual; }

      static Model::Index addJointToModel(  ModelHandler & modelPtr,
                                    Model::Index idx, bp::object joint,
                                    const SE3_fx & placement,
                                    const Inertia_fx & Y,
                                    const std::string & jointName,
                                    const std::string & bodyName,
                                    bool visual=false)
      {
        JointModelVariant variant = bp::extract<JointModelVariant> (joint);
        return boost::apply_visitor(add_body_visitor(modelPtr, idx, placement, Y, jointName, bodyName, visual), variant);
      }

      static int nFixBody( ModelHandler & m )                                     { return m->nFixBody; }
      static std::vector<SE3>          & fix_lmpMi           ( ModelHandler & m ) { return m->fix_lmpMi; }
      static std::vector<Model::Index> & fix_lastMovingParent( ModelHandler & m ) { return m->fix_lastMovingParent; }
      static std::vector<bool> & fix_hasVisual ( ModelHandler & m ) { return m->fix_hasVisual; }
      static std::vector<std::string> & fix_bodyNames ( ModelHandler & m ) { return m->fix_bodyNames; }

      static Motion gravity( ModelHandler & m ) { return m->gravity; }
      static void setGravity( ModelHandler & m,const Motion_fx & g ) { m->gravity = g; }

      static ModelHandler maker_empty()
      {
	return ModelHandler( new Model(),true );
      }
      static ModelHandler maker_humanoidSimple()
      {
	Model * model = new Model();
	buildModels::humanoidSimple(*model);
	return ModelHandler( model,true );
      }

      static std::string toString(const ModelHandler& m)
      {	  std::ostringstream s; s << *m; return s.str();       }

      ///
      /// \brief Provide equivalent to python list index function for
      ///        vectors.
      ///
      /// \param[in] x The input vector.
      /// \param[in] v The value of to look for in the vector.
      ///
      /// \return The index of the matching element of the vector. If
      ///         no element is found, return -1.
      ///
      template<typename T>
      static Model::Index index(std::vector<T> const& x,
                                typename std::vector<T>::value_type const& v)
      {
        Model::Index i = 0;
        for(typename std::vector<T>::const_iterator it = x.begin(); it != x.end(); ++it, ++i)
        {
          if(*it == v)
          {
            return i;
          }
        }
        return -1;
      }

      /* --- Expose --------------------------------------------------------- */
      static void expose()
      {
        bp::class_< std::vector<Index> >("StdVec_Index")
          .def(bp::vector_indexing_suite< std::vector<Index> >());
        bp::class_< std::vector<std::string> >("StdVec_StdString")
          .def(bp::vector_indexing_suite< std::vector<std::string> >())
          .def("index", &ModelPythonVisitor::index<std::string>);
        bp::class_< std::vector<bool> >("StdVec_Bool")
          .def(bp::vector_indexing_suite< std::vector<bool> >());
        bp::class_< std::vector<double> >("StdVec_double")
          .def(bp::vector_indexing_suite< std::vector<double> >());
        bp::class_< JointModelVector >("StdVec_JointModelVector")
          .def(bp::vector_indexing_suite< JointModelVector, true >());

  bp::class_<ModelHandler>("Model",
         "Articulated rigid body model (const)",
         bp::no_init)
    .def(ModelPythonVisitor());

	/* Not sure if it is a good idea to enable automatic
	 * conversion. Prevent it for now */
	//bp::to_python_converter< Model,ModelPythonVisitor >();
	bp::to_python_converter< ModelHandler::SmartPtr_t,ModelPythonVisitor >();
      }

    };

  }} // namespace se3::python

#endif // ifndef __se3_python_model_hpp__

<|endoftext|>


<commit_before>#include "Mongo_Storage.h"
#include <common/fplog_exceptions.h>

#ifdef _WIN32
#include <WinSock2.h>
#include <windows.h>
#endif

#include <mongo/client/dbclient.h>
#include <utils.h>

namespace fpcollect {

class Mongo_Init
{
    public:

        Mongo_Init()
        {
            mongo::client::initialize();
        }
};

Mongo_Storage::~Mongo_Storage()
{
    disconnect();
    delete connection_;
}

void Mongo_Storage::connect(const Params& params)
{
    try
    {
        static Mongo_Init init;
        std::string ip, port, collection;

        for (auto item : params)
        {
            if(generic_util::find_str_no_case(item.first, "ip"))
                ip = item.second;

            if(generic_util::find_str_no_case(item.first, "port"))
                port = item.second;

            if(generic_util::find_str_no_case(item.first, "collection"))
                collection = item.second;
        }

        if (ip.empty())
            THROWM(fplog::exceptions::Connect_Failed, "IP not provided.");

        if (port.empty())
            port = "27017"; //default

        if (collection.empty())
            collection = "fplog.logs"; //default

        collection_ = collection;

        if (!connection_)
            connection_ = new mongo::DBClientConnection();

        connection_->connect(ip + ":" + port);
    }
    catch (mongo::DBException& e)
    {
        THROWM(fplog::exceptions::Connect_Failed, e.what());
    }
}

void Mongo_Storage::disconnect()
{
}

size_t Mongo_Storage::write(const void* buf, size_t buf_size, size_t timeout)
{
    if (!buf || (buf_size == 0))
        return 0;

    if (((const char*)buf)[buf_size - 1] != 0)
        THROWM(fplog::exceptions::Write_Failed, "Only null-terminated strings are supported by the storage.");

    try
    {
        mongo::BSONObj bson(mongo::fromjson((const char*)buf));
        connection_->insert(collection_, bson);
    }
    catch (mongo::DBException& e)
    {
        THROWM(fplog::exceptions::Write_Failed, e.what());
    }

    return buf_size;
}

};
<commit_msg>Fix for #81, need to test on the next Jenkins build.<commit_after>#include "Mongo_Storage.h"
#include <common/fplog_exceptions.h>

#ifdef _WIN32
#include <WinSock2.h>
#include <windows.h>
#endif

#include <mongo/client/dbclient.h>
#include <utils.h>

namespace fpcollect {

class Mongo_Init
{
    public:

        Mongo_Init()
        {
            mongo::client::initialize();
        }
};

Mongo_Storage::~Mongo_Storage()
{
    disconnect();
    delete connection_;
}

void Mongo_Storage::connect(const Params& params)
{
    try
    {
        static std::auto_ptr<Mongo_Init> init(new Mongo_Init());
        std::string ip, port, collection;

        for (auto item : params)
        {
            if(generic_util::find_str_no_case(item.first, "ip"))
                ip = item.second;

            if(generic_util::find_str_no_case(item.first, "port"))
                port = item.second;

            if(generic_util::find_str_no_case(item.first, "collection"))
                collection = item.second;
        }

        if (ip.empty())
            THROWM(fplog::exceptions::Connect_Failed, "IP not provided.");

        if (port.empty())
            port = "27017"; //default

        if (collection.empty())
            collection = "fplog.logs"; //default

        collection_ = collection;

        if (!connection_)
            connection_ = new mongo::DBClientConnection();

        connection_->connect(ip + ":" + port);
    }
    catch (mongo::DBException& e)
    {
        THROWM(fplog::exceptions::Connect_Failed, e.what());
    }
}

void Mongo_Storage::disconnect()
{
}

size_t Mongo_Storage::write(const void* buf, size_t buf_size, size_t timeout)
{
    if (!buf || (buf_size == 0))
        return 0;

    if (((const char*)buf)[buf_size - 1] != 0)
        THROWM(fplog::exceptions::Write_Failed, "Only null-terminated strings are supported by the storage.");

    try
    {
        mongo::BSONObj bson(mongo::fromjson((const char*)buf));
        connection_->insert(collection_, bson);
    }
    catch (mongo::DBException& e)
    {
        THROWM(fplog::exceptions::Write_Failed, e.what());
    }

    return buf_size;
}

};
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * TIGHTDB CONFIDENTIAL
 * __________________
 *
 *  [2011] - [2012] TightDB Inc
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of TightDB Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to TightDB Incorporated
 * and its suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from TightDB Incorporated.
 *
 **************************************************************************/
#ifndef __TIGHTDB_ENGINE_HPP
#define __TIGHTDB_ENGINE_HPP

#include <string>
#include "table.hpp"
#include "column_string.hpp"
#include "column_string_enum.hpp"

#include "utf8.hpp"
#include "query_conditions.hpp"

namespace tightdb {

class ParentNode {
public:
    ParentNode() : m_table(NULL) {}
    virtual ~ParentNode() {}
    virtual void Init(const Table& table) {m_table = &table; if (m_child) m_child->Init(table);}
    virtual size_t find_first(size_t start, size_t end) = 0;

    virtual std::string Verify(void)
    {
        if(error_code != "")
            return error_code;
        if(m_child == 0)
            return "";
        else
            return m_child->Verify();
    };

    ParentNode* m_child;

protected:
    const Table* m_table;
    std::string error_code;
};

/*
template <class T, class C, class F> class NODE: public ParentNode {
public:
    NODE(T v, size_t column) : m_value(v), m_column(column)  {m_child = 0;}
    ~NODE() {delete m_child; }

    size_t find_first(size_t start, size_t end, const Table& table)
    {
        const C& column = (C&)(table.GetColumnBase(m_column));
        const F function = {};
        for (size_t s = start; s < end; ++s) {
            const T t = column.Get(s);
            if (function(t, m_value)) {
                if (m_child == 0)
                    return s;
                else {
                    const size_t a = m_child->find_first(s, end, table);
                    if (s == a)
                        return s;
                    else
                        s = a - 1;
                }
            }
        }
        return end;
    }

protected:
    T m_value;
    size_t m_column;
};
*/

// Not finished
class SUBTABLE: public ParentNode {
public:
    SUBTABLE(size_t column): m_column(column) {m_child = 0; m_child2 = 0;}
    SUBTABLE() {};

    void Init(const Table& table)
    {
        m_table = &table;

        if (m_child) m_child->Init(table);
        if (m_child2) m_child2->Init(table);
    }

    size_t find_first(size_t start, size_t end)
    {
        assert(m_table);
        assert(m_child);

        for (size_t s = start; s < end; ++s) {
            const TableRef subtable = ((Table*)m_table)->get_subtable(m_column, s);

            m_child->Init(*subtable);
            const size_t subsize = subtable->size();
            const size_t sub = m_child->find_first(0, subsize);

            if(sub != subsize) {
                if (m_child2 == 0)
                    return s;
                else {
                    const size_t a = m_child2->find_first(s, end);
                    if (s == a)
                        return s;
                    else
                        s = a - 1;
                }
            }
        }
        return end;
    }
//protected:
    ParentNode* m_child2;
    size_t m_column;
};

template <class T, class C, class F> class NODE: public ParentNode {
public:
    NODE(T v, size_t column) : m_value(v), m_column_id(column) {m_child = 0;}
    ~NODE() {delete m_child; }

    void Init(const Table& table)
    {
        m_table = &table;
        m_column = (C*)&table.GetColumnBase(m_column_id);

        if (m_child) m_child->Init(table);
    }

    size_t find_first(size_t start, size_t end)
    {
        assert(m_table);

        for (size_t s = start; s < end; ++s) {
            s = m_column->template TreeFind<T, C, F>(m_value, s, end);
            if (s == (size_t)-1)
                s = end;

            if (m_child == 0)
                return s;
            else {
                const size_t a = m_child->find_first(s, end);
                if (s == a)
                    return s;
                else
                    s = a - 1;
            }
        }
        return end;
    }

protected:
    C* m_column;
    T m_value;
    size_t m_column_id;
};

template <class F> class STRINGNODE: public ParentNode {
public:
    STRINGNODE(const char* v, size_t column): m_column_id(column)
    {
        m_child = 0;

        m_value = (char *)malloc(strlen(v)*6);
        memcpy(m_value, v, strlen(v) + 1);
        m_ucase = (char *)malloc(strlen(v)*6);
        m_lcase = (char *)malloc(strlen(v)*6);

        const bool b1 = utf8case(v, m_lcase, false);
        const bool b2 = utf8case(v, m_ucase, true);
        if (!b1 || !b2)
            error_code = "Malformed UTF-8: " + std::string(m_value);
    }
    ~STRINGNODE() {delete m_child; free((void*)m_value); free((void*)m_ucase); free((void*)m_lcase); }

    void Init(const Table& table)
    {
        m_table = &table;
        m_column = &table.GetColumnBase(m_column_id);
        m_column_type = table.GetRealColumnType(m_column_id);

        if (m_child) m_child->Init(table);
    }

    size_t find_first(size_t start, size_t end)
    {
        F function;// = {};

        for (size_t s = start; s < end; ++s) {
            const char* t;

            // todo, can be optimized by placing outside loop
            if (m_column_type == COLUMN_TYPE_STRING)
                t = ((const AdaptiveStringColumn*)m_column)->Get(s);
            else {
                //TODO: First check if string is in key list
                t = ((const ColumnStringEnum*)m_column)->Get(s);
            }

            if (function(m_value, m_ucase, m_lcase, t)) {
                if (m_child == 0)
                    return s;
                else {
                    const size_t a = m_child->find_first(s, end);
                    if (s == a)
                        return s;
                    else
                        s = a - 1;
                }
            }
        }
        return end;
    }

protected:
    char* m_value;
    char* m_lcase;
    char* m_ucase;
    size_t m_column_id;
    const ColumnBase* m_column;
    ColumnType m_column_type;
};

template <> class STRINGNODE<EQUAL>: public ParentNode {
public:
    STRINGNODE(const char* v, size_t column): m_column_id(column), m_key_ndx((size_t)-1) {
        m_child = 0;
        m_value = (char *)malloc(strlen(v)*6);
        memcpy(m_value, v, strlen(v) + 1);
    }
    ~STRINGNODE() {delete m_child; free((void*)m_value); }

    void Init(const Table& table)
    {
        m_table = &table;
        m_column = &table.GetColumnBase(m_column_id);
        m_column_type = table.GetRealColumnType(m_column_id);

        if (m_column_type == COLUMN_TYPE_STRING_ENUM) {
            m_key_ndx =  ((const ColumnStringEnum*)m_column)->GetKeyNdx(m_value);
        }

        if (m_child) m_child->Init(table);
    }

    size_t find_first(size_t start, size_t end)
    {
        assert(m_table);

        for (size_t s = start; s < end; ++s) {
            // todo, can be optimized by placing outside loop
            if (m_column_type == COLUMN_TYPE_STRING)
                s = ((const AdaptiveStringColumn*)m_column)->find_first(m_value, s, end);
            else {
                if (m_key_ndx == size_t(-1)) s = end; // not in key set
                else {
                    const ColumnStringEnum* const cse = (const ColumnStringEnum*)m_column;
                    s = cse->find_first(m_key_ndx, s, end);
                }
            }

            if (s == (size_t)-1)
                s = end;

            if (m_child == 0)
                return s;
            else {
                const size_t a = m_child->find_first(s, end);
                if (s == a)
                    return s;
                else
                    s = a - 1;
            }
        }
        return end;
    }

protected:
    char*  m_value;
    size_t m_column_id;

private:
    const ColumnBase* m_column;
    ColumnType m_column_type;
    size_t m_key_ndx;
};

class OR_NODE: public ParentNode {
public:
    OR_NODE(ParentNode* p1) {m_child = 0; m_cond1 = p1; m_cond2 = 0;};
    ~OR_NODE()
    {
        delete m_cond1;
        delete m_cond2;
        delete m_child;
    }

    void Init(const Table& table)
    {
        m_cond1->Init(table);
        m_cond2->Init(table);
    }

    size_t find_first(size_t start, size_t end)
    {
        for (size_t s = start; s < end; ++s) {
            // Todo, redundant searches can occur
            const size_t f1 = m_cond1->find_first(s, end);
            const size_t f2 = m_cond2->find_first(s, f1);
            s = f1 < f2 ? f1 : f2;

            if (m_child == 0)
                return s;
            else {
                const size_t a = m_cond2->find_first(s, end);
                if (s == a)
                    return s;
                else
                    s = a - 1;
            }
        }
        return end;
    }

    virtual std::string Verify(void)
    {
        if(error_code != "")
            return error_code;
        if(m_cond1 == 0)
            return "Missing left-hand side of OR";
        if(m_cond2 == 0)
            return "Missing right-hand side of OR";
        std::string s;
        if(m_child != 0)
            s = m_child->Verify();
        if(s != "")
            return s;
        s = m_cond1->Verify();
        if(s != "")
            return s;
        s = m_cond2->Verify();
        if(s != "")
            return s;
        return "";
    }

    ParentNode* m_cond1;
    ParentNode* m_cond2;
};

}

#endif __TIGHTDB_ENGINE_HPP<commit_msg>Added closing comment<commit_after>/*************************************************************************
 *
 * TIGHTDB CONFIDENTIAL
 * __________________
 *
 *  [2011] - [2012] TightDB Inc
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of TightDB Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to TightDB Incorporated
 * and its suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from TightDB Incorporated.
 *
 **************************************************************************/
#ifndef __TIGHTDB_ENGINE_HPP
#define __TIGHTDB_ENGINE_HPP

#include <string>
#include "table.hpp"
#include "column_string.hpp"
#include "column_string_enum.hpp"

#include "utf8.hpp"
#include "query_conditions.hpp"

namespace tightdb {

class ParentNode {
public:
    ParentNode() : m_table(NULL) {}
    virtual ~ParentNode() {}
    virtual void Init(const Table& table) {m_table = &table; if (m_child) m_child->Init(table);}
    virtual size_t find_first(size_t start, size_t end) = 0;

    virtual std::string Verify(void)
    {
        if(error_code != "")
            return error_code;
        if(m_child == 0)
            return "";
        else
            return m_child->Verify();
    };

    ParentNode* m_child;

protected:
    const Table* m_table;
    std::string error_code;
};

/*
template <class T, class C, class F> class NODE: public ParentNode {
public:
    NODE(T v, size_t column) : m_value(v), m_column(column)  {m_child = 0;}
    ~NODE() {delete m_child; }

    size_t find_first(size_t start, size_t end, const Table& table)
    {
        const C& column = (C&)(table.GetColumnBase(m_column));
        const F function = {};
        for (size_t s = start; s < end; ++s) {
            const T t = column.Get(s);
            if (function(t, m_value)) {
                if (m_child == 0)
                    return s;
                else {
                    const size_t a = m_child->find_first(s, end, table);
                    if (s == a)
                        return s;
                    else
                        s = a - 1;
                }
            }
        }
        return end;
    }

protected:
    T m_value;
    size_t m_column;
};
*/

// Not finished
class SUBTABLE: public ParentNode {
public:
    SUBTABLE(size_t column): m_column(column) {m_child = 0; m_child2 = 0;}
    SUBTABLE() {};

    void Init(const Table& table)
    {
        m_table = &table;

        if (m_child) m_child->Init(table);
        if (m_child2) m_child2->Init(table);
    }

    size_t find_first(size_t start, size_t end)
    {
        assert(m_table);
        assert(m_child);

        for (size_t s = start; s < end; ++s) {
            const TableRef subtable = ((Table*)m_table)->get_subtable(m_column, s);

            m_child->Init(*subtable);
            const size_t subsize = subtable->size();
            const size_t sub = m_child->find_first(0, subsize);

            if(sub != subsize) {
                if (m_child2 == 0)
                    return s;
                else {
                    const size_t a = m_child2->find_first(s, end);
                    if (s == a)
                        return s;
                    else
                        s = a - 1;
                }
            }
        }
        return end;
    }
//protected:
    ParentNode* m_child2;
    size_t m_column;
};

template <class T, class C, class F> class NODE: public ParentNode {
public:
    NODE(T v, size_t column) : m_value(v), m_column_id(column) {m_child = 0;}
    ~NODE() {delete m_child; }

    void Init(const Table& table)
    {
        m_table = &table;
        m_column = (C*)&table.GetColumnBase(m_column_id);

        if (m_child) m_child->Init(table);
    }

    size_t find_first(size_t start, size_t end)
    {
        assert(m_table);

        for (size_t s = start; s < end; ++s) {
            s = m_column->template TreeFind<T, C, F>(m_value, s, end);
            if (s == (size_t)-1)
                s = end;

            if (m_child == 0)
                return s;
            else {
                const size_t a = m_child->find_first(s, end);
                if (s == a)
                    return s;
                else
                    s = a - 1;
            }
        }
        return end;
    }

protected:
    C* m_column;
    T m_value;
    size_t m_column_id;
};

template <class F> class STRINGNODE: public ParentNode {
public:
    STRINGNODE(const char* v, size_t column): m_column_id(column)
    {
        m_child = 0;

        m_value = (char *)malloc(strlen(v)*6);
        memcpy(m_value, v, strlen(v) + 1);
        m_ucase = (char *)malloc(strlen(v)*6);
        m_lcase = (char *)malloc(strlen(v)*6);

        const bool b1 = utf8case(v, m_lcase, false);
        const bool b2 = utf8case(v, m_ucase, true);
        if (!b1 || !b2)
            error_code = "Malformed UTF-8: " + std::string(m_value);
    }
    ~STRINGNODE() {delete m_child; free((void*)m_value); free((void*)m_ucase); free((void*)m_lcase); }

    void Init(const Table& table)
    {
        m_table = &table;
        m_column = &table.GetColumnBase(m_column_id);
        m_column_type = table.GetRealColumnType(m_column_id);

        if (m_child) m_child->Init(table);
    }

    size_t find_first(size_t start, size_t end)
    {
        F function;// = {};

        for (size_t s = start; s < end; ++s) {
            const char* t;

            // todo, can be optimized by placing outside loop
            if (m_column_type == COLUMN_TYPE_STRING)
                t = ((const AdaptiveStringColumn*)m_column)->Get(s);
            else {
                //TODO: First check if string is in key list
                t = ((const ColumnStringEnum*)m_column)->Get(s);
            }

            if (function(m_value, m_ucase, m_lcase, t)) {
                if (m_child == 0)
                    return s;
                else {
                    const size_t a = m_child->find_first(s, end);
                    if (s == a)
                        return s;
                    else
                        s = a - 1;
                }
            }
        }
        return end;
    }

protected:
    char* m_value;
    char* m_lcase;
    char* m_ucase;
    size_t m_column_id;
    const ColumnBase* m_column;
    ColumnType m_column_type;
};

template <> class STRINGNODE<EQUAL>: public ParentNode {
public:
    STRINGNODE(const char* v, size_t column): m_column_id(column), m_key_ndx((size_t)-1) {
        m_child = 0;
        m_value = (char *)malloc(strlen(v)*6);
        memcpy(m_value, v, strlen(v) + 1);
    }
    ~STRINGNODE() {delete m_child; free((void*)m_value); }

    void Init(const Table& table)
    {
        m_table = &table;
        m_column = &table.GetColumnBase(m_column_id);
        m_column_type = table.GetRealColumnType(m_column_id);

        if (m_column_type == COLUMN_TYPE_STRING_ENUM) {
            m_key_ndx =  ((const ColumnStringEnum*)m_column)->GetKeyNdx(m_value);
        }

        if (m_child) m_child->Init(table);
    }

    size_t find_first(size_t start, size_t end)
    {
        assert(m_table);

        for (size_t s = start; s < end; ++s) {
            // todo, can be optimized by placing outside loop
            if (m_column_type == COLUMN_TYPE_STRING)
                s = ((const AdaptiveStringColumn*)m_column)->find_first(m_value, s, end);
            else {
                if (m_key_ndx == size_t(-1)) s = end; // not in key set
                else {
                    const ColumnStringEnum* const cse = (const ColumnStringEnum*)m_column;
                    s = cse->find_first(m_key_ndx, s, end);
                }
            }

            if (s == (size_t)-1)
                s = end;

            if (m_child == 0)
                return s;
            else {
                const size_t a = m_child->find_first(s, end);
                if (s == a)
                    return s;
                else
                    s = a - 1;
            }
        }
        return end;
    }

protected:
    char*  m_value;
    size_t m_column_id;

private:
    const ColumnBase* m_column;
    ColumnType m_column_type;
    size_t m_key_ndx;
};

class OR_NODE: public ParentNode {
public:
    OR_NODE(ParentNode* p1) {m_child = 0; m_cond1 = p1; m_cond2 = 0;};
    ~OR_NODE()
    {
        delete m_cond1;
        delete m_cond2;
        delete m_child;
    }

    void Init(const Table& table)
    {
        m_cond1->Init(table);
        m_cond2->Init(table);
    }

    size_t find_first(size_t start, size_t end)
    {
        for (size_t s = start; s < end; ++s) {
            // Todo, redundant searches can occur
            const size_t f1 = m_cond1->find_first(s, end);
            const size_t f2 = m_cond2->find_first(s, f1);
            s = f1 < f2 ? f1 : f2;

            if (m_child == 0)
                return s;
            else {
                const size_t a = m_cond2->find_first(s, end);
                if (s == a)
                    return s;
                else
                    s = a - 1;
            }
        }
        return end;
    }

    virtual std::string Verify(void)
    {
        if(error_code != "")
            return error_code;
        if(m_cond1 == 0)
            return "Missing left-hand side of OR";
        if(m_cond2 == 0)
            return "Missing right-hand side of OR";
        std::string s;
        if(m_child != 0)
            s = m_child->Verify();
        if(s != "")
            return s;
        s = m_cond1->Verify();
        if(s != "")
            return s;
        s = m_cond2->Verify();
        if(s != "")
            return s;
        return "";
    }

    ParentNode* m_cond1;
    ParentNode* m_cond2;
};

}

#endif //__TIGHTDB_ENGINE_HPP<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: chart2uno.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $  $Date: 2004-02-11 09:55:41 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_CHART2UNO_HXX
#define SC_CHART2UNO_HXX

#ifndef SC_RANGELST_HXX
#include "rangelst.hxx"
#endif
#ifndef _SFXLSTNER_HXX
#include <svtools/lstner.hxx>
#endif
#ifndef _COM_SUN_STAR_CHART2_XDATAPROVIDER_HPP_
#include <com/sun/star/chart2/XDataProvider.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XDATASOURCE_HPP_
#include <com/sun/star/chart2/XDataSource.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XDATASEQUENCE_HPP_
#include <com/sun/star/chart2/XDataSequence.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_DATASEQUENCEROLE_HPP_
#include <com/sun/star/chart2/DataSequenceRole.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE2_HXX_
#include <cppuhelper/implbase2.hxx>
#endif
#ifndef _CPPUHELPER_IMPLBASE3_HXX_
#include <cppuhelper/implbase3.hxx>
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

class ScDocShell;

// DataProvider ==============================================================

class ScChart2DataProvider : public
                ::cppu::WeakImplHelper2<
                    ::com::sun::star::chart2::XDataProvider,
                    ::com::sun::star::lang::XServiceInfo>,
                SfxListener
{
public:

    explicit ScChart2DataProvider( ScDocShell* pDocSh);
    virtual ~ScChart2DataProvider();
    virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );

    // XDataProvider ---------------------------------------------------------

    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XDataSource> SAL_CALL
        getDataByRangeRepresentation(
                const ::rtl::OUString& rRangeRepresentation)
        throw( ::com::sun::star::lang::IllegalArgumentException,
                ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XDataSequence> SAL_CALL
        getDataSequenceByRangeIdentifier(
                const ::rtl::OUString& rRangeIdentifier)
        throw( ::com::sun::star::lang::IllegalArgumentException,
                ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XDataSequence> SAL_CALL replaceRange(
                const ::com::sun::star::uno::Reference<
                ::com::sun::star::chart2::XDataSequence>& rSeq)
        throw( ::com::sun::star::lang::IllegalArgumentException,
                ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL addDataChangeListener(
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDataChangeListener>& rListener,
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDataSource>& rData)
        throw( ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL removeDataChangeListener(
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDataChangeListener>& rListener,
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDataSource>& rData)
        throw( ::com::sun::star::lang::IllegalArgumentException,
                ::com::sun::star::uno::RuntimeException);

    // XServiceInfo ----------------------------------------------------------

    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(
            ::com::sun::star::uno::RuntimeException);

    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString&
            rServiceName) throw( ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
        getSupportedServiceNames() throw(
                ::com::sun::star::uno::RuntimeException);

private:

    ScDocShell*                 pDocShell;

};

// DataSource ================================================================

class ScChart2DataSource : public
                ::cppu::WeakImplHelper2<
                    ::com::sun::star::chart2::XDataSource,
                    ::com::sun::star::lang::XServiceInfo>,
                SfxListener
{
public:

    explicit ScChart2DataSource( ScDocShell* pDocSh, const ScRangeListRef&
            rRangeList);
    virtual ~ScChart2DataSource();
    virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );

    // XDataSource -----------------------------------------------------------

    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XDataSequence> > SAL_CALL
        getDataSequences() throw( ::com::sun::star::uno::RuntimeException);

    // XServiceInfo ----------------------------------------------------------

    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(
            ::com::sun::star::uno::RuntimeException);

    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString&
            rServiceName) throw( ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
        getSupportedServiceNames() throw(
                ::com::sun::star::uno::RuntimeException);

private:

    ScRangeListRef              xRanges;
    ScDocShell*                 pDocShell;

};

// DataSequence ==============================================================

class ScChart2DataSequence : public
                ::cppu::WeakImplHelper3<
                    ::com::sun::star::chart2::XDataSequence,
                    ::com::sun::star::beans::XPropertySet,
                    ::com::sun::star::lang::XServiceInfo>,
                SfxListener
{
public:

    explicit ScChart2DataSequence( ScDocShell* pDocSh,
            const ScRangeListRef& rRangeList );
    virtual ~ScChart2DataSequence();
    virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );

    // XDataSequence ---------------------------------------------------------

    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>
        SAL_CALL getData() throw( ::com::sun::star::uno::RuntimeException);

    virtual ::rtl::OUString SAL_CALL getSourceIdentifier() throw (
            ::com::sun::star::uno::RuntimeException);

    // XPropertySet ----------------------------------------------------------

    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySetInfo> SAL_CALL
        getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL setPropertyValue(
            const ::rtl::OUString& rPropertyName,
            const ::com::sun::star::uno::Any& rValue)
        throw( ::com::sun::star::beans::UnknownPropertyException,
                ::com::sun::star::beans::PropertyVetoException,
                ::com::sun::star::lang::IllegalArgumentException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue(
            const ::rtl::OUString& rPropertyName)
        throw( ::com::sun::star::beans::UnknownPropertyException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL addPropertyChangeListener(
            const ::rtl::OUString& rPropertyName,
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertyChangeListener>& xListener)
        throw( ::com::sun::star::beans::UnknownPropertyException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL removePropertyChangeListener(
            const ::rtl::OUString& rPropertyName,
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertyChangeListener>& rListener)
        throw( ::com::sun::star::beans::UnknownPropertyException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL addVetoableChangeListener(
            const ::rtl::OUString& rPropertyName,
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XVetoableChangeListener>& rListener)
        throw( ::com::sun::star::beans::UnknownPropertyException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL removeVetoableChangeListener(
            const ::rtl::OUString& rPropertyName,
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XVetoableChangeListener>& rListener)
        throw( ::com::sun::star::beans::UnknownPropertyException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException);

    // XServiceInfo ----------------------------------------------------------

    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(
            ::com::sun::star::uno::RuntimeException);

    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString&
            rServiceName) throw( ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
        getSupportedServiceNames() throw(
                ::com::sun::star::uno::RuntimeException);

private:

    // properties
    ::com::sun::star::chart2::DataSequenceRole  aRole;
    sal_Bool                    bHidden;
    // internals
    ScRangeListRef              xRanges;
    ::rtl::OUString             aIdentifier;
    ScDocShell*                 pDocShell;

};

#endif // SC_CHART2UNO_HXX
<commit_msg>INTEGRATION: CWS ooo19126 (1.2.526); FILE MERGED 2005/09/05 15:00:34 rt 1.2.526.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: chart2uno.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 17:25:36 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_CHART2UNO_HXX
#define SC_CHART2UNO_HXX

#ifndef SC_RANGELST_HXX
#include "rangelst.hxx"
#endif
#ifndef _SFXLSTNER_HXX
#include <svtools/lstner.hxx>
#endif
#ifndef _COM_SUN_STAR_CHART2_XDATAPROVIDER_HPP_
#include <com/sun/star/chart2/XDataProvider.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XDATASOURCE_HPP_
#include <com/sun/star/chart2/XDataSource.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XDATASEQUENCE_HPP_
#include <com/sun/star/chart2/XDataSequence.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_DATASEQUENCEROLE_HPP_
#include <com/sun/star/chart2/DataSequenceRole.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE2_HXX_
#include <cppuhelper/implbase2.hxx>
#endif
#ifndef _CPPUHELPER_IMPLBASE3_HXX_
#include <cppuhelper/implbase3.hxx>
#endif
#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

class ScDocShell;

// DataProvider ==============================================================

class ScChart2DataProvider : public
                ::cppu::WeakImplHelper2<
                    ::com::sun::star::chart2::XDataProvider,
                    ::com::sun::star::lang::XServiceInfo>,
                SfxListener
{
public:

    explicit ScChart2DataProvider( ScDocShell* pDocSh);
    virtual ~ScChart2DataProvider();
    virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );

    // XDataProvider ---------------------------------------------------------

    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XDataSource> SAL_CALL
        getDataByRangeRepresentation(
                const ::rtl::OUString& rRangeRepresentation)
        throw( ::com::sun::star::lang::IllegalArgumentException,
                ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XDataSequence> SAL_CALL
        getDataSequenceByRangeIdentifier(
                const ::rtl::OUString& rRangeIdentifier)
        throw( ::com::sun::star::lang::IllegalArgumentException,
                ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XDataSequence> SAL_CALL replaceRange(
                const ::com::sun::star::uno::Reference<
                ::com::sun::star::chart2::XDataSequence>& rSeq)
        throw( ::com::sun::star::lang::IllegalArgumentException,
                ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL addDataChangeListener(
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDataChangeListener>& rListener,
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDataSource>& rData)
        throw( ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL removeDataChangeListener(
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDataChangeListener>& rListener,
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::chart2::XDataSource>& rData)
        throw( ::com::sun::star::lang::IllegalArgumentException,
                ::com::sun::star::uno::RuntimeException);

    // XServiceInfo ----------------------------------------------------------

    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(
            ::com::sun::star::uno::RuntimeException);

    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString&
            rServiceName) throw( ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
        getSupportedServiceNames() throw(
                ::com::sun::star::uno::RuntimeException);

private:

    ScDocShell*                 pDocShell;

};

// DataSource ================================================================

class ScChart2DataSource : public
                ::cppu::WeakImplHelper2<
                    ::com::sun::star::chart2::XDataSource,
                    ::com::sun::star::lang::XServiceInfo>,
                SfxListener
{
public:

    explicit ScChart2DataSource( ScDocShell* pDocSh, const ScRangeListRef&
            rRangeList);
    virtual ~ScChart2DataSource();
    virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );

    // XDataSource -----------------------------------------------------------

    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference<
        ::com::sun::star::chart2::XDataSequence> > SAL_CALL
        getDataSequences() throw( ::com::sun::star::uno::RuntimeException);

    // XServiceInfo ----------------------------------------------------------

    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(
            ::com::sun::star::uno::RuntimeException);

    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString&
            rServiceName) throw( ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
        getSupportedServiceNames() throw(
                ::com::sun::star::uno::RuntimeException);

private:

    ScRangeListRef              xRanges;
    ScDocShell*                 pDocShell;

};

// DataSequence ==============================================================

class ScChart2DataSequence : public
                ::cppu::WeakImplHelper3<
                    ::com::sun::star::chart2::XDataSequence,
                    ::com::sun::star::beans::XPropertySet,
                    ::com::sun::star::lang::XServiceInfo>,
                SfxListener
{
public:

    explicit ScChart2DataSequence( ScDocShell* pDocSh,
            const ScRangeListRef& rRangeList );
    virtual ~ScChart2DataSequence();
    virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );

    // XDataSequence ---------------------------------------------------------

    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any>
        SAL_CALL getData() throw( ::com::sun::star::uno::RuntimeException);

    virtual ::rtl::OUString SAL_CALL getSourceIdentifier() throw (
            ::com::sun::star::uno::RuntimeException);

    // XPropertySet ----------------------------------------------------------

    virtual ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySetInfo> SAL_CALL
        getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL setPropertyValue(
            const ::rtl::OUString& rPropertyName,
            const ::com::sun::star::uno::Any& rValue)
        throw( ::com::sun::star::beans::UnknownPropertyException,
                ::com::sun::star::beans::PropertyVetoException,
                ::com::sun::star::lang::IllegalArgumentException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue(
            const ::rtl::OUString& rPropertyName)
        throw( ::com::sun::star::beans::UnknownPropertyException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL addPropertyChangeListener(
            const ::rtl::OUString& rPropertyName,
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertyChangeListener>& xListener)
        throw( ::com::sun::star::beans::UnknownPropertyException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL removePropertyChangeListener(
            const ::rtl::OUString& rPropertyName,
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XPropertyChangeListener>& rListener)
        throw( ::com::sun::star::beans::UnknownPropertyException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL addVetoableChangeListener(
            const ::rtl::OUString& rPropertyName,
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XVetoableChangeListener>& rListener)
        throw( ::com::sun::star::beans::UnknownPropertyException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL removeVetoableChangeListener(
            const ::rtl::OUString& rPropertyName,
            const ::com::sun::star::uno::Reference<
            ::com::sun::star::beans::XVetoableChangeListener>& rListener)
        throw( ::com::sun::star::beans::UnknownPropertyException,
                ::com::sun::star::lang::WrappedTargetException,
                ::com::sun::star::uno::RuntimeException);

    // XServiceInfo ----------------------------------------------------------

    virtual ::rtl::OUString SAL_CALL getImplementationName() throw(
            ::com::sun::star::uno::RuntimeException);

    virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString&
            rServiceName) throw( ::com::sun::star::uno::RuntimeException);

    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
        getSupportedServiceNames() throw(
                ::com::sun::star::uno::RuntimeException);

private:

    // properties
    ::com::sun::star::chart2::DataSequenceRole  aRole;
    sal_Bool                    bHidden;
    // internals
    ScRangeListRef              xRanges;
    ::rtl::OUString             aIdentifier;
    ScDocShell*                 pDocShell;

};

#endif // SC_CHART2UNO_HXX
<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
// Author:		Martin Klemsa
//----------------------------------------------------------------------------
#ifndef _ctoolhu_thread_proxy_included_
#define _ctoolhu_thread_proxy_included_

namespace Ctoolhu::Thread {

	//Provides object-level locking for any lockable class.
	//If used in conjunction with inheriting from Lockable the client class internals needn't be touched
	//(indeed this is the same implementation as appears in Modern C++ design by Alexandrescu)
	template <class T>
	class LockingProxy {

	  public:

		explicit LockingProxy(T *client) : _client(client)
		{
			_client->Lock();
		}

		LockingProxy(LockingProxy &&src)
		{
			_client = src._client;
			src._client = nullptr;
		}

		~LockingProxy()
		{
			if (_client)
				_client->Unlock();
		}

		T *operator ->() const
		{
			return _client;
		}

		LockingProxy(const LockingProxy &) = delete;
		LockingProxy &operator =(const LockingProxy &) = delete;

	  private:

		T *_client;
	};

} //ns Ctoolhu::Thread

#endif //file guard
<commit_msg>Added move constructor to locking proxy class<commit_after>//----------------------------------------------------------------------------
// Author:		Martin Klemsa
//----------------------------------------------------------------------------
#ifndef _ctoolhu_thread_proxy_included_
#define _ctoolhu_thread_proxy_included_

#include <utility>

namespace Ctoolhu::Thread {

	//Provides object-level locking for any lockable class.
	//If used in conjunction with inheriting from Lockable the client class internals needn't be touched
	//(indeed this is the same implementation as appears in Modern C++ design by Alexandrescu)
	template <class T>
	class LockingProxy {

	  public:

		explicit LockingProxy(T *client) : _client(client)
		{
			_client->Lock();
		}

		LockingProxy(LockingProxy &&src)
		{
			_client = std::exchange(src._client, nullptr);
		}

		LockingProxy &operator =(LockingProxy &&src)
		{
			_client = std::exchange(src._client, nullptr);
			return *this;
		}

		~LockingProxy()
		{
			if (_client)
				_client->Unlock();
		}

		T *operator ->() const
		{
			return _client;
		}

		LockingProxy(const LockingProxy &) = delete;
		LockingProxy &operator =(const LockingProxy &) = delete;

	  private:

		T *_client;
	};

} //ns Ctoolhu::Thread

#endif //file guard
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "EasyServer.h"
#include "PacketType.h"
#include "ClientSession.h"
#include "ClientManager.h"
#include "DatabaseJobContext.h"
#include "DatabaseJobManager.h"

ClientManager* GClientManager = nullptr ;

ClientSession* ClientManager::CreateClient(SOCKET sock)
{
	ClientSession* client = new ClientSession(sock) ;
	mClientList.insert(ClientList::value_type(sock, client)) ;

	return client ;
}

void ClientManager::BroadcastPacket(ClientSession* from, PacketHeader* pkt)
{
	///FYI: C++ STL iterator Ÿ
	for (ClientList::const_iterator it=mClientList.begin() ; it!=mClientList.end() ; ++it)
	{
		ClientSession* client = it->second ;

		if ( from == client )
			continue ;

		client->Send(pkt) ;
	}
}

void ClientManager::OnPeriodWork()
{
	///   ǵ ֱ  (1   )
	DWORD currTick = GetTickCount() ;
	if ( currTick - mLastGCTick >= 1000 )
	{
		CollectGarbageSessions() ;
		mLastGCTick = currTick ;
	}

	/// ӵ Ŭ̾Ʈ Ǻ ֱ  ϴ  (ֱ ˾Ƽ ϸ  -  1ʷ )
	if ( currTick - mLastClientWorkTick >= 1000 )
	{
		ClientPeriodWork() ;
		mLastClientWorkTick = currTick ;
	}

	/// ó Ϸ DB ۾  Client dispatch
	DispatchDatabaseJobResults() ;

}

void ClientManager::CollectGarbageSessions()
{
	std::vector<ClientSession*> disconnectedSessions ;

	///FYI: C++ 11 ٸ ̿ Ÿ
	std::for_each(mClientList.begin(), mClientList.end(),
		[&](ClientList::const_reference it)
		{
			ClientSession* client = it.second ;

			if ( false == client->IsConnected() && false == client->DoingOverlappedOperation() )
				disconnectedSessions.push_back(client) ;
		}
	) ;

	///FYI: C Ÿ
	for (size_t i=0 ; i<disconnectedSessions.size() ; ++i)
	{
		ClientSession* client = disconnectedSessions[i] ;
		mClientList.erase(client->mSocket) ;
		delete client ;
	}

}

void ClientManager::ClientPeriodWork()
{
	GPlayerManager->UpdatePlayers();

	/// FYI: C++ 11 Ÿ
	for (auto& it : mClientList)
	{
		ClientSession* client = it.second ;
		client->OnTick() ;
	}
}

void ClientManager::DispatchDatabaseJobResults()
{
	/// ׿ ִ DB ۾ ó   Ŭ󿡰 ѱ
	DatabaseJobContext* dbResult = nullptr ;
	while ( GDatabaseJobManager->PopDatabaseJobResult(dbResult) )
	{
		if ( false == dbResult->mSuccess )
		{
			printf("DB JOB FAIL \n") ;
		}
		else
		{
			if ( typeid(*dbResult) == typeid(CreatePlayerDataContext) )
			{
				CreatePlayerDone(dbResult) ;
			}
			else if ( typeid(*dbResult) == typeid(DeletePlayerDataContext) )
			{
				DeletePlayerDone(dbResult) ;
			}
			else
			{
				///  ش DBû ߴ Ŭ̾Ʈ
				auto& it = mClientList.find(dbResult->mSockKey) ;

				if ( it != mClientList.end() && it->second->IsConnected() )
				{
					/// dispatch here....
					it->second->DatabaseJobDone(dbResult) ;
				}
			}
		}

		/// Ϸ DB ۾ ؽƮ
		DatabaseJobContext* toBeDelete = dbResult ;
		delete toBeDelete ;
	}
}

void ClientManager::CreatePlayer(int pid, double x, double y, double z, const char* name, const char* comment)
{
	CreatePlayerDataContext* newPlayerJob = new CreatePlayerDataContext() ;
	newPlayerJob->mPlayerId = pid ;
	newPlayerJob->mPosX = x ;
	newPlayerJob->mPosY = y ;
	newPlayerJob->mPosZ = z ;
	strcpy_s(newPlayerJob->mPlayerName, name) ;
	strcpy_s(newPlayerJob->mComment, comment) ;

	GDatabaseJobManager->PushDatabaseJobRequest(newPlayerJob) ;

}

void ClientManager::DeletePlayer(int pid)
{
	DeletePlayerDataContext* delPlayerJob = new DeletePlayerDataContext(pid) ;
	GDatabaseJobManager->PushDatabaseJobRequest(delPlayerJob) ;
}

void ClientManager::CreatePlayerDone(DatabaseJobContext* dbJob)
{
	CreatePlayerDataContext* createJob = dynamic_cast<CreatePlayerDataContext*>(dbJob) ;

	printf("PLAYER[%d] CREATED: %s \n", createJob->mPlayerId, createJob->mPlayerName) ;
}

void ClientManager::DeletePlayerDone(DatabaseJobContext* dbJob)
{
	DeletePlayerDataContext* deleteJob = dynamic_cast<DeletePlayerDataContext*>(dbJob) ;

	printf("PLAYER [%d] DELETED\n", deleteJob->mPlayerId) ;

}<commit_msg>플레이어 시뮬레이션이 매순간 되도록<commit_after>#include "stdafx.h"
#include "EasyServer.h"
#include "PacketType.h"
#include "ClientSession.h"
#include "ClientManager.h"
#include "DatabaseJobContext.h"
#include "DatabaseJobManager.h"

ClientManager* GClientManager = nullptr ;

ClientSession* ClientManager::CreateClient(SOCKET sock)
{
	ClientSession* client = new ClientSession(sock) ;
	mClientList.insert(ClientList::value_type(sock, client)) ;

	return client ;
}

void ClientManager::BroadcastPacket(ClientSession* from, PacketHeader* pkt)
{
	///FYI: C++ STL iterator Ÿ
	for (ClientList::const_iterator it=mClientList.begin() ; it!=mClientList.end() ; ++it)
	{
		ClientSession* client = it->second ;

		if ( from == client )
			continue ;

		client->Send(pkt) ;
	}
}

void ClientManager::OnPeriodWork()
{
	///   ǵ ֱ  (1   )
	DWORD currTick = GetTickCount() ;
	if ( currTick - mLastGCTick >= 1000 )
	{
		CollectGarbageSessions() ;
		mLastGCTick = currTick ;
	}

	/// ӵ Ŭ̾Ʈ Ǻ ֱ  ϴ  (ֱ ˾Ƽ ϸ  -  0ʷ )
	if ( currTick - mLastClientWorkTick >= 0 )
	{
		ClientPeriodWork() ;
		mLastClientWorkTick = currTick ;
	}

	/// ó Ϸ DB ۾  Client dispatch
	DispatchDatabaseJobResults() ;

}

void ClientManager::CollectGarbageSessions()
{
	std::vector<ClientSession*> disconnectedSessions ;

	///FYI: C++ 11 ٸ ̿ Ÿ
	std::for_each(mClientList.begin(), mClientList.end(),
		[&](ClientList::const_reference it)
		{
			ClientSession* client = it.second ;

			if ( false == client->IsConnected() && false == client->DoingOverlappedOperation() )
				disconnectedSessions.push_back(client) ;
		}
	) ;

	///FYI: C Ÿ
	for (size_t i=0 ; i<disconnectedSessions.size() ; ++i)
	{
		ClientSession* client = disconnectedSessions[i] ;
		mClientList.erase(client->mSocket) ;
		delete client ;
	}

}

void ClientManager::ClientPeriodWork()
{
	GPlayerManager->UpdatePlayers();

	/// FYI: C++ 11 Ÿ
	for (auto& it : mClientList)
	{
		ClientSession* client = it.second ;
		client->OnTick() ;
	}
}

void ClientManager::DispatchDatabaseJobResults()
{
	/// ׿ ִ DB ۾ ó   Ŭ󿡰 ѱ
	DatabaseJobContext* dbResult = nullptr ;
	while ( GDatabaseJobManager->PopDatabaseJobResult(dbResult) )
	{
		if ( false == dbResult->mSuccess )
		{
			printf("DB JOB FAIL \n") ;
		}
		else
		{
			if ( typeid(*dbResult) == typeid(CreatePlayerDataContext) )
			{
				CreatePlayerDone(dbResult) ;
			}
			else if ( typeid(*dbResult) == typeid(DeletePlayerDataContext) )
			{
				DeletePlayerDone(dbResult) ;
			}
			else
			{
				///  ش DBû ߴ Ŭ̾Ʈ
				auto& it = mClientList.find(dbResult->mSockKey) ;

				if ( it != mClientList.end() && it->second->IsConnected() )
				{
					/// dispatch here....
					it->second->DatabaseJobDone(dbResult) ;
				}
			}
		}

		/// Ϸ DB ۾ ؽƮ
		DatabaseJobContext* toBeDelete = dbResult ;
		delete toBeDelete ;
	}
}

void ClientManager::CreatePlayer(int pid, double x, double y, double z, const char* name, const char* comment)
{
	CreatePlayerDataContext* newPlayerJob = new CreatePlayerDataContext() ;
	newPlayerJob->mPlayerId = pid ;
	newPlayerJob->mPosX = x ;
	newPlayerJob->mPosY = y ;
	newPlayerJob->mPosZ = z ;
	strcpy_s(newPlayerJob->mPlayerName, name) ;
	strcpy_s(newPlayerJob->mComment, comment) ;

	GDatabaseJobManager->PushDatabaseJobRequest(newPlayerJob) ;

}

void ClientManager::DeletePlayer(int pid)
{
	DeletePlayerDataContext* delPlayerJob = new DeletePlayerDataContext(pid) ;
	GDatabaseJobManager->PushDatabaseJobRequest(delPlayerJob) ;
}

void ClientManager::CreatePlayerDone(DatabaseJobContext* dbJob)
{
	CreatePlayerDataContext* createJob = dynamic_cast<CreatePlayerDataContext*>(dbJob) ;

	printf("PLAYER[%d] CREATED: %s \n", createJob->mPlayerId, createJob->mPlayerName) ;
}

void ClientManager::DeletePlayerDone(DatabaseJobContext* dbJob)
{
	DeletePlayerDataContext* deleteJob = dynamic_cast<DeletePlayerDataContext*>(dbJob) ;

	printf("PLAYER [%d] DELETED\n", deleteJob->mPlayerId) ;

}<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include <gflags/gflags.h>
#include <glib.h>

#include "update_engine/marshal.glibmarshal.h"
#include "update_engine/dbus_constants.h"
#include "update_engine/subprocess.h"
#include "update_engine/utils.h"

extern "C" {
#include "update_engine/update_engine.dbusclient.h"
}

using chromeos_update_engine::kUpdateEngineServiceName;
using chromeos_update_engine::kUpdateEngineServicePath;
using chromeos_update_engine::kUpdateEngineServiceInterface;
using chromeos_update_engine::utils::GetAndFreeGError;
using std::string;

DEFINE_string(app_version, "", "Force the current app version.");
DEFINE_bool(check_for_update, false, "Initiate check for updates.");
DEFINE_string(omaha_url, "", "The URL of the Omaha update server.");
DEFINE_bool(reboot, false, "Initiate a reboot if needed.");
DEFINE_bool(show_track, false, "Show the update track.");
DEFINE_bool(status, false, "Print the status to stdout.");
DEFINE_bool(reset_status, false, "Sets the status in update_engine to idle.");
DEFINE_string(track, "", "Permanently change the update track.");
DEFINE_bool(update, false, "Forces an update and waits for its completion. "
            "Exit status is 0 if the update succeeded, and 1 otherwise.");
DEFINE_bool(watch_for_updates, false,
            "Listen for status updates and print them to the screen.");

namespace {

bool GetProxy(DBusGProxy** out_proxy) {
  DBusGConnection* bus;
  DBusGProxy* proxy = NULL;
  GError* error = NULL;
  const int kTries = 4;
  const int kRetrySeconds = 10;

  bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
  if (bus == NULL) {
    LOG(ERROR) << "Failed to get bus: " << GetAndFreeGError(&error);
    exit(1);
  }
  for (int i = 0; !proxy && i < kTries; ++i) {
    if (i > 0) {
      LOG(INFO) << "Retrying to get dbus proxy. Try "
                << (i + 1) << "/" << kTries;
      g_usleep(kRetrySeconds * G_USEC_PER_SEC);
    }
    proxy = dbus_g_proxy_new_for_name_owner(bus,
                                            kUpdateEngineServiceName,
                                            kUpdateEngineServicePath,
                                            kUpdateEngineServiceInterface,
                                            &error);
    LOG_IF(WARNING, !proxy) << "Error getting dbus proxy for "
                            << kUpdateEngineServiceName << ": "
                            << GetAndFreeGError(&error);
  }
  if (proxy == NULL) {
    LOG(ERROR) << "Giving up -- unable to get dbus proxy for "
               << kUpdateEngineServiceName;
    exit(1);
  }
  *out_proxy = proxy;
  return true;
}

static void StatusUpdateSignalHandler(DBusGProxy* proxy,
                                      int64_t last_checked_time,
                                      double progress,
                                      gchar* current_operation,
                                      gchar* new_version,
                                      int64_t new_size,
                                      void* user_data) {
  LOG(INFO) << "Got status update:";
  LOG(INFO) << "  last_checked_time: " << last_checked_time;
  LOG(INFO) << "  progress: " << progress;
  LOG(INFO) << "  current_operation: " << current_operation;
  LOG(INFO) << "  new_version: " << new_version;
  LOG(INFO) << "  new_size: " << new_size;
}

bool ResetStatus() {
  DBusGProxy* proxy;
  GError* error = NULL;

  CHECK(GetProxy(&proxy));

  gboolean rc =
      org_chromium_UpdateEngineInterface_reset_status(proxy, &error);
  return rc;
}

// If |op| is non-NULL, sets it to the current operation string or an
// empty string if unable to obtain the current status.
bool GetStatus(string* op) {
  DBusGProxy* proxy;
  GError* error = NULL;

  CHECK(GetProxy(&proxy));

  gint64 last_checked_time = 0;
  gdouble progress = 0.0;
  char* current_op = NULL;
  char* new_version = NULL;
  gint64 new_size = 0;

  gboolean rc = org_chromium_UpdateEngineInterface_get_status(
      proxy,
      &last_checked_time,
      &progress,
      &current_op,
      &new_version,
      &new_size,
      &error);
  if (rc == FALSE) {
    LOG(INFO) << "Error getting status: " << GetAndFreeGError(&error);
  }
  printf("LAST_CHECKED_TIME=%" PRIi64 "\nPROGRESS=%f\nCURRENT_OP=%s\n"
         "NEW_VERSION=%s\nNEW_SIZE=%" PRIi64 "\n",
         last_checked_time,
         progress,
         current_op,
         new_version,
         new_size);
  if (op) {
    *op = current_op ? current_op : "";
  }
  return true;
}

// Should never return.
void WatchForUpdates() {
  DBusGProxy* proxy;

  CHECK(GetProxy(&proxy));

  // Register marshaller
  dbus_g_object_register_marshaller(
      update_engine_VOID__INT64_DOUBLE_STRING_STRING_INT64,
      G_TYPE_NONE,
      G_TYPE_INT64,
      G_TYPE_DOUBLE,
      G_TYPE_STRING,
      G_TYPE_STRING,
      G_TYPE_INT64,
      G_TYPE_INVALID);

  static const char kStatusUpdate[] = "StatusUpdate";
  dbus_g_proxy_add_signal(proxy,
                          kStatusUpdate,
                          G_TYPE_INT64,
                          G_TYPE_DOUBLE,
                          G_TYPE_STRING,
                          G_TYPE_STRING,
                          G_TYPE_INT64,
                          G_TYPE_INVALID);
  GMainLoop* loop = g_main_loop_new (NULL, TRUE);
  dbus_g_proxy_connect_signal(proxy,
                              kStatusUpdate,
                              G_CALLBACK(StatusUpdateSignalHandler),
                              NULL,
                              NULL);
  g_main_loop_run(loop);
  g_main_loop_unref(loop);
}

bool CheckForUpdates(const string& app_version, const string& omaha_url) {
  DBusGProxy* proxy;
  GError* error = NULL;

  CHECK(GetProxy(&proxy));

  gboolean rc =
      org_chromium_UpdateEngineInterface_attempt_update(proxy,
                                                        app_version.c_str(),
                                                        omaha_url.c_str(),
                                                        &error);
  CHECK_EQ(rc, TRUE) << "Error checking for update: "
                     << GetAndFreeGError(&error);
  return true;
}

bool RebootIfNeeded() {
  DBusGProxy* proxy;
  GError* error = NULL;

  CHECK(GetProxy(&proxy));

  gboolean rc =
      org_chromium_UpdateEngineInterface_reboot_if_needed(proxy, &error);
  // Reboot error code doesn't necessarily mean that a reboot
  // failed. For example, D-Bus may be shutdown before we receive the
  // result.
  LOG_IF(INFO, !rc) << "Reboot error message: " << GetAndFreeGError(&error);
  return true;
}

void SetTrack(const string& track) {
  DBusGProxy* proxy;
  GError* error = NULL;

  CHECK(GetProxy(&proxy));

  gboolean rc =
      org_chromium_UpdateEngineInterface_set_track(proxy,
                                                   track.c_str(),
                                                   &error);
  CHECK_EQ(rc, true) << "Error setting the track: "
                     << GetAndFreeGError(&error);
  LOG(INFO) << "Track permanently set to: " << track;
}

string GetTrack() {
  DBusGProxy* proxy;
  GError* error = NULL;

  CHECK(GetProxy(&proxy));

  char* track = NULL;
  gboolean rc =
      org_chromium_UpdateEngineInterface_get_track(proxy,
                                                   &track,
                                                   &error);
  CHECK_EQ(rc, true) << "Error getting the track: " << GetAndFreeGError(&error);
  string output = track;
  g_free(track);
  return output;
}

static gboolean CompleteUpdateSource(gpointer data) {
  string current_op;
  if (!GetStatus(&current_op) || current_op == "UPDATE_STATUS_IDLE") {
    LOG(ERROR) << "Update failed.";
    exit(1);
  }
  if (current_op == "UPDATE_STATUS_UPDATED_NEED_REBOOT") {
    LOG(INFO) << "Update succeeded -- reboot needed.";
    exit(0);
  }
  return TRUE;
}

// This is similar to watching for updates but rather than registering
// a signal watch, activelly poll the daemon just in case it stops
// sending notifications.
void CompleteUpdate() {
  GMainLoop* loop = g_main_loop_new (NULL, TRUE);
  g_timeout_add_seconds(5, CompleteUpdateSource, NULL);
  g_main_loop_run(loop);
  g_main_loop_unref(loop);
}

}  // namespace {}

int main(int argc, char** argv) {
  // Boilerplate init commands.
  g_type_init();
  g_thread_init(NULL);
  dbus_g_thread_init();
  chromeos_update_engine::Subprocess::Init();
  google::ParseCommandLineFlags(&argc, &argv, true);

  // Update the status if requested.
  if (FLAGS_reset_status) {
    LOG(INFO) << "Setting Update Engine status to idle ...";
    if (!ResetStatus()) {
      LOG(ERROR) << "ResetStatus failed.";
      return 1;
    }

    LOG(INFO) << "ResetStatus succeeded.";
    return 0;
  }

  if (FLAGS_status) {
    LOG(INFO) << "Querying Update Engine status...";
    if (!GetStatus(NULL)) {
      LOG(FATAL) << "GetStatus failed.";
      return 1;
    }
    return 0;
  }

  // First, update the track if requested.
  if (!FLAGS_track.empty()) {
    SetTrack(FLAGS_track);
  }

  // Show the track if requested.
  if (FLAGS_show_track) {
    LOG(INFO) << "Track: " << GetTrack();
  }

  // Initiate an update check, if necessary.
  if (FLAGS_check_for_update ||
      FLAGS_update ||
      !FLAGS_app_version.empty() ||
      !FLAGS_omaha_url.empty()) {
    LOG_IF(WARNING, FLAGS_reboot) << "-reboot flag ignored.";
    string app_version = FLAGS_app_version;
    if (FLAGS_update && app_version.empty()) {
      app_version = "ForcedUpdate";
      LOG(INFO) << "Forcing an update by setting app_version to ForcedUpdate.";
    }
    LOG(INFO) << "Initiating update check and install.";
    CHECK(CheckForUpdates(app_version, FLAGS_omaha_url))
        << "Update check/initiate update failed.";

    // Wait for an update to complete.
    if (FLAGS_update) {
      LOG(INFO) << "Waiting for update to complete.";
      CompleteUpdate();  // Should never return.
      return 1;
    }
    return 0;
  }

  // Start watching for updates.
  if (FLAGS_watch_for_updates) {
    LOG_IF(WARNING, FLAGS_reboot) << "-reboot flag ignored.";
    LOG(INFO) << "Watching for status updates.";
    WatchForUpdates();  // Should never return.
    return 1;
  }

  if (FLAGS_reboot) {
    LOG(INFO) << "Requesting a reboot...";
    CHECK(RebootIfNeeded());
    return 0;
  }

  LOG(INFO) << "Done.";
  return 0;
}
<commit_msg>AU: recommend cgpt undo on update_engine_client -reset_status<commit_after>// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include <gflags/gflags.h>
#include <glib.h>

#include "update_engine/marshal.glibmarshal.h"
#include "update_engine/dbus_constants.h"
#include "update_engine/subprocess.h"
#include "update_engine/utils.h"

extern "C" {
#include "update_engine/update_engine.dbusclient.h"
}

using chromeos_update_engine::kUpdateEngineServiceName;
using chromeos_update_engine::kUpdateEngineServicePath;
using chromeos_update_engine::kUpdateEngineServiceInterface;
using chromeos_update_engine::utils::GetAndFreeGError;
using std::string;

DEFINE_string(app_version, "", "Force the current app version.");
DEFINE_bool(check_for_update, false, "Initiate check for updates.");
DEFINE_string(omaha_url, "", "The URL of the Omaha update server.");
DEFINE_bool(reboot, false, "Initiate a reboot if needed.");
DEFINE_bool(show_track, false, "Show the update track.");
DEFINE_bool(status, false, "Print the status to stdout.");
DEFINE_bool(reset_status, false, "Sets the status in update_engine to idle.");
DEFINE_string(track, "", "Permanently change the update track.");
DEFINE_bool(update, false, "Forces an update and waits for its completion. "
            "Exit status is 0 if the update succeeded, and 1 otherwise.");
DEFINE_bool(watch_for_updates, false,
            "Listen for status updates and print them to the screen.");

namespace {

bool GetProxy(DBusGProxy** out_proxy) {
  DBusGConnection* bus;
  DBusGProxy* proxy = NULL;
  GError* error = NULL;
  const int kTries = 4;
  const int kRetrySeconds = 10;

  bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
  if (bus == NULL) {
    LOG(ERROR) << "Failed to get bus: " << GetAndFreeGError(&error);
    exit(1);
  }
  for (int i = 0; !proxy && i < kTries; ++i) {
    if (i > 0) {
      LOG(INFO) << "Retrying to get dbus proxy. Try "
                << (i + 1) << "/" << kTries;
      g_usleep(kRetrySeconds * G_USEC_PER_SEC);
    }
    proxy = dbus_g_proxy_new_for_name_owner(bus,
                                            kUpdateEngineServiceName,
                                            kUpdateEngineServicePath,
                                            kUpdateEngineServiceInterface,
                                            &error);
    LOG_IF(WARNING, !proxy) << "Error getting dbus proxy for "
                            << kUpdateEngineServiceName << ": "
                            << GetAndFreeGError(&error);
  }
  if (proxy == NULL) {
    LOG(ERROR) << "Giving up -- unable to get dbus proxy for "
               << kUpdateEngineServiceName;
    exit(1);
  }
  *out_proxy = proxy;
  return true;
}

static void StatusUpdateSignalHandler(DBusGProxy* proxy,
                                      int64_t last_checked_time,
                                      double progress,
                                      gchar* current_operation,
                                      gchar* new_version,
                                      int64_t new_size,
                                      void* user_data) {
  LOG(INFO) << "Got status update:";
  LOG(INFO) << "  last_checked_time: " << last_checked_time;
  LOG(INFO) << "  progress: " << progress;
  LOG(INFO) << "  current_operation: " << current_operation;
  LOG(INFO) << "  new_version: " << new_version;
  LOG(INFO) << "  new_size: " << new_size;
}

bool ResetStatus() {
  DBusGProxy* proxy;
  GError* error = NULL;

  CHECK(GetProxy(&proxy));

  gboolean rc =
      org_chromium_UpdateEngineInterface_reset_status(proxy, &error);
  return rc;
}

// If |op| is non-NULL, sets it to the current operation string or an
// empty string if unable to obtain the current status.
bool GetStatus(string* op) {
  DBusGProxy* proxy;
  GError* error = NULL;

  CHECK(GetProxy(&proxy));

  gint64 last_checked_time = 0;
  gdouble progress = 0.0;
  char* current_op = NULL;
  char* new_version = NULL;
  gint64 new_size = 0;

  gboolean rc = org_chromium_UpdateEngineInterface_get_status(
      proxy,
      &last_checked_time,
      &progress,
      &current_op,
      &new_version,
      &new_size,
      &error);
  if (rc == FALSE) {
    LOG(INFO) << "Error getting status: " << GetAndFreeGError(&error);
  }
  printf("LAST_CHECKED_TIME=%" PRIi64 "\nPROGRESS=%f\nCURRENT_OP=%s\n"
         "NEW_VERSION=%s\nNEW_SIZE=%" PRIi64 "\n",
         last_checked_time,
         progress,
         current_op,
         new_version,
         new_size);
  if (op) {
    *op = current_op ? current_op : "";
  }
  return true;
}

// Should never return.
void WatchForUpdates() {
  DBusGProxy* proxy;

  CHECK(GetProxy(&proxy));

  // Register marshaller
  dbus_g_object_register_marshaller(
      update_engine_VOID__INT64_DOUBLE_STRING_STRING_INT64,
      G_TYPE_NONE,
      G_TYPE_INT64,
      G_TYPE_DOUBLE,
      G_TYPE_STRING,
      G_TYPE_STRING,
      G_TYPE_INT64,
      G_TYPE_INVALID);

  static const char kStatusUpdate[] = "StatusUpdate";
  dbus_g_proxy_add_signal(proxy,
                          kStatusUpdate,
                          G_TYPE_INT64,
                          G_TYPE_DOUBLE,
                          G_TYPE_STRING,
                          G_TYPE_STRING,
                          G_TYPE_INT64,
                          G_TYPE_INVALID);
  GMainLoop* loop = g_main_loop_new (NULL, TRUE);
  dbus_g_proxy_connect_signal(proxy,
                              kStatusUpdate,
                              G_CALLBACK(StatusUpdateSignalHandler),
                              NULL,
                              NULL);
  g_main_loop_run(loop);
  g_main_loop_unref(loop);
}

bool CheckForUpdates(const string& app_version, const string& omaha_url) {
  DBusGProxy* proxy;
  GError* error = NULL;

  CHECK(GetProxy(&proxy));

  gboolean rc =
      org_chromium_UpdateEngineInterface_attempt_update(proxy,
                                                        app_version.c_str(),
                                                        omaha_url.c_str(),
                                                        &error);
  CHECK_EQ(rc, TRUE) << "Error checking for update: "
                     << GetAndFreeGError(&error);
  return true;
}

bool RebootIfNeeded() {
  DBusGProxy* proxy;
  GError* error = NULL;

  CHECK(GetProxy(&proxy));

  gboolean rc =
      org_chromium_UpdateEngineInterface_reboot_if_needed(proxy, &error);
  // Reboot error code doesn't necessarily mean that a reboot
  // failed. For example, D-Bus may be shutdown before we receive the
  // result.
  LOG_IF(INFO, !rc) << "Reboot error message: " << GetAndFreeGError(&error);
  return true;
}

void SetTrack(const string& track) {
  DBusGProxy* proxy;
  GError* error = NULL;

  CHECK(GetProxy(&proxy));

  gboolean rc =
      org_chromium_UpdateEngineInterface_set_track(proxy,
                                                   track.c_str(),
                                                   &error);
  CHECK_EQ(rc, true) << "Error setting the track: "
                     << GetAndFreeGError(&error);
  LOG(INFO) << "Track permanently set to: " << track;
}

string GetTrack() {
  DBusGProxy* proxy;
  GError* error = NULL;

  CHECK(GetProxy(&proxy));

  char* track = NULL;
  gboolean rc =
      org_chromium_UpdateEngineInterface_get_track(proxy,
                                                   &track,
                                                   &error);
  CHECK_EQ(rc, true) << "Error getting the track: " << GetAndFreeGError(&error);
  string output = track;
  g_free(track);
  return output;
}

static gboolean CompleteUpdateSource(gpointer data) {
  string current_op;
  if (!GetStatus(&current_op) || current_op == "UPDATE_STATUS_IDLE") {
    LOG(ERROR) << "Update failed.";
    exit(1);
  }
  if (current_op == "UPDATE_STATUS_UPDATED_NEED_REBOOT") {
    LOG(INFO) << "Update succeeded -- reboot needed.";
    exit(0);
  }
  return TRUE;
}

// This is similar to watching for updates but rather than registering
// a signal watch, activelly poll the daemon just in case it stops
// sending notifications.
void CompleteUpdate() {
  GMainLoop* loop = g_main_loop_new (NULL, TRUE);
  g_timeout_add_seconds(5, CompleteUpdateSource, NULL);
  g_main_loop_run(loop);
  g_main_loop_unref(loop);
}

}  // namespace {}

int main(int argc, char** argv) {
  // Boilerplate init commands.
  g_type_init();
  g_thread_init(NULL);
  dbus_g_thread_init();
  chromeos_update_engine::Subprocess::Init();
  google::ParseCommandLineFlags(&argc, &argv, true);

  // Update the status if requested.
  if (FLAGS_reset_status) {
    LOG(INFO) << "Setting Update Engine status to idle ...";
    if (!ResetStatus()) {
      LOG(ERROR) << "ResetStatus failed.";
      return 1;
    }

    LOG(INFO) << "ResetStatus succeeded; to undo partition table changes run:\n"
                 "(D=$(rootdev -d) P=$(rootdev -s); cgpt p -i$(($(echo ${P#$D} "
                 "| sed 's/^[^0-9]*//')-1)) $D;)";
    return 0;
  }

  if (FLAGS_status) {
    LOG(INFO) << "Querying Update Engine status...";
    if (!GetStatus(NULL)) {
      LOG(FATAL) << "GetStatus failed.";
      return 1;
    }
    return 0;
  }

  // First, update the track if requested.
  if (!FLAGS_track.empty()) {
    SetTrack(FLAGS_track);
  }

  // Show the track if requested.
  if (FLAGS_show_track) {
    LOG(INFO) << "Track: " << GetTrack();
  }

  // Initiate an update check, if necessary.
  if (FLAGS_check_for_update ||
      FLAGS_update ||
      !FLAGS_app_version.empty() ||
      !FLAGS_omaha_url.empty()) {
    LOG_IF(WARNING, FLAGS_reboot) << "-reboot flag ignored.";
    string app_version = FLAGS_app_version;
    if (FLAGS_update && app_version.empty()) {
      app_version = "ForcedUpdate";
      LOG(INFO) << "Forcing an update by setting app_version to ForcedUpdate.";
    }
    LOG(INFO) << "Initiating update check and install.";
    CHECK(CheckForUpdates(app_version, FLAGS_omaha_url))
        << "Update check/initiate update failed.";

    // Wait for an update to complete.
    if (FLAGS_update) {
      LOG(INFO) << "Waiting for update to complete.";
      CompleteUpdate();  // Should never return.
      return 1;
    }
    return 0;
  }

  // Start watching for updates.
  if (FLAGS_watch_for_updates) {
    LOG_IF(WARNING, FLAGS_reboot) << "-reboot flag ignored.";
    LOG(INFO) << "Watching for status updates.";
    WatchForUpdates();  // Should never return.
    return 1;
  }

  if (FLAGS_reboot) {
    LOG(INFO) << "Requesting a reboot...";
    CHECK(RebootIfNeeded());
    return 0;
  }

  LOG(INFO) << "Done.";
  return 0;
}
<|endoftext|>