Skip to content
Snippets Groups Projects
Commit ba4fe069 authored by Joan Solà Ortega's avatar Joan Solà Ortega
Browse files

Update factory.h

parent 60916617
No related branches found
No related tags found
1 merge request!350Resolve "Factory documentation"
Pipeline #5097 passed
...@@ -25,35 +25,61 @@ namespace wolf ...@@ -25,35 +25,61 @@ namespace wolf
/** \brief Singleton template factory /** \brief Singleton template factory
* *
* This class implements a generic factory as a singleton. * This template class implements a generic factory as a singleton.
*
* > IMPORTANT: This template factory can be used to construct many different objects except:
* > - Objects deriving from SensorBase --> see SensorFactory
* > - Objects deriving from ProcessorBase --> see ProcessorFactory
* >
* > The reason for this is that the two cases above need a more elaborated API than the one in this template class.
* *
* \param TypeBase base type of all the objects created by the factory * \param TypeBase base type of all the objects created by the factory
* \param TypeInput type of the input argument. Typical cases are std::string for file names, and YAML::Node for YAML nodes. * \param TypeInput variadic type for the input arguments.
*
* ### Template specialization
* *
* - The class is templatized on the class of the produced objects, __TypeBase__. * - The class is templatized on the class of the produced objects, __TypeBase__.
* The produced objects are always of a class deriving from TypeBase. * The produced objects are always of a class deriving from TypeBase.
* The returned data is always a pointer to TypeBase. * The returned data is always a shared pointer to TypeBase.
* *
* For example, you may use as __TypeBase__ the following types: * For example, you may use as __TypeBase__ the following types:
* - LandmarkBase: the Factory creates landmarks deriving from LandmarkBase and returns base pointers ````LandmarkBasePtr```` to them * - LandmarkBase: the Factory creates landmarks deriving from LandmarkBase and returns base pointers ````LandmarkBasePtr```` to them
* - ParamsSensorBase: the Factory creates intrinsic parameters deriving from ParamsSensorBase and returns base pointers ````ParamsSensorBasePtr```` to them * - ParamsSensorBase: the Factory creates intrinsic parameters deriving from ParamsSensorBase and returns base pointers ````ParamsSensorBasePtr```` to them
* - XxxBase: the Factory creates objects deriving from XxxBase and returns pointers ````XxxBasePtr```` to them. * - XxxBase: the Factory creates objects deriving from XxxBase and returns pointers ````XxxBasePtr```` to them.
* *
* - The class in also templatized on the type of the input parameter of the creator, __TypeInput__: * - The class is variadic-templatized on the types of the input parameter of the creator, __TypeInput__:
* - ````std::string```` is used when the input parameter is a file name from which to read data (typically a YAML file). * - ````std::string```` is used when the input parameter is a file name from which to read data (typically a YAML file).
* - ````YAML::Node```` is used when the input parameter is a YAML node with structured data. * - ````std::string, wolf::ParamsServer``` is used when nodes are build from parameters in the ParamsServer
* - ````YAML::Node```` is used when the input parameter is a YAML node with structured data.
* - Any other variadic list of inputs is possible.
*
* - Examples of specific factories existing in Wolf are:
* \code
*
* // SensorFactory
* typedef Factory<SensorBase, // Type of objects to be created: SensorBasePtr
* const std::string&, // Name of the sensor
* const Eigen::VectorXd&, // Sensor extrinsics
* const ParamsSensorBasePtr> // Sensor parameters
* SensorFactory;
*
* // ProcessorFactory
* typedef Factory<ProcessorBase, // Type of object created: ProcessorBasePtr
* const std::string&, // Name of the processor
* const ParamsProcessorBasePtr> // Parameters for creating the processor
* ProcessorFactory;
*
* // AutoConfProcessorFactory
* typedef Factory<ProcessorBase, // Type of object created: ProcessorBasePtr
* const std::string&, // Name of the processor
* const ParamsServer> // Parameters for creating the processor
* AutoConfProcessorFactory;
*
* // Landmarks from YAML
* typedef Factory<LandmarkBase, // Type of node created: LandmarkBasePtr
* const YAML::Node&> // YAML node with the lmk params
* LandmarkFactory;
* \endcode
* *
* ### Operation of the factory * ### Operation of the factory
* *
* #### Rationale * #### Rationale
* *
* This factory can create objects of classes deriving from TypeBase. * Once specialized, this factory can create objects of classes deriving from TypeBase.
* *
* > For example, if you want to make a Landmark factory, set TypeBase = LandmarkBase.\n * > For example, if you want to make a Landmark factory, set TypeBase = LandmarkBase.\n
* > Then, the factory will create specific landmarks deriving from LandmarkBase.\n * > Then, the factory will create specific landmarks deriving from LandmarkBase.\n
...@@ -75,18 +101,18 @@ namespace wolf ...@@ -75,18 +101,18 @@ namespace wolf
* - Examples: Write and register a landmark creator for LandmarkPolyline2d. * - Examples: Write and register a landmark creator for LandmarkPolyline2d.
* *
* #### Define correct TYPE names * #### Define correct TYPE names
* The rule to make new TYPE strings unique is that you skip the generic 'Type' prefix from your class name, * We use a std::string with literally the same text as the derived class name, e.g.:
* and you build a string in CAPITALS with space separators, e.g.: * - ParamsSensorCamera -> ````"ParamsSensorCamera"````
* - ParamsSensorCamera -> ````"CAMERA"```` * - ParamsSensorLaser2d -> ````"ParamsSensorLaser2d"````
* - ParamsSensorLaser2d -> ````"LASER 2d"```` * - LandmarkPolyline2d -> ````"LandmarkPolyline2d"````
* - LandmarkPolyline2d -> ````"POLYLINE 2d"````
* - etc. * - etc.
* *
* #### Access the factory * #### Access the factory
*
* The first thing to know is that we have defined typedefs for the templates that we are using. For example: * The first thing to know is that we have defined typedefs for the templates that we are using. For example:
* *
* \code * \code
* typedef Factory<ParamsSensorBase, std::string> ParamsSensorFactory; * typedef Factory<ParamsSensorBase, std::string> ParamsSensorFactory;
* typedef Factory<ProcessorParamsBase, std::string> ProcessorParamsFactory; * typedef Factory<ProcessorParamsBase, std::string> ProcessorParamsFactory;
* typedef Factory<LandmarkBase, YAML::Node> LandmarkFactory; * typedef Factory<LandmarkBase, YAML::Node> LandmarkFactory;
* \endcode * \endcode
...@@ -103,10 +129,11 @@ namespace wolf ...@@ -103,10 +129,11 @@ namespace wolf
* You can then call the methods you like, e.g. to create a landmark, you use: * You can then call the methods you like, e.g. to create a landmark, you use:
* *
* \code * \code
* LandmarkFactory::get().create(...); // see below for creating objects ... * LandmarkFactory::get().create(TYPE, args...); // see below for creating objects ...
* \endcode * \endcode
* *
* #### Write creator methods (in your derived object classes) * #### Write creator methods (in your derived object classes)
*
* The method LandmarkPolyline2d::create(...) exists in the LandmarkPolyline2d class as a static method. * The method LandmarkPolyline2d::create(...) exists in the LandmarkPolyline2d class as a static method.
* All these ````XxxXxx::create()```` methods need to have exactly the same API, regardless of the object type. * All these ````XxxXxx::create()```` methods need to have exactly the same API, regardless of the object type.
* The API puts into play the two template parameters: * The API puts into play the two template parameters:
...@@ -234,12 +261,16 @@ namespace wolf ...@@ -234,12 +261,16 @@ namespace wolf
template<class TypeBase, typename... TypeInput> template<class TypeBase, typename... TypeInput>
class Factory class Factory
{ {
private:
typedef std::shared_ptr<TypeBase> TypeBasePtr; typedef std::shared_ptr<TypeBase> TypeBasePtr;
public: public:
// example of creator callback (see typedefs below) // example of creator callback (see typedefs below)
typedef TypeBasePtr (*CreatorCallback)(TypeInput... _input); typedef TypeBasePtr (*CreatorCallback)(TypeInput... _input);
private: private:
typedef std::map<std::string, CreatorCallback> CallbackMap; typedef std::map<std::string, CreatorCallback> CallbackMap;
public: public:
bool registerCreator(const std::string& _type, CreatorCallback createFn); bool registerCreator(const std::string& _type, CreatorCallback createFn);
bool unregisterCreator(const std::string& _type); bool unregisterCreator(const std::string& _type);
......
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