gramods
Loading...
Searching...
No Matches
OFactory.hh
1
2#ifndef GRAMODS_CORE_OFACTORYNODE
3#define GRAMODS_CORE_OFACTORYNODE
4
5#include <gmCore/config.hh>
6#include <gmCore/Object.hh>
7#include <gmCore/Stringify.hh>
8#include <gmCore/InvalidArgument.hh>
9
10#include <map>
11#include <string>
12#include <filesystem>
13#include <iomanip>
14#include <typeinfo>
15#include <iostream>
16#include <sstream>
17
18#include <assert.h>
19
20BEGIN_NAMESPACE_GMCORE;
21
22class Configuration;
23
30#define GM_OFI_DECLARE \
31 static gramods::gmCore::OFactory::OFactoryInformation _gm_ofi;//
32
42#define GM_OFI_DEFINE(NAME) \
43 gramods::gmCore::OFactory::OFactoryInformation \
44 NAME::_gm_ofi(#NAME, new gramods::gmCore::OFactory::ObjectCreator<NAME>());
45
54#define GM_OFI_DEFINE_ABSTRACT(NAME) \
55 gramods::gmCore::OFactory::OFactoryInformation \
56 NAME::_gm_ofi(#NAME, nullptr);
57
69#define GM_OFI_DEFINE_SUB(NAME, BASE) \
70 gramods::gmCore::OFactory::OFactoryInformation \
71 NAME::_gm_ofi(#NAME, new gramods::gmCore::OFactory::ObjectCreator<NAME>(), &BASE::_gm_ofi);
72
83#define GM_OFI_DEFINE_ABSTRACT_SUB(NAME, BASE) \
84 gramods::gmCore::OFactory::OFactoryInformation \
85 NAME::_gm_ofi(#NAME, nullptr, &BASE::_gm_ofi);
86
106#define GM_OFI_PARAM(CLASS, NAME, TYPE, FUNC) \
107 gramods::gmCore::OFactory::ParamSetterInsert gm_ofi_##CLASS##_param_##NAME( \
108 &CLASS::_gm_ofi, \
109 #NAME, \
110 new gramods::gmCore::OFactory::ParamSetter<CLASS, TYPE>(&FUNC));
111
131#define GM_OFI_PARAM2(CLASS, NAME, TYPE, FUNC) \
132 gramods::gmCore::OFactory::ParamSetterInsert gm_ofi_##CLASS##_param_##NAME( \
133 &CLASS::_gm_ofi, \
134 #NAME, \
135 new gramods::gmCore::OFactory::ParamSetter<CLASS, TYPE>(&CLASS::FUNC));
136
156#define GM_OFI_POINTER(CLASS, NAME, TYPE, FUNC) \
157 gramods::gmCore::OFactory::PointerSetterInsert gm_ofi_##CLASS##_pointer_##NAME \
158 (&CLASS::_gm_ofi, #NAME, \
159 new gramods::gmCore::OFactory::PointerSetter<CLASS, TYPE>(&FUNC));
160
180#define GM_OFI_POINTER2(CLASS, NAME, TYPE, FUNC) \
181 gramods::gmCore::OFactory::PointerSetterInsert gm_ofi_##CLASS##_pointer_##NAME \
182 (&CLASS::_gm_ofi, #NAME, \
183 new gramods::gmCore::OFactory::PointerSetter<CLASS, TYPE>(&CLASS::FUNC));
184
203class OFactory {
204
210 struct ParamSetterBase {
211 virtual void setValueFromString(Object *n, std::string s) const = 0;
212 };
213
219 struct PointerSetterBase {
220 virtual void setPointer(Object *n, std::shared_ptr<Object> o) const = 0;
221 };
222
226 struct ObjectCreatorBase {
229 virtual Object * create() const = 0;
230 };
231
232public:
233
241
248 OFactoryInformation(std::string name,
249 ObjectCreatorBase *creator,
250 OFactoryInformation *base = nullptr);
251
256
261 Object * create() const;
262
266 void registerParamSetter(std::string name, ParamSetterBase *setter);
267
271 void registerPointerSetter(std::string name, PointerSetterBase *setter);
272
280 bool setParamValueFromString(Object *node, std::string name, std::string value) const;
281
288 bool setPointerValue(Object *node, std::string name, std::shared_ptr<Object> ptr) const;
289
290 private:
291
292 const std::string name;
293 const std::unique_ptr<const ObjectCreatorBase> creator;
294 const OFactoryInformation *const base;
295
296 std::map<std::string, std::unique_ptr<ParamSetterBase>> param_setters;
297 std::map<std::string, std::unique_ptr<PointerSetterBase>> pointer_setters;
298 };
299
305
311 std::string name,
312 ParamSetterBase *setter) {
313 ofi->registerParamSetter(name, setter);
314 }
315 };
316
322
328 std::string name,
329 PointerSetterBase *setter) {
330 ofi->registerPointerSetter(name, setter);
331 }
332 };
333
342 template<class Node, class T>
343 struct ParamSetter : ParamSetterBase {
344
345 ParamSetter(void (Node::*m)(T val))
346 : method(m) {}
347
348 void setValueFromString(Object *n, std::string s) const;
349
350 void (Node::*method)(T val);
351 };
352
357 template<class Node>
358 struct ParamSetter<Node, std::string> : ParamSetterBase {
359
360 ParamSetter(void (Node::*m)(std::string val))
361 : method(m) {}
362
363 void setValueFromString(Object *n, std::string s) const;
364
365 void (Node::*method)(std::string val);
366 };
367
372 template<class Node>
373 struct ParamSetter<Node, std::filesystem::path> : ParamSetterBase {
374
375 ParamSetter(void (Node::*m)(std::filesystem::path val))
376 : method(m) {}
377
378 void setValueFromString(Object *n, std::string s) const;
379
380 void (Node::*method)(std::filesystem::path val);
381 };
382
387 template<class Node>
388 struct ParamSetter<Node, bool> : ParamSetterBase {
389
390 ParamSetter(void (Node::*m)(bool val))
391 : method(m) {}
392
393 void setValueFromString(Object *n, std::string s) const;
394
395 void (Node::*method)(bool val);
396 };
397
402 template<class Node, class T>
403 struct PointerSetter : PointerSetterBase {
404
405 PointerSetter(void (Node::*m)(std::shared_ptr<T> ptr))
406 : method(m) {}
407
408 void setPointer(Object *n, std::shared_ptr<Object> ptr) const;
409
410 void (Node::*method)(std::shared_ptr<T> ptr);
411 };
412
416 template<class Node>
417 struct ObjectCreator : ObjectCreatorBase {
420 Object *create() const { return new Node; }
421 };
422
425 static Object * createObject(std::string name);
426
427private:
428
429 static std::map<std::string, OFactoryInformation *> &getOFIByNameMap();
430
431 static void registerOFI(std::string name, OFactoryInformation *info);
432 static void unregisterOFI(std::string name);
433 static OFactoryInformation* getOFI(std::string name);
434
435
436 friend struct OFactoryInformation;
437
438 friend class Configuration;
439};
440
441
442template<class Node, class T>
443void OFactory::ParamSetter<Node, T>::setValueFromString
444(Object *n, std::string s) const {
445 assert(dynamic_cast<Node*>(n) != nullptr);
446 Node *node = static_cast<Node*>(n);
447 std::stringstream ss(s);
448 T val;
449 ss >> std::setbase(0) >> val;
450
451 if (!ss)
452 throw gmCore::InvalidArgument(GM_STR("cannot parse '" << s << "' as type " << typeid(T).name()));
453
454 (node->*method)(val);
455}
456
457template<class Node>
458void OFactory::ParamSetter<Node, std::string>::setValueFromString
459(Object *n, std::string s) const {
460 assert(dynamic_cast<Node*>(n) != nullptr);
461 Node *node = static_cast<Node*>(n);
462
463 (node->*method)(s);
464}
465
466template<class Node>
467void OFactory::ParamSetter<Node, std::filesystem::path>::setValueFromString
468(Object *n, std::string s) const {
469 assert(dynamic_cast<Node*>(n) != nullptr);
470 Node *node = static_cast<Node*>(n);
471
472 (node->*method)(s);
473}
474
475template<class Node>
476void OFactory::ParamSetter<Node, bool>::setValueFromString
477(Object *n, std::string s) const {
478 assert(dynamic_cast<Node*>(n) != nullptr);
479 Node *node = static_cast<Node*>(n);
480
481 if (s == "true" ||
482 s == "True" ||
483 s == "TRUE" ||
484 s == "on" ||
485 s == "On" ||
486 s == "ON" ||
487 s == "1") {
488 (node->*method)(true);
489 } else if (s == "false" ||
490 s == "False" ||
491 s == "FALSE" ||
492 s == "off" ||
493 s == "Off" ||
494 s == "OFF" ||
495 s == "0") {
496 (node->*method)(false);
497 } else {
498 std::stringstream ss;
499 ss << "Cannot convert " << s << " to boolean";
500 throw gmCore::InvalidArgument(ss.str());
501 }
502}
503
504template<class Node, class T>
505void OFactory::PointerSetter<Node, T>::setPointer
506(Object *n, std::shared_ptr<Object> ptr) const {
507 assert(dynamic_cast<Node*>(n) != nullptr);
508 Node *node = static_cast<Node*>(n);
509 std::shared_ptr<T> _ptr = std::dynamic_pointer_cast<T>(ptr);
510
511 if (!_ptr)
512 throw gmCore::InvalidArgument(GM_STR("cannot cast " << typeid(ptr).name() << " to type " << typeid(T).name()));
513
514 (node->*method)(_ptr);
515}
516
517END_NAMESPACE_GMCORE;
518
519#endif
A wrapper for the XML parser that also creates and configures the system objects and holds temporary ...
Definition Configuration.hh:41
This is an object factory for classes with Object as base type, instantiating them by name and callin...
Definition OFactory.hh:203
Base type for objects in the Gramods package for standardized handling of construction,...
Definition Object.hh:42
Standard exception for invalid arguments in a call to a function or object.
Definition InvalidArgument.hh:15
Registrator of information required by the object factory.
Definition OFactory.hh:240
void registerParamSetter(std::string name, ParamSetterBase *setter)
Registers a parameter setter with a specific attribute name.
Definition OFactory.cpp:70
void registerPointerSetter(std::string name, PointerSetterBase *setter)
Registers a pointer setter with a specific attribute name.
Definition OFactory.cpp:76
Actual object creator, templated for the type to instantiate.
Definition OFactory.hh:417
Object * create() const
Creates and returns an instance of the template argument class.
Definition OFactory.hh:420
Convenience class that registers a parameter setter upon instantiation.
Definition OFactory.hh:304
ParamSetterInsert(OFactoryInformation *ofi, std::string name, ParamSetterBase *setter)
Constructor registering the specified parameter setter with the specified OFI, associating it with th...
Definition OFactory.hh:310
General parameter setter, templated to determine the type to set value for.
Definition OFactory.hh:343
Convenience class that registers a pointer setter upon instantiation.
Definition OFactory.hh:321
PointerSetterInsert(OFactoryInformation *ofi, std::string name, PointerSetterBase *setter)
Constructor registering the specified pointer setter with the specified OFI, associating it with the ...
Definition OFactory.hh:327
General pointer setter, templated to determine the type of the pointer.
Definition OFactory.hh:403