Newer
Older
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
//
#include <boost/foreach.hpp>
#include "dynamic-graph/debug.h"
Francois Bleibel
committed
using namespace std;
using namespace dynamicgraph;
namespace dynamicgraph {
FactoryStorage *FactoryStorage::getInstance() {
if (instance_ == 0) {
instance_ = new FactoryStorage;
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)
EntityRegisterer::EntityRegisterer(const std::string &entityClassName,
FactoryStorage::EntityConstructor_ptr maker)
: entityName(entityClassName) {
dgDEBUGIN(15);
FactoryStorage::getInstance()->registerEntity(entityClassName, maker);
dgDEBUGOUT(15);
}
EntityRegisterer::~EntityRegisterer() {
dgDEBUGIN(15);
FactoryStorage::getInstance()->deregisterEntity(entityName);
dgDEBUGOUT(15);
}
// The global factory.
FactoryStorage *FactoryStorage::instance_ = NULL;