All Classes Namespaces Functions Variables Typedefs Enumerations Pages
objectfactory.h
1 /* Copyright (C) 2004-2010 OpenMBV Development Team
2  *
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2.1 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16  *
17  * Contact: friedrich.at.gc@googlemail.com
18  */
19 
20 #ifndef _OPENMBV_OBJECTFACTORY_H_
21 #define _OPENMBV_OBJECTFACTORY_H_
22 
23 #include <map>
24 #include <stdexcept>
25 #include <typeinfo>
26 #include <mbxmlutilshelper/dom.h>
27 #include <xercesc/dom/DOMElement.hpp>
28 
29 namespace OpenMBV {
30 
31 class Object;
32 
37 
38  public:
39 
43  template<class CreateType>
44  static void registerXMLName(const MBXMLUtils::FQN &name) {
45  registerXMLName(name, &allocate<CreateType>);
46  }
47 
51  template<class ContainerType>
52  static std::shared_ptr<ContainerType> create(const xercesc::DOMElement *element) {
53  // just check if ContainerType is derived from Object if not throw a compile error
54  static_assert(std::is_convertible<ContainerType*, Object*>::value,
55  "In OpenMBV::ObjectFactory::create<ContainerType>(...) ContainerType must be derived from Object.");
56  // return NULL if no input is supplied
57  if(element==NULL) return std::shared_ptr<ContainerType>();
58  // loop over all all registred types corresponding to element->ValueStr()
59  std::pair<MapIt, MapIt> range=instance().registeredType.equal_range(MBXMLUtils::E(element)->getTagName());
60  for(MapIt it=range.first; it!=range.second; it++) {
61  // allocate a new object using the allocate function pointer
62  std::shared_ptr<Object> ele=it->second();
63  // try to cast ele up to ContainerType
64  std::shared_ptr<ContainerType> ret=std::dynamic_pointer_cast<ContainerType>(ele);
65  // if possible, return it
66  if(ret)
67  return ret;
68  }
69  // no matching element found: throw error
70  throw std::runtime_error("No class named "+MBXMLUtils::X()%element->getTagName()+" found which is of type "+
71  typeid(ContainerType).name()+".");
72  }
73 
75  template<class CreateType>
76  static std::shared_ptr<CreateType> create() {
77  return std::shared_ptr<CreateType>(new CreateType, &deleter<CreateType>);
78  }
79 
81  template<class CreateType>
82  static std::shared_ptr<CreateType> create(const std::shared_ptr<CreateType> &t) {
83  return std::shared_ptr<CreateType>(new CreateType(*t.get()), &deleter<CreateType>);
84  }
85 
86  private:
87 
88  // a pointer to a function allocating an object
89  typedef std::shared_ptr<Object> (*allocateFkt)();
90 
91  // convinence typedefs
92  typedef std::multimap<MBXMLUtils::FQN, allocateFkt> Map;
93  typedef typename Map::iterator MapIt;
94 
95  // private ctor
96  ObjectFactory() {}
97 
98  static void registerXMLName(const MBXMLUtils::FQN &name, allocateFkt alloc);
99 
100  // create an singleton instance of the object factory.
101  // only declaration here and defition and explicit instantation for all Object in objectfactory.cc (required for Windows)
102  static ObjectFactory& instance();
103 
104  // a multimap of all registered types
105  Map registeredType;
106 
107  // a wrapper to allocate an object of type CreateType: used by create(xercesc::DOMElement *)
108  template<class CreateType>
109  static std::shared_ptr<Object> allocate() {
110  return std::shared_ptr<CreateType>(new CreateType, &deleter<CreateType>);
111  }
112 
113  // a wrapper to deallocate an object of type T: all dtors are protected but ObjectFactory is a friend of all classes
114  template<class T>
115  static void deleter(T *t) { delete t; }
116 
117 };
118 
122 template<class CreateType>
124 
125  public:
126 
129  ObjectFactory::registerXMLName<CreateType>(name);
130  };
131 
132 };
133 
134 }
135 
136 #define OPENMBV_OBJECTFACTORY_CONCAT1(X, Y) X##Y
137 #define OPENMBV_OBJECTFACTORY_CONCAT(X, Y) OPENMBV_OBJECTFACTORY_CONCAT1(X, Y)
138 #define OPENMBV_OBJECTFACTORY_APPENDLINE(X) OPENMBV_OBJECTFACTORY_CONCAT(X, __LINE__)
139 
142 #define OPENMBV_OBJECTFACTORY_REGISTERXMLNAME(ThisType, name) \
143  static OpenMBV::ObjectFactoryRegisterXMLNameHelper<ThisType> \
144  OPENMBV_OBJECTFACTORY_APPENDLINE(objectFactoryRegistrationDummyVariable)(name);
145 
146 #endif
static std::shared_ptr< ContainerType > create(const xercesc::DOMElement *element)
Definition: objectfactory.h:52
Definition: objectfactory.h:36
static void registerXMLName(const MBXMLUtils::FQN &name)
Definition: objectfactory.h:44
static std::shared_ptr< CreateType > create(const std::shared_ptr< CreateType > &t)
Definition: objectfactory.h:82
ObjectFactoryRegisterXMLNameHelper(const MBXMLUtils::FQN &name)
Definition: objectfactory.h:128
Definition: objectfactory.h:123
static std::shared_ptr< CreateType > create()
Definition: objectfactory.h:76

Impressum / Disclaimer / Datenschutz Generated by doxygen 1.8.5 Valid HTML