20#ifndef _MBSIM_OBJECTFACTORY_H_
21#define _MBSIM_OBJECTFACTORY_H_
23#include "objectfactory_part.h"
29#include <mbsim/mbsim_event.h>
30#include <xercesc/dom/DOMAttr.hpp>
31#include <mbxmlutilshelper/utils.h>
32#include "fmatvec/atom.h"
33#include <boost/core/demangle.hpp>
44 void add(
const std::string &type,
const std::shared_ptr<MBXMLUtils::DOMEvalException> &ex);
45 const char* what()
const noexcept override;
46 std::vector<std::pair<std::string, std::shared_ptr<MBXMLUtils::DOMEvalException>>> &getExceptionVector();
48 std::vector<std::pair<std::string, std::shared_ptr<MBXMLUtils::DOMEvalException>>> exVec;
49 mutable std::string whatStr;
50 void generateWhat(std::stringstream &str,
const std::string &indent)
const;
75 template<
class ContainerType>
76 static ContainerType*
createAndInit(
const xercesc::DOMElement *element);
78 static void addErrorMsg(
const std::string &msg);
79 static std::string getAndClearErrorMsg();
84 typedef std::pair<const AllocateBase*, const DeallocateBase*> AllocDeallocPair;
85 typedef std::vector<AllocDeallocPair> AllocDeallocVector;
86 typedef AllocDeallocVector::iterator AllocDeallocVectorIt;
87 typedef std::map<MBXMLUtils::FQN, AllocDeallocVector> NameMap;
88 typedef NameMap::iterator NameMapIt;
97 NameMap registeredType;
99 static std::string errorMsg;
102template<
class ContainerType>
105 static_assert(std::is_convertible<ContainerType*, fmatvec::Atom*>::value,
106 "In MBSim::ObjectFactory::create<ContainerType>(...) ContainerType must be derived from fmatvec::Atom.");
109 throw std::runtime_error(
"Internal error: NULL argument specified.");
112 auto nameIt=instance().registeredType.find(fqn);
113 if(nameIt==instance().registeredType.end())
117 for(
auto & allocDeallocIt : nameIt->second) {
119 fmatvec::Atom *ele=(*allocDeallocIt.first)();
121 auto *ret=
dynamic_cast<ContainerType*
>(ele);
124 allErrors.add(boost::core::demangle(
typeid(*ele).name()),
125 std::make_shared<DOMEvalExceptionWrongType>(
126 boost::core::demangle(
typeid(ContainerType).name()), element));
127 (*allocDeallocIt.second)(ele);
131 ret->initializeUsingXML(
const_cast<xercesc::DOMElement*
>(element));
135 allErrors.add(boost::core::demangle(
typeid(*ele).name()), std::make_shared<DOMEvalExceptionStack>(ex));
138 allErrors.add(boost::core::demangle(
typeid(*ele).name()), std::make_shared<MBXMLUtils::DOMEvalException>(ex));
140 catch(std::exception &ex) {
141 allErrors.add(boost::core::demangle(
typeid(*ele).name()),
142 std::make_shared<MBXMLUtils::DOMEvalException>(ex.what(), element));
145 allErrors.add(boost::core::demangle(
typeid(*ele).name()),
146 std::make_shared<MBXMLUtils::DOMEvalException>(
"Unknwon exception", element));
148 (*allocDeallocIt.second)(ele);
155template<
class CreateType>
159 return new CreateType;
165 return typeid(*this)==
typeid(other);
180template<
class CreateType>
190 catch(std::exception &ex) {
191 ObjectFactory::addErrorMsg(ex.what());
194 ObjectFactory::addErrorMsg(
"Unknown error");
203 catch(std::exception &ex) {
204 fprintf(stderr,
"%s\n", ex.what());
207 fprintf(stderr,
"%s\n",
"Unknown error");
219template<
class EnumType>
222 template<
class EV>
friend void registerEnum_internal(
const MBXMLUtils::FQN &name,
const EV& value);
223 template<
class EV>
friend void deregisterEnum_internal(
const MBXMLUtils::FQN &name);
230 registerEnum_internal<EnumType>(fqn, enumVar);
232 catch(std::exception &ex) {
233 ObjectFactory::addErrorMsg(ex.what());
236 ObjectFactory::addErrorMsg(
"Unknown error");
243 deregisterEnum_internal<EnumType>(fqn);
245 catch(std::exception &ex) {
246 fprintf(stderr,
"%s\n", ex.what());
249 fprintf(stderr,
"%s\n",
"Unknown error");
255 auto it=regmap().find(fqn);
256 if(it==regmap().end())
258 return it->second.get();
266 static std::map<MBXMLUtils::FQN, std::reference_wrapper<const EnumType>>& regmap();
270void registerEnum_internal(
const MBXMLUtils::FQN &name,
const EV& value) {
271 EnumFactory<EV>::regmap().insert(std::make_pair(name, std::ref(value)));
276 EnumFactory<EV>::regmap().erase(name);
280std::string fixXMLLocalName(std::string name);
287#define MBSIM_OBJECTFACTORY_REGISTERCLASS(NS, Class) \
288 static MBSim::ObjectFactoryRegisterClassHelper<Class> \
289 BOOST_PP_CAT(objectFactoryRegistrationDummyVariable_, __LINE__)((NS)%MBSim::fixXMLLocalName(#Class));
293#define MBSIM_OBJECTFACTORY_REGISTERCLASS_AND_INSTANTIATE(NS, Class) \
294 template class Class; \
295 static MBSim::ObjectFactoryRegisterClassHelper<Class> \
296 BOOST_PP_CAT(objectFactoryRegistrationDummyVariable_, __LINE__)((NS)%MBSim::fixXMLLocalName(#Class));
300#define MBSIM_OBJECTFACTORY_REGISTERCLASSWITHTEMPLATENAME_AND_INSTANTIATE(NS, Class, TemplateName) \
301 template class Class; \
302 static MBSim::ObjectFactoryRegisterClassHelper<Class> \
303 BOOST_PP_CAT(objectFactoryRegistrationDummyVariable_, __LINE__)((NS)%(MBSim::fixXMLLocalName(#Class)+"_"+#TemplateName));
306#define MBSIM_OBJECTFACTORY_REGISTERENUM(EnumType, NS, enumName) \
307 static MBSim::EnumFactory<EnumType> \
308 BOOST_PP_CAT(objectFactoryRegistrationDummyVariable_, __LINE__)(enumName, (NS)%#enumName);
Definition: objectfactory.h:39
Definition: objectfactory.h:55
Definition: objectfactory.h:220
EnumFactory(const EnumType &enumVar, MBXMLUtils::FQN fqn_)
Definition: objectfactory.h:228
static const EnumType & get(const MBXMLUtils::FQN &fqn, const xercesc::DOMElement *e=nullptr)
Definition: objectfactory.h:254
~EnumFactory()
Definition: objectfactory.h:241
Definition: objectfactory.h:181
~ObjectFactoryRegisterClassHelper()
Definition: objectfactory.h:199
ObjectFactoryRegisterClassHelper(MBXMLUtils::FQN name_) noexcept
Definition: objectfactory.h:186
Definition: objectfactory.h:66
static ContainerType * createAndInit(const xercesc::DOMElement *element)
Definition: objectfactory.h:103
namespace MBSim
Definition: bilateral_constraint.cc:30
Definition: objectfactory_part.h:37
Definition: objectfactory.h:156
fmatvec::Atom * operator()() const override
Implement this function to allocate a new object.
Definition: objectfactory.h:158
bool isEqual(const AllocateBase &other) const override
Definition: objectfactory.h:164
Definition: objectfactory_part.h:49
Definition: objectfactory.h:170
void operator()(fmatvec::Atom *obj) const override
Implement this function to deallocate the object obj.
Definition: objectfactory.h:172