gramods
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 
20 BEGIN_NAMESPACE_GMCORE;
21 
22 class 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 
203 class 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 
232 public:
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 
427 private:
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 
442 template<class Node, class T>
443 void 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 
457 template<class Node>
458 void 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 
466 template<class Node>
467 void 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 
475 template<class Node>
476 void 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 
504 template<class Node, class T>
505 void 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 
517 END_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