factory.h
1 /********************************************************************************
2  * FARSA - Total99 *
3  * Copyright (C) 2008-2011 Tomassino Ferrauto <t_ferrauto@yahoo.it> *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but 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, write to the Free Software *
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
18  ********************************************************************************/
19 
20 #ifndef FACTORY_H
21 #define FACTORY_H
22 
23 #include "configurationconfig.h"
24 #include "parametersettable.h"
25 #include <QString>
26 #include <QStringList>
27 #include <QMap>
28 #include <QList>
29 #include <QVector>
30 #include <typeinfo>
31 #include <memory>
32 
33 namespace farsa {
34 
35 class RealFactory;
36 class ParameterSettableCreator;
37 class ConfigurationWidget;
38 
45 class FARSA_CONF_TEMPLATE ConfigurationWidgetCreator
46 {
47 public:
52  {
53  }
54 
65  virtual ConfigurationWidget* create(ConfigurationParameters& params, QString prefix, QWidget* parent, Qt::WindowFlags f) const = 0;
66 };
67 
75 template <class T>
76 class FARSA_CONF_TEMPLATE ConfigurationWidgetCreatorT : public ConfigurationWidgetCreator
77 {
78 public:
83  {
84  }
85 
96  virtual ConfigurationWidget* create(ConfigurationParameters& params, QString prefix, QWidget* parent, Qt::WindowFlags f) const;
97 };
98 
119 class FARSA_CONF_API Factory {
120 public:
126  static Factory& getInstance();
127 
136  static ConfigurationParameters& getTypeDescriptions();
137 
141  ~Factory();
142 
161  template <class NewClass>
162  void registerClass(QString className, QString parentClassName);
163 
181  QStringList getAllSubclasses(QString className, int levelToStop = -1, bool noAbstractClasses = false);
182 
190  bool isAbstract(QString className);
191 
202  template <class EditorType>
203  void registerEditorForType(QString type);
204 
222  ConfigurationWidget* getEditorForType(ConfigurationParameters& params, QString prefix, QWidget* parent = NULL, Qt::WindowFlags f = 0);
223 
224 private:
231  void cleanupMapsForReRegistration(QString className);
232 
239  template <class T, class U>
240  class Conversion
241  {
242  // Type1 and Type2 have surely two different sizes
243  typedef char Type1;
244  class Type2
245  {
246  char dummy[2];
247  };
248  static Type1 Test(U);
249  static Type2 Test(...);
250  static T MakeT();
251  public:
252  enum { exists = sizeof(Test(MakeT())) == sizeof(Type1) };
253  };
254 
261  template<bool canBeCreated, class H>
262  class RegisterClassHelper {
263  public:
264  RegisterClassHelper(Factory* factory, QString className, QString parentClassName);
265  };
266 
272  Factory();
273 
280  Factory(const Factory &other);
281 
288  Factory& operator=(const Factory &other);
289 
293  QMap<QString, ParameterSettableCreator*> m_classMap;
294 
298  QMap<QString, QString> m_parentsMap;
299 
303  QMap<QString, QStringList> m_childrenMap;
304 
308  QMap<QString, ConfigurationWidgetCreator*> m_editorsMap;
309 
314  friend class RealFactory;
315 };
316 
317 } // end namespace farsa
318 
319 // Implementation of template functions
320 #include "configurationparameters.h"
321 #include "realfactory.h"
322 
323 namespace farsa {
324 
325 template <class T>
326 ConfigurationWidget* ConfigurationWidgetCreatorT<T>::create(ConfigurationParameters& params, QString prefix, QWidget* parent, Qt::WindowFlags f) const
327 {
328  // Addind a group separator at the end of the prefix
329  const QString terminatedPrefix = prefix + ConfigurationParameters::GroupSeparator();
330 
331  // Creating the new editor
332  std::auto_ptr<T> t(new T(params, terminatedPrefix, parent, f));
333 
334  return t.release();
335 }
336 
337 // This namespace contains helper code. We put it in an inner namespace to avoid polluting the farsa namespace
338 namespace __Factory_internal {
339  // this local template check if a class is Abstract
340  // it's is needed because for register a complete hierarchy it's necessary
341  // also to check if a class is abstract so it can be possible to register also
342  // abstract class
343  template<class T>
344  struct checkClass {
345  // Inspired by boost/type_traits/is_abstract.hpp
346  // Deduction fails if T is void, function type,
347  // reference type (14.8.2/2)or an abstract class type
348  // according to review status issue #337
349  template<class U>
350  static char check_sig(U (*)[1]);
351  template<class U>
352  static short check_sig(...);
353  static const bool isAbstract = (sizeof(check_sig<T>(0))!=sizeof(char));
354  // correspond to !isAbstract
355  static const bool canBeCreated = (sizeof(check_sig<T>(0))==sizeof(char));
356  };
357 }
358 
359 template <class H>
360 class Factory::RegisterClassHelper<true, H> {
361 public:
362  RegisterClassHelper(Factory* factory, QString className, QString parentClassName) {
363  factory->cleanupMapsForReRegistration(className);
365  factory->m_parentsMap[className] = parentClassName;
366  factory->m_childrenMap[parentClassName].append( className );
367  H::describe( className );
368  };
369 };
370 
371 template <class H>
372 class Factory::RegisterClassHelper<false, H> {
373 public:
374  RegisterClassHelper(Factory* factory, QString className, QString parentClassName) {
375  factory->cleanupMapsForReRegistration(className);
376  factory->m_parentsMap[className] = parentClassName;
377  factory->m_childrenMap[parentClassName].append( className );
378  };
379 };
380 
381 template <class NewClass>
382 void Factory::registerClass(QString className, QString parentClassName)
383 {
384  RegisterClassHelper<__Factory_internal::checkClass<NewClass>::canBeCreated, NewClass> registerHelper(this, className, parentClassName );
385 }
386 
387 template <class EditorType>
389 {
390  // Checking type if in typeDescriptions
391  //if (!getTypeDescriptions().isGroup(type)) {
392  // throw ConfigurationWidgetForUnknownTypeException(type.toLatin1().data());
393  //}
394 
395  // Removing the old creator, if it existed
396  if (m_editorsMap.contains(type)) {
397  delete m_editorsMap[type];
398 
399  m_editorsMap[type] = NULL;
400  }
401 
402  // Creating the new creator
403  m_editorsMap[type] = new ConfigurationWidgetCreatorT<EditorType>();
404 }
405 
406 template <class EditorType>
408 {
409  Factory::getInstance().registerEditorForType<EditorType>(type);
410 }
411 
412 } // end namespace farsa
413 
414 #endif
The class that registers ParameterSettable types.
Definition: factory.h:119
This file contains the common type defitions used on the whole framework.
The base class for configuration widgets creators. The implementation is in the template class below...
Definition: factory.h:45
The base class for widgets for editing configuration parameters.
virtual ~ConfigurationWidgetCreator()
Destructor.
Definition: factory.h:51
static void setGraphicalEditor(QString type)
Sets the graphical editor for this ParameterSettable This method sets the editor (a subclass of Confi...
Definition: factory.h:407
virtual ~ConfigurationWidgetCreatorT()
Destructor.
Definition: factory.h:82
The class containing configuration parameters.
void registerEditorForType(QString type)
Registers a class to be the editor for the give type.
Definition: factory.h:388
The class implementing the create function of the class above.
Definition: factory.h:76
The class implementing the create function of the class above.
Definition: realfactory.h:93
static Factory & getInstance()
Returns the only instance of this class.
Definition: factory.cpp:26
static QString GroupSeparator()
The character used to split path in groups.
virtual ConfigurationWidget * create(ConfigurationParameters &params, QString prefix, QWidget *parent, Qt::WindowFlags f) const
Creates an instance.
Definition: factory.h:326
Factory class to create ParameterSettable objects.
Definition: realfactory.h:186
void registerClass(QString className, QString parentClassName)
Registers a new instatiable class.
Definition: factory.h:382