From 273ce670f433c5d4aee6cd889d4fc8a0c3a0ef1d Mon Sep 17 00:00:00 2001 From: Florent Lamiraux <florent@laas.fr> Date: Mon, 20 Jun 2011 17:09:02 +0200 Subject: [PATCH] FactoryStorage and PoolStorage are now singletons. g_pool and g_factory global variables have been replaced by static methods getInstance in each class. getInstance returns a pointer to the unique instance of the class and creates it if needed. --- doc/additionalDoc/package.h | 9 +++--- include/dynamic-graph/entity.h | 2 +- include/dynamic-graph/factory.h | 45 ++++++++++++---------------- include/dynamic-graph/pool.h | 23 ++++++++------- src/dgraph/entity.cpp | 4 +-- src/dgraph/factory.cpp | 23 ++++++++++++--- src/dgraph/pool.cpp | 23 +++++++++++---- src/traces/tracer.cpp | 4 +-- tests/factory.cpp | 52 +++++++++++++++++++-------------- tests/pool.cpp | 12 +++++--- 10 files changed, 114 insertions(+), 83 deletions(-) diff --git a/doc/additionalDoc/package.h b/doc/additionalDoc/package.h index 1137875..3933783 100644 --- a/doc/additionalDoc/package.h +++ b/doc/additionalDoc/package.h @@ -112,11 +112,10 @@ Some basic shell functions, and support for procedures, are also included. For a complete list of those, load the plugin shell-functions.so and type 'help' at the command line. -The public static objects (singletons) made available by including the -corresponding headers in this module are: -\li g_factory: dynamicgraph::FactoryStorage -\li g_pool: dynamicgraph::PoolStorage -\li g_shell: dynamicgraph::Interpreter +The (singletons made available by including the corresponding headers in this +module are: +\li dynamicgraph::FactoryStorage +\li dynamicgraph::PoolStorage For an example of a program creating entities in C++, see the unit test test_pool.cpp (in your package source directory/unitTesting). diff --git a/include/dynamic-graph/entity.h b/include/dynamic-graph/entity.h index 601a25b..dde3226 100644 --- a/include/dynamic-graph/entity.h +++ b/include/dynamic-graph/entity.h @@ -64,7 +64,7 @@ namespace dynamicgraph /// /// These signals link the entities together to form a complete /// computation graph. To declare a new entity, please see the - /// DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN macro in g_factory.h. A + /// DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN macro in factory.h. A /// command-line interface provided by the entity can be used by a /// sot shell to call methods from entities and display the result /// of their execution. Classes that derive from Entity can diff --git a/include/dynamic-graph/factory.h b/include/dynamic-graph/factory.h index 44b40c2..c85b16a 100644 --- a/include/dynamic-graph/factory.h +++ b/include/dynamic-graph/factory.h @@ -91,8 +91,7 @@ namespace dynamicgraph /// appropriate and to check for uniqueness if required. /// /// - /// This class should <b>never</b> be used directly. Use the - /// g_factory global variable instead. The rationale is that each + /// This class is a singleton. The rationale is that each /// unique name must identify a unique Entity. The use of a single /// instance of this class enforces this behavior, instantiating one /// yourself would break this property. @@ -103,15 +102,14 @@ namespace dynamicgraph /// name. typedef Entity* (*EntityConstructor_ptr) (const std::string&); - /// \brief Constructor the factory. - /// - /// After the initialization, no entities will be available. - /// registerEntity has to be used to add new entities to the - /// object. - explicit FactoryStorage (); - ~FactoryStorage (); + /// \brief Get pointer to unique object of the class + static FactoryStorage* getInstance(); + + /// \brief Destroy the unique instance of the class + static void destroy(); + /// \brief Add a new entity to the factory. /// /// It is not allowed to have several entities using the same @@ -182,6 +180,14 @@ namespace dynamicgraph std::ostream& os); private: + + /// \brief Constructor the factory. + /// + /// After the initialization, no entities will be available. + /// registerEntity has to be used to add new entities to the + /// object. + explicit FactoryStorage (); + /// \brief Entity map type. /// /// This maps entity names to functions pointers which can be @@ -191,26 +197,11 @@ namespace dynamicgraph /// \brief The entity map storing information about how to /// instantiate an Entity. EntityMap entityMap; + + /// \pointer to the unique object of the class + static FactoryStorage* instance_; }; - /// \ingroup dgraph - /// - /// \brief Global factory. - /// - /// This global variable is the only valid instance of the - /// FactoryStorage class. - /// - /// This unique instance is to make sure that only only one entity - /// list is built. - /// - /// This global variable must be used to search for entities and - /// to instantiate them. - /// - /// Please use the DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN macro if - /// possible to register an entity to this factory. - DYNAMIC_GRAPH_DLLAPI extern FactoryStorage g_factory; - - /// \ingroup dgraph /// /// \brief This class automatically register an Entity to the diff --git a/include/dynamic-graph/pool.h b/include/dynamic-graph/pool.h index 885b171..49536e9 100644 --- a/include/dynamic-graph/pool.h +++ b/include/dynamic-graph/pool.h @@ -29,7 +29,7 @@ namespace dynamicgraph { /*! @ingroup dgraph - \brief This class keep tracks of all the objects in the stack of Tasks. + \brief Singleton that keeps track of all the entities. This class gives access to and remembers all the entities created during its life. @@ -42,11 +42,6 @@ namespace dynamicgraph \note From the code it is not very clear why we should not unregister from the tasks and the features... - The role of this class is also to look for the object supporting - a command, and to apply this command. - - It also returns signal. - */ class DYNAMIC_GRAPH_DLLAPI PoolStorage { @@ -57,6 +52,12 @@ namespace dynamicgraph /*! \brief Sorted set of entities with unique key (name). */ typedef std::map< std::string,Entity* > Entities; + /// \brief Get unique instance of the class. + static PoolStorage *getInstance(); + + /// \brief Destroy the unique instance of the class + static void destroy(); + /*! @} */ /*! \brief Default destructor */ @@ -108,7 +109,7 @@ namespace dynamicgraph If the method of the object displays some information this will be done on os. - The commands specific to the \b g_pool object are: + The commands specific to the \b PoolStorage singleton are: \li \b list : List all the entities registered in the pool */ void commandLine (const std::string& objectName, @@ -128,11 +129,11 @@ namespace dynamicgraph */ /*! \brief Set of basic objects of the SoT */ Entities entityMap; - }; - - - DYNAMIC_GRAPH_DLLAPI extern dynamicgraph::PoolStorage g_pool; + private: + PoolStorage () {} + static PoolStorage* instance_; + }; } // end of namespace dynamicgraph. #endif //! DYNAMIC_GRAPH_POOL_H diff --git a/src/dgraph/entity.cpp b/src/dgraph/entity.cpp index b71ba72..f99bf18 100644 --- a/src/dgraph/entity.cpp +++ b/src/dgraph/entity.cpp @@ -42,13 +42,13 @@ entityRegistration () { //sotPool.entity[name] = this; - g_pool.registerEntity(name,this); + PoolStorage::getInstance()->registerEntity(name,this); } void Entity:: entityDeregistration () { - g_pool.deregisterEntity(name); + PoolStorage::getInstance()->deregisterEntity(name); } Entity:: diff --git a/src/dgraph/factory.cpp b/src/dgraph/factory.cpp index 341c103..77e7e0b 100644 --- a/src/dgraph/factory.cpp +++ b/src/dgraph/factory.cpp @@ -24,12 +24,27 @@ using namespace dynamicgraph; namespace dynamicgraph { + FactoryStorage* FactoryStorage::getInstance () + { + if (instance_ == 0) { + instance_ = new FactoryStorage; + } + return instance_; + } + + void FactoryStorage::destroy() + { + delete instance_; + instance_ = NULL; + } + FactoryStorage::FactoryStorage () : entityMap () {} FactoryStorage::~FactoryStorage () { + instance_ = 0; dgDEBUGINOUT (25); } @@ -43,7 +58,7 @@ namespace dynamicgraph DG_THROW ExceptionFactory (ExceptionFactory::OBJECT_CONFLICT, "Another entity class already defined with the same name. ", - "(while adding entity class <%s> inside the g_factory).", + "(while adding entity class <%s> inside the factory).", entname.c_str ()); dgERRORF ("Another entity class already defined with the same name. " "(while adding entity class <%s> inside the factory).", @@ -173,18 +188,18 @@ namespace dynamicgraph : entityName (entityClassName) { dgDEBUGIN (15); - g_factory.registerEntity (entityClassName, maker); + FactoryStorage::getInstance()->registerEntity (entityClassName, maker); dgDEBUGOUT (15); } EntityRegisterer::~EntityRegisterer () { dgDEBUGIN(15); - g_factory.deregisterEntity (entityName); + FactoryStorage::getInstance()->deregisterEntity (entityName); dgDEBUGOUT (15); } // The global factory. - FactoryStorage g_factory; + FactoryStorage* FactoryStorage::instance_ = NULL; } // end of namespace dynamicgraph. diff --git a/src/dgraph/pool.cpp b/src/dgraph/pool.cpp index 30054f4..c2224d3 100644 --- a/src/dgraph/pool.cpp +++ b/src/dgraph/pool.cpp @@ -38,6 +38,22 @@ using namespace dynamicgraph; /* --- CLASS ----------------------------------------------------------- */ /* --------------------------------------------------------------------- */ +PoolStorage* PoolStorage:: +getInstance() +{ + if (instance_ == 0) { + instance_ = new PoolStorage; + } + return instance_; +} + +void PoolStorage:: +destroy() +{ + delete instance_; + instance_ = NULL; +} + PoolStorage:: ~PoolStorage () { @@ -52,7 +68,7 @@ PoolStorage:: deregisterEntity(iter); delete (entity); } - + instance_ = 0; dgDEBUGOUT(15); } @@ -301,8 +317,5 @@ getSignal( std::istringstream& sigpath ) return ent.getSignal( signame ); } -namespace dynamicgraph { - //! The global g_pool object. - PoolStorage g_pool; -} +PoolStorage* PoolStorage::instance_ = 0; diff --git a/src/traces/tracer.cpp b/src/traces/tracer.cpp index f85901f..a40c7ad 100644 --- a/src/traces/tracer.cpp +++ b/src/traces/tracer.cpp @@ -128,7 +128,7 @@ addSignalToTraceByName( const string& signame, { dgDEBUGIN(15); istringstream iss( signame ); - SignalBase<int> &sig = g_pool.getSignal(iss); + SignalBase<int> &sig = PoolStorage::getInstance()->getSignal(iss); addSignalToTrace(sig,filename); dgDEBUGOUT(15); } @@ -321,7 +321,7 @@ commandLine( const std::string& cmdLine } else if( cmdLine=="add" ) { - SignalBase<int> &sig = g_pool.getSignal(cmdArgs); + SignalBase<int> &sig = PoolStorage::getInstance()->getSignal(cmdArgs); string r; cmdArgs>>ws>>r; addSignalToTrace(sig,r); dgDEBUG(14)<<"Add <" <<sig.getName ()<<"> with nick \""<<r<<"\""<<endl; diff --git a/tests/factory.cpp b/tests/factory.cpp index 716964d..6b79da6 100644 --- a/tests/factory.cpp +++ b/tests/factory.cpp @@ -34,17 +34,18 @@ dynamicgraph::Entity* makeEntity(const std::string& objectName) BOOST_AUTO_TEST_CASE (constructor) { - dynamicgraph::FactoryStorage factory; + dynamicgraph::FactoryStorage::getInstance(); } BOOST_AUTO_TEST_CASE (registerEntity) { - dynamicgraph::FactoryStorage factory; - factory.registerEntity ("myEntity", &makeEntity); + dynamicgraph::FactoryStorage::getInstance()->registerEntity + ("myEntity", &makeEntity); try { - factory.registerEntity ("myEntity", &makeEntity); + dynamicgraph::FactoryStorage::getInstance()->registerEntity + ("myEntity", &makeEntity); BOOST_ERROR ("Should never happen."); } catch (const dynamicgraph::ExceptionFactory& exception) @@ -55,7 +56,8 @@ BOOST_AUTO_TEST_CASE (registerEntity) try { - factory.registerEntity ("myEntity", 0); + dynamicgraph::FactoryStorage::getInstance()->registerEntity + ("myEntity", 0); BOOST_ERROR ("Should never happen."); } catch (const dynamicgraph::ExceptionFactory& exception) @@ -68,13 +70,12 @@ BOOST_AUTO_TEST_CASE (registerEntity) BOOST_AUTO_TEST_CASE (unregisterEntity) { - dynamicgraph::FactoryStorage factory; - factory.registerEntity ("myEntity", &makeEntity); - factory.deregisterEntity ("myEntity"); + dynamicgraph::FactoryStorage::getInstance()->registerEntity ("myEntity", &makeEntity); + dynamicgraph::FactoryStorage::getInstance()->deregisterEntity ("myEntity"); try { - factory.deregisterEntity ("myEntity"); + dynamicgraph::FactoryStorage::getInstance()->deregisterEntity("myEntity"); BOOST_ERROR ("Should never happen."); } catch (const dynamicgraph::ExceptionFactory& exception) @@ -85,7 +86,8 @@ BOOST_AUTO_TEST_CASE (unregisterEntity) try { - factory.deregisterEntity ("I do not exist."); + dynamicgraph::FactoryStorage::getInstance()->deregisterEntity + ("I do not exist."); BOOST_ERROR ("Should never happen."); } catch (const dynamicgraph::ExceptionFactory& exception) @@ -97,23 +99,27 @@ BOOST_AUTO_TEST_CASE (unregisterEntity) BOOST_AUTO_TEST_CASE (newEntity) { - dynamicgraph::FactoryStorage factory; - factory.registerEntity ("myEntity", &makeEntity); + dynamicgraph::FactoryStorage::getInstance()->registerEntity + ("myEntity", &makeEntity); { boost::shared_ptr<dynamicgraph::Entity> entity - (factory.newEntity ("myEntity", "foo")); + (dynamicgraph::FactoryStorage::getInstance()->newEntity + ("myEntity", "foo")); boost::shared_ptr<dynamicgraph::Entity> entity2 - (factory.newEntity ("myEntity", "foo2")); + (dynamicgraph::FactoryStorage::getInstance()->newEntity + ("myEntity", "foo2")); boost::shared_ptr<dynamicgraph::Entity> entity3 - (factory.newEntity ("myEntity", "")); + (dynamicgraph::FactoryStorage::getInstance()->newEntity + ("myEntity", "")); } try { - factory.newEntity ("I do not exist.", ""); + dynamicgraph::FactoryStorage::getInstance()->newEntity + ("I do not exist.", ""); BOOST_ERROR ("Should never happen."); } catch (const dynamicgraph::ExceptionFactory& exception) @@ -125,10 +131,12 @@ BOOST_AUTO_TEST_CASE (newEntity) BOOST_AUTO_TEST_CASE (existEntity) { - dynamicgraph::FactoryStorage factory; - factory.registerEntity ("myEntity", &makeEntity); - - BOOST_CHECK (factory.existEntity ("myEntity")); - BOOST_CHECK (!factory.existEntity ("myEntity2")); - BOOST_CHECK (!factory.existEntity ("")); + dynamicgraph::FactoryStorage::getInstance()->registerEntity + ("myEntity", &makeEntity); + + BOOST_CHECK (dynamicgraph::FactoryStorage::getInstance()->existEntity + ("myEntity")); + BOOST_CHECK (!dynamicgraph::FactoryStorage::getInstance()->existEntity + ("myEntity2")); + BOOST_CHECK (!dynamicgraph::FactoryStorage::getInstance()->existEntity ("")); } diff --git a/tests/pool.cpp b/tests/pool.cpp index ab323bf..0e8b19d 100644 --- a/tests/pool.cpp +++ b/tests/pool.cpp @@ -52,17 +52,21 @@ BOOST_AUTO_TEST_CASE (pool_list) MyEntity myEntity("MyEntityInst"); std::istringstream in; output_test_stream output; - dynamicgraph::g_pool.commandLine("pool", "list", in, output); + dynamicgraph::PoolStorage::getInstance()->commandLine + ("pool", "list", in, output); BOOST_CHECK (output.is_equal ("MyEntityInst (MyEntity)\n")); - dynamicgraph::g_pool.deregisterEntity(myEntity.getName()); + dynamicgraph::PoolStorage::getInstance()->deregisterEntity + (myEntity.getName()); } BOOST_AUTO_TEST_CASE (pool_display) { MyEntity myEntity("MyEntityInst"); output_test_stream output; - dynamicgraph::Entity& e = dynamicgraph::g_pool.getEntity("MyEntityInst"); + dynamicgraph::Entity& e = dynamicgraph::PoolStorage::getInstance()->getEntity + ("MyEntityInst"); e.display(output); BOOST_CHECK (output.is_equal ("Hello! My name is MyEntityInst !\n")); - dynamicgraph::g_pool.deregisterEntity(myEntity.getName()); + dynamicgraph::PoolStorage::getInstance()->deregisterEntity + (myEntity.getName()); } -- GitLab