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,
bool &normalErrorFound)
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));
143 allErrors.add(boost::core::demangle(
typeid(*ele).name()),
144 std::make_shared<MBXMLUtils::DOMEvalException>(ex.getErrorMessage(), element));
146 catch(std::exception &ex) {
147 allErrors.add(boost::core::demangle(
typeid(*ele).name()),
148 std::make_shared<MBXMLUtils::DOMEvalException>(ex.what(), element));
151 allErrors.add(boost::core::demangle(
typeid(*ele).name()),
152 std::make_shared<MBXMLUtils::DOMEvalException>(
"Unknwon exception", element));
154 (*allocDeallocIt.second)(ele);
161template<
class CreateType>
165 return new CreateType;
171 return typeid(*this)==
typeid(other);
186template<
class CreateType>
196 catch(std::exception &ex) {
197 ObjectFactory::addErrorMsg(ex.what());
200 ObjectFactory::addErrorMsg(
"Unknown error");
209 catch(std::exception &ex) {
210 fprintf(stderr,
"%s\n", ex.what());
213 fprintf(stderr,
"%s\n",
"Unknown error");
225template<
class EnumType>
228 template<
class EV>
friend void registerEnum_internal(
const MBXMLUtils::FQN &name,
const EV& value);
229 template<
class EV>
friend void deregisterEnum_internal(
const MBXMLUtils::FQN &name);
236 registerEnum_internal<EnumType>(fqn, enumVar);
238 catch(std::exception &ex) {
239 ObjectFactory::addErrorMsg(ex.what());
242 ObjectFactory::addErrorMsg(
"Unknown error");
249 deregisterEnum_internal<EnumType>(fqn);
251 catch(std::exception &ex) {
252 fprintf(stderr,
"%s\n", ex.what());
255 fprintf(stderr,
"%s\n",
"Unknown error");
261 auto it=regmap().find(fqn);
262 if(it==regmap().end())
264 return it->second.get();
272 static std::map<MBXMLUtils::FQN, std::reference_wrapper<const EnumType>>& regmap();
276void registerEnum_internal(
const MBXMLUtils::FQN &name,
const EV& value) {
277 EnumFactory<EV>::regmap().insert(std::make_pair(name, std::ref(value)));
282 EnumFactory<EV>::regmap().erase(name);
286std::string fixXMLLocalName(std::string name);
293#define MBSIM_OBJECTFACTORY_REGISTERCLASS(NS, Class) \
294 static MBSim::ObjectFactoryRegisterClassHelper<Class> \
295 BOOST_PP_CAT(objectFactoryRegistrationDummyVariable_, __LINE__)((NS)%MBSim::fixXMLLocalName(#Class));
299#define MBSIM_OBJECTFACTORY_REGISTERCLASS_AND_INSTANTIATE(NS, Class) \
300 template class Class; \
301 static MBSim::ObjectFactoryRegisterClassHelper<Class> \
302 BOOST_PP_CAT(objectFactoryRegistrationDummyVariable_, __LINE__)((NS)%MBSim::fixXMLLocalName(#Class));
306#define MBSIM_OBJECTFACTORY_REGISTERCLASSWITHTEMPLATENAME_AND_INSTANTIATE(NS, Class, TemplateName) \
307 template class Class; \
308 static MBSim::ObjectFactoryRegisterClassHelper<Class> \
309 BOOST_PP_CAT(objectFactoryRegistrationDummyVariable_, __LINE__)((NS)%(MBSim::fixXMLLocalName(#Class)+"_"+#TemplateName));
312#define MBSIM_OBJECTFACTORY_REGISTERENUM(EnumType, NS, enumName) \
313 static MBSim::EnumFactory<EnumType> \
314 BOOST_PP_CAT(objectFactoryRegistrationDummyVariable_, __LINE__)(enumName, (NS)%#enumName);
Definition: objectfactory.h:39
Definition: objectfactory.h:55
Definition: objectfactory.h:226
EnumFactory(const EnumType &enumVar, MBXMLUtils::FQN fqn_)
Definition: objectfactory.h:234
static const EnumType & get(const MBXMLUtils::FQN &fqn, const xercesc::DOMElement *e=nullptr)
Definition: objectfactory.h:260
~EnumFactory()
Definition: objectfactory.h:247
basic error class for mbsim
Definition: mbsim_event.h:39
Definition: objectfactory.h:187
~ObjectFactoryRegisterClassHelper()
Definition: objectfactory.h:205
ObjectFactoryRegisterClassHelper(MBXMLUtils::FQN name_) noexcept
Definition: objectfactory.h:192
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:162
fmatvec::Atom * operator()() const override
Implement this function to allocate a new object.
Definition: objectfactory.h:164
bool isEqual(const AllocateBase &other) const override
Definition: objectfactory.h:170
Definition: objectfactory_part.h:49
Definition: objectfactory.h:176
void operator()(fmatvec::Atom *obj) const override
Implement this function to deallocate the object obj.
Definition: objectfactory.h:178