00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef FACTORY_H
00021 #define FACTORY_H
00022
00023 #include "configurationconfig.h"
00024 #include "parametersettable.h"
00025 #include <QString>
00026 #include <QStringList>
00027 #include <QMap>
00028 #include <QList>
00029 #include <QVector>
00030 #include <typeinfo>
00031 #include <memory>
00032
00033 namespace farsa {
00034
00035 class RealFactory;
00036 class ParameterSettableCreator;
00037
00058 class FARSA_CONF_API Factory {
00059 public:
00065 static Factory& getInstance();
00066
00075 static ConfigurationParameters& getTypeDescriptions();
00076
00080 ~Factory();
00081
00100 template <class NewClass>
00101 void registerClass(QString className, QString parentClassName);
00102
00120 QStringList getAllSubclasses(QString className, int levelToStop = -1, bool noAbstractClasses = false);
00121
00129 bool isAbstract(QString className);
00130
00131 private:
00138 void cleanupMapsForReRegistration(QString className);
00139
00146 template <class T, class U>
00147 class Conversion
00148 {
00149
00150 typedef char Type1;
00151 class Type2
00152 {
00153 char dummy[2];
00154 };
00155 static Type1 Test(U);
00156 static Type2 Test(...);
00157 static T MakeT();
00158 public:
00159 enum { exists = sizeof(Test(MakeT())) == sizeof(Type1) };
00160 };
00161
00168 template<bool canBeCreated, class H>
00169 class RegisterClassHelper {
00170 public:
00171 RegisterClassHelper(Factory* factory, QString className, QString parentClassName);
00172 };
00173
00179 Factory();
00180
00187 Factory(const Factory &other);
00188
00195 Factory& operator=(const Factory &other);
00196
00200 QMap<QString, ParameterSettableCreator*> m_classMap;
00201
00205 QMap<QString, QString> m_parentsMap;
00206
00210 QMap<QString, QStringList> m_childrenMap;
00211
00216 friend class RealFactory;
00217 };
00218
00219 }
00220
00221
00222 #include "configurationparameters.h"
00223 #include "realfactory.h"
00224
00225 namespace farsa {
00226
00227
00228 namespace __Factory_internal {
00229
00230
00231
00232
00233 template<class T>
00234 struct checkClass {
00235
00236
00237
00238
00239 template<class U>
00240 static char check_sig(U (*)[1]);
00241 template<class U>
00242 static short check_sig(...);
00243 static const bool isAbstract = (sizeof(check_sig<T>(0))!=sizeof(char));
00244
00245 static const bool canBeCreated = (sizeof(check_sig<T>(0))==sizeof(char));
00246 };
00247 }
00248
00249 template <class H>
00250 class Factory::RegisterClassHelper<true, H> {
00251 public:
00252 RegisterClassHelper(Factory* factory, QString className, QString parentClassName) {
00253 factory->cleanupMapsForReRegistration(className);
00254 factory->m_classMap[className] = new ParameterSettableCreatorT<H, Conversion<H *, ParameterSettableInConstructor *>::exists>();
00255 factory->m_parentsMap[className] = parentClassName;
00256 factory->m_childrenMap[parentClassName].append( className );
00257 H::describe( className );
00258 };
00259 };
00260
00261 template <class H>
00262 class Factory::RegisterClassHelper<false, H> {
00263 public:
00264 RegisterClassHelper(Factory* factory, QString className, QString parentClassName) {
00265 factory->cleanupMapsForReRegistration(className);
00266 factory->m_parentsMap[className] = parentClassName;
00267 factory->m_childrenMap[parentClassName].append( className );
00268 };
00269 };
00270
00271 template <class NewClass>
00272 void Factory::registerClass(QString className, QString parentClassName)
00273 {
00274 RegisterClassHelper<__Factory_internal::checkClass<NewClass>::canBeCreated, NewClass> registerHelper(this, className, parentClassName );
00275 }
00276
00277 }
00278
00279 #endif