Skip to content
Snippets Groups Projects

Resolve "Do not require the invocation of ::get() in Factory"

15 files
+ 90
88
Compare changes
  • Side-by-side
  • Inline
Files
15
@@ -126,18 +126,20 @@ namespace wolf
*
* Second to know, the Factory class is a <a href="http://stackoverflow.com/questions/1008019/c-singleton-design-pattern#1008289">singleton</a>:
* it can only exist once in your application.
* To access it, use the static method get(),
* To access it, we internally use the static method get(),
*
* \code
* Factory<MyTypeBase, MyTypeInput>::get()
* \endcode
*
* where, of course, you better make use of the appropriate typedef in place of ````Factory<MyTypeBase, MyTypeInput>````.
* but this is a private method.
*
* You can then call the methods you like, e.g. to create a landmark, you use:
* The interesting methods are designed static, and are the ones responsible for accessing the Factory instance via .get().
*
* You must therefore call the methods you like statically, e.g. to create a landmark, you use:
*
* \code
* FactoryLandmark::get().create(TYPE, args...); // see below for creating objects ...
* FactoryLandmark::create(TYPE, args...); // see below for creating objects ...
* \endcode
*
* #### Write creator methods (in your derived object classes)
@@ -172,7 +174,7 @@ namespace wolf
* that knows how to create your specific object, e.g.:
*
* \code
* FactoryLandmark::get().registerCreator("LandmarkPolyline2d", LandmarkPolyline2d::create);
* FactoryLandmark::registerCreator("LandmarkPolyline2d", LandmarkPolyline2d::create);
* \endcode
*
* #### Automatic registration
@@ -180,7 +182,7 @@ namespace wolf
* For example, in sensor_camera_yaml.cpp we find the line:
*
* \code
* const bool registered_camera_intr = FactoryParamsSensor::get().registerCreator("ParamsSensorCamera", createParamsSensorCamera);
* const bool registered_camera_intr = FactoryParamsSensor::registerCreator("ParamsSensorCamera", createParamsSensorCamera);
* \endcode
*
* which is a static invocation (i.e., it is placed at global scope outside of the ParamsSensorCamera class).
@@ -191,7 +193,7 @@ namespace wolf
* The method unregisterCreator() unregisters the ObjectXxx::create() method. It only needs to be passed the string of the object type.
*
* \code
* Factory<MyTypeBase, MyTypeInput>::get().unregisterCreator("ParamsSensorCamera");
* Factory<MyTypeBase, MyTypeInput>::unregisterCreator("ParamsSensorCamera");
* \endcode
*
* #### Create objects using the factory
@@ -201,13 +203,13 @@ namespace wolf
* To create e.g. a LandmarkPolyline2d from a YAML node you type:
*
* \code
* LandmarkBasePtr lmk_ptr = Factory<LandmarkBasePtr, YAML::Node>::get().create("LandmarkPolyline2d", lmk_yaml_node);
* LandmarkBasePtr lmk_ptr = Factory<LandmarkBasePtr, YAML::Node>::create("LandmarkPolyline2d", lmk_yaml_node);
* \endcode
*
* or even better, make use of the convenient typedefs:
*
* \code
* LandmarkBasePtr lmk_ptr = FactoryLandmark::get().create("LandmarkPolyline2d", lmk_yaml_node);
* LandmarkBasePtr lmk_ptr = FactoryLandmark::create("LandmarkPolyline2d", lmk_yaml_node);
* \endcode
*
* ### Examples
@@ -247,7 +249,7 @@ namespace wolf
* // Register landmark creator (put the register code inside an unnamed namespace):
* namespace
* {
* const bool registered_lmk_polyline_2d = FactoryLandmark::get().registerCreator("LandmarkPolyline2d", LandmarkPolyline2d::create);
* const bool registered_lmk_polyline_2d = FactoryLandmark::registerCreator("LandmarkPolyline2d", LandmarkPolyline2d::create);
* }
*
* \endcode
@@ -280,9 +282,9 @@ class Factory
typedef std::map<std::string, CreatorCallback> CallbackMap;
public:
bool registerCreator(const std::string& _type, CreatorCallback createFn);
bool unregisterCreator(const std::string& _type);
TypeBasePtr create(const std::string& _type, TypeInput... _input);
static bool registerCreator(const std::string& _type, CreatorCallback createFn);
static bool unregisterCreator(const std::string& _type);
static TypeBasePtr create(const std::string& _type, TypeInput... _input);
std::string getClass() const;
private:
@@ -291,7 +293,7 @@ class Factory
// Singleton ---------------------------------------------------
// This class is a singleton. The code below guarantees this.
// See: http://stackoverflow.com/questions/1008019/c-singleton-design-pattern
public:
private:
static Factory& get();
public:
Factory(const Factory&) = delete;
@@ -304,11 +306,11 @@ class Factory
template<class TypeBase, typename... TypeInput>
inline bool Factory<TypeBase, TypeInput...>::registerCreator(const std::string& _type, CreatorCallback createFn)
{
bool reg = callbacks_.insert(typename CallbackMap::value_type(_type, createFn)).second;
bool reg = get().callbacks_.insert(typename CallbackMap::value_type(_type, createFn)).second;
if (reg)
std::cout << std::setw(26) << std::left << getClass() << " <-- registered " << _type << std::endl;
std::cout << std::setw(26) << std::left << get().getClass() << " <-- registered " << _type << std::endl;
else
std::cout << std::setw(26) << std::left << getClass() << " X-- skipping " << _type << ": already registered." << std::endl;
std::cout << std::setw(26) << std::left << get().getClass() << " X-- skipping " << _type << ": already registered." << std::endl;
return reg;
}
@@ -316,17 +318,17 @@ inline bool Factory<TypeBase, TypeInput...>::registerCreator(const std::string&
template<class TypeBase, typename... TypeInput>
inline bool Factory<TypeBase, TypeInput...>::unregisterCreator(const std::string& _type)
{
return callbacks_.erase(_type) == 1;
return get().callbacks_.erase(_type) == 1;
}
template<class TypeBase, typename... TypeInput>
inline typename Factory<TypeBase, TypeInput...>::TypeBasePtr Factory<TypeBase, TypeInput...>::create(const std::string& _type, TypeInput... _input)
{
typename CallbackMap::const_iterator creator_callback_it = callbacks_.find(_type);
typename CallbackMap::const_iterator creator_callback_it = get().callbacks_.find(_type);
if (creator_callback_it == callbacks_.end())
if (creator_callback_it == get().callbacks_.end())
// not found
throw std::runtime_error(getClass() + " : Unknown type \"" + _type + "\". Possibly you tried to use an unregistered creator.");
throw std::runtime_error(get().getClass() + " : Unknown type \"" + _type + "\". Possibly you tried to use an unregistered creator.");
// Invoke the creation function
return (creator_callback_it->second)(std::forward<TypeInput>(_input)...);
Loading