Newer
Older
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
//
#include <boost/foreach.hpp>
#include "dynamic-graph/debug.h"
#include "dynamic-graph/factory.h"
Francois Bleibel
committed
using namespace std;
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()
{
void FactoryStorage::
registerEntity
(const std::string& entname, FactoryStorage::EntityConstructor_ptr ent)
{
if (existEntity(entname))
{
DG_THROW ExceptionFactory
(ExceptionFactory::OBJECT_CONFLICT,
"Another entity class already defined with the same name. ",
"(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).",
entname.c_str());
}
else
{
if (!ent)
{
// FIXME: we should have a better error code for that.
DG_THROW ExceptionFactory
(ExceptionFactory::OBJECT_CONFLICT, "Bad entity constructor.");
}
dgDEBUG(30) << "Register entity <" << entname << "> in the factory."
<< std::endl;
entityMap[entname] = ent;
void FactoryStorage::deregisterEntity(const std::string& entname)
{
if (!existEntity(entname))
{
DG_THROW ExceptionFactory
(ExceptionFactory::OBJECT_CONFLICT, "Entity class not defined yet. ",
"(while removing entity class <%s>).", entname.c_str());
dgERRORF(ExceptionFactory::OBJECT_CONFLICT,
"Entity class not defined yet. "
"(while removing entity class <%s>).",
entname.c_str());
}
else
{
dgDEBUG(30) << "Deregister entity <" << entname
<< "> from the factory." << std::endl;
entityMap.erase(entname);
}
Francois Bleibel
committed
Entity* FactoryStorage::newEntity
(const std::string& classname, const std::string& objname) const
{
dgDEBUG(15) << "New <" << classname << ">Entity <"
<< objname << ">" << std::endl;
Francois Bleibel
committed
EntityMap::const_iterator entPtr = entityMap.find(classname);
if (entPtr == entityMap.end())
{
DG_THROW ExceptionFactory
(ExceptionFactory::UNREFERED_OBJECT, "Unknown entity.",
" (while calling new_entity <%s>)", classname.c_str());
}
return entPtr->second(objname);
}
// This checks efficiently if a key exists in an STL map using the
// approach suggested by Scott Meyer's Effective STL (item 24).
bool FactoryStorage::existEntity(const std::string& name) const
{
EntityMap::const_iterator lb = entityMap.lower_bound(name);
return lb != entityMap.end() && !(entityMap.key_comp()(name, lb->first));
}
// FIXME: this should be removed at some point.
void FactoryStorage::listEntities
(std::vector<std::string>& outList) const
{
typedef std::pair<std::string, EntityConstructor_ptr> iter_t;
BOOST_FOREACH (const iter_t& entity, entityMap)
outList.push_back(entity.first);
}
EntityRegisterer::EntityRegisterer
(const std::string& entityClassName,
FactoryStorage::EntityConstructor_ptr maker)
: entityName(entityClassName)
{
dgDEBUGIN(15);
FactoryStorage::getInstance()->registerEntity(entityClassName, maker);
dgDEBUGOUT(15);
}
EntityRegisterer::~EntityRegisterer()
{