Skip to content
Snippets Groups Projects

Resolve "Factory documentation"

Merged Joan Solà Ortega requested to merge 299-factory-documentation into devel
@@ -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);
Loading