20#ifndef _OPENMBV_OBJECTFACTORY_H_
21#define _OPENMBV_OBJECTFACTORY_H_
27#include <mbxmlutilshelper/dom.h>
28#include <xercesc/dom/DOMElement.hpp>
29#include <openmbvcppinterface/object.h>
45 template<
class CreateType>
47 registerXMLNamePrivate(name, &defaultCTor<CreateType>);
48 registerTypePrivate<CreateType>(©CTor<CreateType>);
54 template<
class ContainerType>
55 static std::shared_ptr<ContainerType>
create(
const xercesc::DOMElement *element) {
57 static_assert(std::is_convertible<ContainerType*, Object*>::value,
58 "In OpenMBV::ObjectFactory::create<ContainerType>(...) ContainerType must be derived from Object.");
60 if(element==
nullptr)
return {};
62 auto range=instance().registeredName.equal_range(MBXMLUtils::E(element)->getTagName());
63 for(
auto it=range.first; it!=range.second; it++) {
65 std::shared_ptr<Object> ele=it->second();
67 std::shared_ptr<ContainerType> ret=std::dynamic_pointer_cast<ContainerType>(ele);
73 throw std::runtime_error(
"No class named "+
MBXMLUtils::X()%element->getTagName()+
" found which is of type "+
74 typeid(ContainerType).name()+
".");
78 template<
class CreateType>
79 static std::shared_ptr<CreateType>
create() {
80 return std::shared_ptr<CreateType>(
new CreateType, &deleter<CreateType>);
86 template<
class ContainerType>
87 static std::shared_ptr<ContainerType>
create(
const std::shared_ptr<ContainerType> &t) {
89 if(t==
nullptr)
return {};
92 auto it=instance().registeredType.find(std::type_index(
typeid(tRef)));
94 if(it==instance().registeredType.end())
95 throw std::runtime_error(std::string(
"No class type ")+
typeid(tRef).name()+
" found in ObjectFactory.");
97 return std::static_pointer_cast<ContainerType>(it->second(t));
100 static void addErrorMsg(
const std::string &msg);
101 static std::string getAndClearErrorMsg();
106 using DefaultCTor = std::shared_ptr<Object> (*)();
107 using CopyCTor = std::shared_ptr<Object> (*)(
const std::shared_ptr<Object>&);
110 using MapName = std::multimap<MBXMLUtils::FQN, DefaultCTor>;
111 using MapNameIt =
typename MapName::iterator;
112 using MapType = std::map<std::type_index, CopyCTor>;
113 using MapTypeIt =
typename MapType::iterator;
118 static void registerXMLNamePrivate(
const MBXMLUtils::FQN &name, DefaultCTor alloc);
120 template<
class CreateType>
121 static void registerTypePrivate(CopyCTor alloc) {
122 instance().registeredType.emplace(std::type_index(
typeid(CreateType)), alloc);
127 static ObjectFactory& instance();
130 MapName registeredName;
131 MapType registeredType;
134 template<
class CreateType>
135 static std::shared_ptr<Object> defaultCTor() {
136 return std::shared_ptr<CreateType>(
new CreateType, &deleter<CreateType>);
140 template<
class CreateType>
141 static std::shared_ptr<Object> copyCTor(
const std::shared_ptr<Object> &t) {
142 auto tCast=std::static_pointer_cast<CreateType>(t);
143 return std::shared_ptr<CreateType>(
new CreateType(*tCast), &deleter<CreateType>);
148 static void deleter(T *t) {
delete t; }
150 static std::string errorMsg;
156template<
class CreateType>
164 ObjectFactory::registerXMLName<CreateType>(name);
166 catch(std::exception &ex) {
167 ObjectFactory::addErrorMsg(ex.what());
170 ObjectFactory::addErrorMsg(
"Unknown error");
180#define OPENMBV_OBJECTFACTORY_REGISTERXMLNAME(ThisType, name) \
181 static OpenMBV::ObjectFactoryRegisterXMLNameHelper<ThisType> BOOST_PP_CAT(objectFactoryRegistrationDummyVariable_, __LINE__)(name);
Definition: objectfactory.h:157
ObjectFactoryRegisterXMLNameHelper(const MBXMLUtils::FQN &name) noexcept
Definition: objectfactory.h:162
Definition: objectfactory.h:38
static std::shared_ptr< CreateType > create()
Definition: objectfactory.h:79
static void registerXMLName(const MBXMLUtils::FQN &name)
Definition: objectfactory.h:46
static std::shared_ptr< ContainerType > create(const xercesc::DOMElement *element)
Definition: objectfactory.h:55
static std::shared_ptr< ContainerType > create(const std::shared_ptr< ContainerType > &t)
Definition: objectfactory.h:87