Skip to content
Snippets Groups Projects
Commit 273ce670 authored by Florent Lamiraux's avatar Florent Lamiraux
Browse files

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.
parent 34801f48
No related branches found
No related tags found
No related merge requests found
......@@ -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).
......
......@@ -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
......
......@@ -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
......
......@@ -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
......@@ -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::
......
......@@ -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.
......@@ -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;
......@@ -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;
......
......@@ -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 (""));
}
......@@ -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());
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment