ClassFactory.h
Go to the documentation of this file.
1 /*+-------------------------------------------------------------------------+
2  | MultiVehicle simulator (libmvsim) |
3  | |
4  | Copyright (C) 2014-2023 Jose Luis Blanco Claraco |
5  | Copyright (C) 2017 Borys Tymchenko (Odessa Polytechnic University) |
6  | Distributed under 3-clause BSD License |
7  | See COPYING |
8  +-------------------------------------------------------------------------+ */
9 #pragma once
10 
11 #include <mvsim/basic_types.h>
12 
13 #include <map>
14 #include <memory>
15 #include <stdexcept>
16 #include <string>
17 
18 namespace mvsim
19 {
22 template <class CLASS, typename ARG1 = void, typename ARG2 = int>
24 {
25  public:
26  using Ptr = std::shared_ptr<CLASS>;
27 
28  struct TClassData
29  {
30  CLASS* (*ptr_factory1)(ARG1);
31  CLASS* (*ptr_factory2)(ARG1, ARG2);
32  TClassData() : ptr_factory1(nullptr), ptr_factory2(nullptr) {}
33  };
34 
35  void do_register(const std::string& class_name, const TClassData& data)
36  {
37  classes_[class_name] = data;
38  }
39 
40  Ptr create(const std::string& class_name, ARG1 a1) const
41  {
42  auto it = classes_.find(class_name);
43  if (it == classes_.end())
44  throw std::runtime_error(
45  (std::string("ClassFactory: Unknown class ") + class_name)
46  .c_str());
47  if (!it->second.ptr_factory1)
48  throw std::runtime_error(
49  (std::string(
50  "ClassFactory: factory(1) pointer is nullptr for ") +
51  class_name)
52  .c_str());
53  return Ptr((*it->second.ptr_factory1)(a1));
54  }
55  Ptr create(const std::string& class_name, ARG1 a1, ARG2 a2) const
56  {
57  auto it = classes_.find(class_name);
58  if (it == classes_.end())
59  throw std::runtime_error(
60  (std::string("ClassFactory: Unknown class ") + class_name)
61  .c_str());
62  if (!it->second.ptr_factory2)
63  throw std::runtime_error(
64  (std::string(
65  "ClassFactory: factory(2) pointer is nullptr for ") +
66  class_name)
67  .c_str());
68  return Ptr((*it->second.ptr_factory2)(a1, a2));
69  }
70 
71  private:
72  std::map<std::string, TClassData> classes_;
73 }; // namespace mvsim
74 
75 #define DECLARES_REGISTER_CLASS1(CLASS_NAME, BASE_CLASS, ARG1) \
76  public: \
77  static BASE_CLASS* Create(ARG1 a1) { return new CLASS_NAME(a1); }
78 #define DECLARES_REGISTER_CLASS2(CLASS_NAME, BASE_CLASS, ARG1, ARG2) \
79  public: \
80  static BASE_CLASS* Create(ARG1 a1, ARG2 a2) \
81  { \
82  return new CLASS_NAME(a1, a2); \
83  }
84 
85 #define REGISTER_CLASS1(FACTORY_TYPE, FACTORY_OBJ, TEXTUAL_NAME, CLASS_NAME) \
86  { \
87  FACTORY_TYPE::TClassData data; \
88  data.ptr_factory1 = &CLASS_NAME::Create; \
89  FACTORY_OBJ.do_register(TEXTUAL_NAME, data); \
90  }
91 
92 #define REGISTER_CLASS2(FACTORY_TYPE, FACTORY_OBJ, TEXTUAL_NAME, CLASS_NAME) \
93  { \
94  FACTORY_TYPE::TClassData data; \
95  data.ptr_factory2 = &CLASS_NAME::Create; \
96  FACTORY_OBJ.do_register(TEXTUAL_NAME, data); \
97  }
98 } // namespace mvsim
std::map< std::string, TClassData > classes_
Definition: ClassFactory.h:72
void do_register(const std::string &class_name, const TClassData &data)
Definition: ClassFactory.h:35
std::shared_ptr< CLASS > Ptr
Definition: ClassFactory.h:26
CLASS *(* ptr_factory2)(ARG1, ARG2)
Definition: ClassFactory.h:31
Ptr create(const std::string &class_name, ARG1 a1, ARG2 a2) const
Definition: ClassFactory.h:55
Ptr create(const std::string &class_name, ARG1 a1) const
Definition: ClassFactory.h:40


mvsim
Author(s):
autogenerated on Tue Jul 4 2023 03:08:19