AbstractFactoryMethod.h
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5*
6* ArmarX is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License version 2 as
8* published by the Free Software Foundation.
9*
10* ArmarX is distributed in the hope that it will be useful, but
11* WITHOUT ANY WARRANTY; without even the implied warranty of
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13* GNU General Public License for more details.
14*
15* You should have received a copy of the GNU General Public License
16* along with this program. If not, see <http://www.gnu.org/licenses/>.
17*
18* @package ArmarXCore::core
19* @author Nils Adermann (naderman at naderman dot de)
20* @date 2009
21* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22* GNU General Public License
23*/
24
25#pragma once
26
27#include <map>
28#include <memory>
29#include <string>
30#include <vector>
31
33
34namespace armarx
35{
36 /**
37 * A template that can be used as a superclass of a class hierarchy that
38 * wants to provide a factory method which allows instantiation of objects
39 * based on a string identifier.
40 *
41 * The first template argument is the base class of your class hierarchy.
42 * The second argument is the parameter type for the initialisation function
43 * each subclass has to provide. If you need multiple constructor arguments
44 * it is recommended to use a boost::tuple.
45 */
46 template <typename Base,
47 typename constructorArg,
48 typename SharedPointer = std::shared_ptr<Base>>
50 {
51 /**
52 * Classname of this instance, so that one can save in a string which classtype this instance is and recreate it.
53 */
54 std::string className;
55
56 public:
57 using BaseFactory = Base;
58 using ConstructorArg = constructorArg;
59 using SharedPointerType = SharedPointer;
60
61 /**
62 * @brief getClassName returns the name that this instance was generated
63 * with.
64 * @return name of class
65 */
66 std::string
68 {
69 return className;
70 }
71
72 /**
73 * The function pointer type of subclass initialisation functions.
74 * This matches the createInstance method.
75 */
76 typedef SharedPointerType (*initialisationFunction)(constructorArg);
77
78 /**
79 * Function which can be used to retrieve an object specified by string name.
80 */
82 fromName(const std::string& name, constructorArg params)
83 {
84 if (subTypes()->find(name) == subTypes()->end())
85 {
86 ARMARX_DEBUG << "factory does not manage a type of name " << name;
87 return SharedPointerType();
88 }
89 ARMARX_DEBUG << "calling initializer for name " << name;
90 SharedPointerType result = subTypes()->at(name)(params);
91 ARMARX_DEBUG << "done initializing object for name " << name;
92 if (result)
93 {
94 result->className = name;
95 }
96 return result;
97 }
98
99 /**
100 * @brief getAvailableClasses retrieves a list of all registered classes
101 * as their string-representation.
102 * @return list of available classes by their name.
103 */
104 static std::vector<std::string>
106 {
107 std::vector<std::string> result;
108 typename std::map<std::string, initialisationFunction>::iterator it =
109 subTypes()->begin();
110
111 for (; it != subTypes()->end(); ++it)
112 {
113 result.push_back(it->first);
114 }
115
116 return result;
117 }
118
119 /**
120 * Returns the class's name. This is used to identify the class which the
121 * user requests an instance of.
122 */
123 static std::string
125 {
126 return "AbstractFactoryMethod";
127 }
128
129 /**
130 * Initialisation function which needs to be provided by every subclass.
131 * It calls the constructor and returns a shared_ptr to the resulting
132 * object.
133 */
134 static SharedPointerType
135 createInstance(constructorArg)
136 {
137 return SharedPointerType();
138 }
139
140 /**
141 * Statically called by subclasses to register their name and initialisation
142 * function so they can be found by {@link fromName fromName}.
143 */
144 static void
145 registerClass(const std::string& name, initialisationFunction init)
146 {
147 ARMARX_VERBOSE << typeid(Base).name() << "Registering factory '" << name
148 << "' for function of type: " << armarx::GetTypeString<Base>();
149
150 (*subTypes())[name] = init;
151 }
152
153 /**
154 * A helper struct to allow static initialisation of the subclass lookup table.
155 */
157 {
158 SubClassRegistry(const std::string& name, initialisationFunction init)
159 {
160 Base::registerClass(name, init);
161 }
162 };
163
164 private:
165 /**
166 * Static wrapper method for accessing subTypes map.
167 * This method is necessary to make certain that the map is initialised
168 * before use. This can only be guaranteed through a static local variable
169 * in a function.
170 */
171 static std::shared_ptr<std::map<std::string, initialisationFunction>>
172 subTypes()
173 {
174 static std::shared_ptr<std::map<std::string, initialisationFunction>> subTypes(
175 new std::map<std::string, initialisationFunction>);
176
177 return subTypes;
178 }
179 };
180} // namespace armarx
A template that can be used as a superclass of a class hierarchy that wants to provide a factory meth...
SharedPointerType(* initialisationFunction)(constructorArg)
The function pointer type of subclass initialisation functions.
std::string getClassName()
getClassName returns the name that this instance was generated with.
static void registerClass(const std::string &name, initialisationFunction init)
Statically called by subclasses to register their name and initialisation function so they can be fou...
static SharedPointerType fromName(const std::string &name, constructorArg params)
Function which can be used to retrieve an object specified by string name.
static std::string getName()
Returns the class's name.
static std::vector< std::string > getAvailableClasses()
getAvailableClasses retrieves a list of all registered classes as their string-representation.
static SharedPointerType createInstance(constructorArg)
Initialisation function which needs to be provided by every subclass.
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::string GetTypeString(const std::type_info &tinf, bool withoutNamespaceSpecifier=false)
SubClassRegistry(const std::string &name, initialisationFunction init)