Newer
Older
// Copyright 2010, François Bleibel, Thomas Moulard, Olivier Stasse,
// JRL, CNRS/AIST.
//
// This file is part of dynamic-graph.
// dynamic-graph 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.
//
// dynamic-graph 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
// dynamic-graph. If not, see <http://www.gnu.org/licenses/>.
#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 ()
: entityMap ()
{}
Francois Bleibel
committed
FactoryStorage::~FactoryStorage ()
{
dgDEBUGINOUT (25);
}
Francois Bleibel
committed
void
FactoryStorage::registerEntity(const std::string& entname,
FactoryStorage::EntityConstructor_ptr ent)
{
dgDEBUGIN (25);
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 g_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;
}
dgDEBUGOUT (25);
}
Francois Bleibel
committed
void
FactoryStorage::deregisterEntity (const std::string& entname)
{
dgDEBUGIN (25);
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);
}
dgDEBUGOUT (25);
}
Francois Bleibel
committed
Entity*
FactoryStorage::newEntity (const std::string& classname,
const std::string& objname) const
{
dgDEBUG (15) << "New <" << classname << ">Entity <"
<< objname << ">" << std::endl;
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);
}
Francois Bleibel
committed
// 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));
}
Francois Bleibel
committed
//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);
}
Francois Bleibel
committed
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
void
FactoryStorage::commandLine(const std::string& cmdLine,
std::istringstream& cmdArgs,
std::ostream& os)
{
if (cmdLine == "help")
{
os << "factory ";
std::string cmd2;
cmdArgs >> cmd2;
if (!cmdArgs.good ())
os
<< " <arg>\t\t\t\taccess to the factory (help <arg> for more detail)"
<< std::endl;
else if (cmd2 == "list")
os << "list\t\t:List all available entities." << std::endl;
else if (cmd2 == "listEntities")
os <<"listEntities\t:List available entities." << std::endl;
}
else if (cmdLine == "list")
commandLine("listEntities",cmdArgs,os);
else if (cmdLine == "listEntities")
{
os <<" List of available entities:" << std::endl;
typedef std::pair<std::string, EntityConstructor_ptr> iter_t;
BOOST_FOREACH (const iter_t& entity, entityMap)
os << " - " << entity.first << std::endl;
}
return;
}
Francois Bleibel
committed
EntityRegisterer::EntityRegisterer
(const std::string& entityClassName, FactoryStorage::EntityConstructor_ptr maker)
: entityName (entityClassName)
{
dgDEBUGIN (15);
g_factory.registerEntity (entityClassName, maker);
dgDEBUGOUT (15);
}
EntityRegisterer::~EntityRegisterer()
{
dgDEBUGIN(15);
g_factory.deregisterEntity (entityName);
dgDEBUGOUT (15);
}
// The global factory.
FactoryStorage g_factory;
} // end of namespace dynamicgraph.