GranOO  3.0
A robust and versatile workbench to build 3D dynamic simulations based on the Discrete Element Method
ObjectFactory.hpp
Go to the documentation of this file.
1 // This file is part of GranOO, a workbench for DEM simulation.
2 //
3 // Author(s) : - Damien Andre IRCER/UNILIM, Limoges France
4 // <damien.andre@unilim.fr>
5 // - Jean-luc Charles Arts et Metiers ParisTech, CNRS, I2M, Bordeaux France
6 // <jean-luc.charles@ensam.eu>
7 // - Jeremie Girardot Arts et Metiers ParisTech, CNRS, I2M, Bordeaux France
8 // <jeremie.girardot@ensam.eu>
9 // - Cedric Hubert LAMIH/UPHF, Valenciennes France
10 // <cedric.hubert@uphf.fr>
11 // - Ivan Iordanoff Arts et Metiers ParisTech, CNRS, I2M, Bordeaux France
12 // <ivan.iordanoff@ensam.eu>
13 //
14 // Copyright (C) 2008-2019 D. Andre, JL. Charles, J. Girardot, C. Hubert, I. Iordanoff
15 //
16 // This program is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 // This program is distributed in the hope that it will be useful,
22 // but WITHOUT ANY WARRANTY; without even the implied warranty of
23 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 // GNU General Public License for more details.
25 //
26 // You should have received a copy of the GNU General Public License
27 // along with this program. If not, see <http://www.gnu.org/licenses/>.
28 
29 
30 #ifndef _GranOO_libCore_ObjectFactory_hpp_
31 #define _GranOO_libCore_ObjectFactory_hpp_
32 
33 #include <iostream>
34 #include <vector>
35 #include <map>
36 #include <functional>
37 
38 #include "GranOO3/Core/Out.hpp"
39 #include "GranOO3/Core/Macro.hpp"
40 #include "GranOO3/Core/Doc.hpp"
41 
42 
43 #define GRANOO_OBJECT_FACTORY(CLASS) \
44  static const bool register_object_factory_; \
45  static CLASS& glob(const std::string& id) \
46  {return Core::XmlObjectManager<CLASS>::get(id);} \
47  virtual void add_glob(const std::string& id) \
48  {Core::XmlObjectManager<CLASS>::add_item(id, this);}
49 
50 #define GRANOO_OBJECT_FACTORY_REGISTER(BASE, CLASS) \
51  const bool CLASS::register_object_factory_ = \
52  GranOO3::Core::ObjectFactoryInterface<BASE, CLASS>::record(CLASS::class_ID(), __FILE__);
53 
54 #define GRANOO_OBJECT_FACTORY_REGISTER_DESC(BASE, CLASS, DESC) \
55  const bool CLASS::register_object_factory_ = \
56  GranOO3::Core::ObjectFactoryInterface<BASE, CLASS>::record(CLASS::class_ID(), __FILE__, DESC);
57 
58 
59 #define GRANOO_OBJECT_FACTORY_REGISTER_T(BASE, CLASS, TPL) \
60  template<> const bool CLASS<TPL>::register_object_factory_ = \
61  GranOO3::Core::ObjectFactoryInterface<BASE, CLASS<TPL> >::record(TPL::class_ID(), __FILE__);
62 
63 #define GRANOO_OBJECT_FACTORY_REGISTER_DESC_T(BASE, CLASS, TPL, DESC) \
64  template<> const bool CLASS<TPL>::register_object_factory_ = \
65  GranOO3::Core::ObjectFactoryInterface<BASE, CLASS<TPL> >::record(TPL::class_ID(), __FILE__, DESC);
66 
67 
68 #define GRANOO_OBJECT_FACTORY_REGISTER_T2(BASE, CLASS, TPL) \
69  template<> const bool CLASS<TPL>::register_object_factory_ = \
70  GranOO3::Core::ObjectFactoryInterface<BASE, CLASS<TPL> >::record(CLASS<TPL>::class_ID(), __FILE__);
71 
72 #define GRANOO_OBJECT_FACTORY_REGISTER_DESC_T2(BASE, CLASS, TPL, DESC) \
73  template<> const bool CLASS<TPL>::register_object_factory_ = \
74  GranOO3::Core::ObjectFactoryInterface<BASE, CLASS<TPL> >::record(CLASS<TPL>::class_ID(), __FILE__, DESC);
75 
76 #define GRANOO_OBJECT_FACTORY_REGISTER_TT(BASE, CLASS, TPL1, TPL2) \
77  template<> const bool CLASS<TPL1, TPL2>::register_object_factory_ = \
78  GranOO3::Core::ObjectFactoryInterface<BASE, CLASS<TPL1,TPL2> >::record(CLASS<TPL1,TPL2>::class_ID(), __FILE__);
79 
80 #define GRANOO_OBJECT_FACTORY_REGISTER_DESC_TT(BASE, CLASS, TPL1, TPL2, DESC) \
81  template<> const bool CLASS<TPL1, TPL2>::register_object_factory_ = \
82  GranOO3::Core::ObjectFactoryInterface<BASE, CLASS<TPL1,TPL2> >::record(CLASS<TPL1,TPL2>::class_ID(), __FILE__, DESC);
83 
84 # define GRANOO_OBJECT_FACTORY_BASE_CLASS_DOC(DOC) \
85  static std::string Doc() {return DOC;}
86 
87 
88 namespace GranOO3
89 {
90  namespace Core
91  {
92 
93 
94 
95 
96 
97  template<class BaseClass>
99  {
100  public:
101  static void record(std::function<BaseClass* ()>, const std::string&,
102  const std::string file = "", const std::string desc = "");
103  static BaseClass* new_object(const std::string&);
104  static std::vector<std::string> get_ID();
105 
106  protected:
108  }
109 
110  virtual ~ObjectFactory() {
111  }
112 
113  public:
114  static std::map<const std::string, std::function<BaseClass * ()> >& get_map();
115  };
116 
117  template<class BaseClass>
118  void
119  ObjectFactory<BaseClass>::record(std::function<BaseClass* ()> f, const std::string& id,
120  const std::string file_name, const std::string desc) {
121  UserAssert(get_map().count(id) == 0,
122  "the id=" + id + " is already used");
123  InternAssert(get_map().count(id)==0);
124 
125  get_map()[id] = f;
126  Doc::add(BaseClass::class_ID(), id, file_name, desc);
127  }
128 
129  template<class BaseClass>
130  BaseClass*
131  ObjectFactory<BaseClass>::new_object(const std::string& id) {
132  if (get_map().count(id)!=1) {
133  granoo::cerr << "cannot find Child class with name \"" << id << "\"" << granoo::endl;
134  granoo::cerr << "please use :";
135  for (auto& it : get_ID())
136  granoo::cerr << it << ",";
138  InternAssert(0);
139  }
140  std::function<BaseClass * ()> f = get_map()[id];
141  BaseClass* instance = f();
142  return instance;
143  }
144 
145  template<class BaseClass>
146  std::map<const std::string, std::function<BaseClass * ()> >&
148  static std::map<const std::string, std::function<BaseClass * ()> > map;
149  return map;
150  }
151 
152  template<class BaseClass>
153  std::vector<std::string>
155  typedef std::map<const std::string, std::function<BaseClass * ()> > MAP;
156 
157  std::vector<std::string> vec;
158  for (typename MAP::iterator it = get_map().begin(); it!=get_map().end(); ++it)
159  vec.push_back(it->first);
160 
161  InternAssert(vec.size() > 0);
162  return vec;
163  }
164 
165  template<class ChildClass>
167  {
168  public:
170 
171  public:
172  void add_object(ChildClass&);
173  ChildClass& get_object(unsigned int = 0);
174  std::vector<ChildClass*>& get_all_object();
175 
176  private:
177  virtual ~ObjectFactoryRegistered();
181 
182  private:
184 
185  private:
186  std::vector<ChildClass*> _registered_object;
187  };
188 
189 
190  template<class ChildClass>
192 
193 
194  template<class ChildClass>
197  if (_me == nullptr)
199  return *_me;
200  }
201 
202  template<class ChildClass>
204  : _registered_object() {
205  InternAssert(_me == nullptr);
206  }
207 
208  template<class ChildClass>
210  InternAssert(0);
211  _me = nullptr;
212  }
213 
214  template<class ChildClass>
215  void
217  _registered_object.push_back(&obj);
218  }
219 
220  template<class ChildClass>
221  ChildClass&
223  InternAssert(rank < _registered_object.size());
224  return *_registered_object[rank];
225  }
226 
227  template<class ChildClass>
228  std::vector<ChildClass*>&
230  return _registered_object;
231  }
232 
233  template<class BaseClass, class ChildClass>
234  class ObjectFactoryInterface : public ObjectFactory<BaseClass>
235  {
236  public:
237  static BaseClass* build();
238  static bool record(const std::string& id, std::string file_name = "", std::string desc = "");
239 
240  protected:
243 
244 
245  };
246 
247  template<class BaseClass, class ChildClass>
249  {
250  static ChildClass* build() {
251  return new ChildClass();
252  }
253 
254  };
255 
256 
257  template<class BaseClass, class ChildClass>
259  : ObjectFactory<BaseClass>() {
260  }
261 
262  template<class BaseClass, class ChildClass>
264  }
265 
266  template<class BaseClass, class ChildClass>
267  BaseClass*
270  ObjectFactoryRegistered<ChildClass>::get().add_object(*ptr);
271  return ptr;
272  }
273 
274  template<class BaseClass, class ChildClass>
275  bool
277  std::string file_name, std::string desc) {
278  std::function<BaseClass * ()> f;
280  ObjectFactory<BaseClass>::record(f, id, file_name, desc);
281  return true;
282  }
283 
284  }
285 }
286 
287 #endif
#define InternAssert(condition)
Definition: Macro.hpp:81
#define UserAssert(condition, message)
Definition: Macro.hpp:54
static bool add(const std::string &section, const std::string &subsection, const std::string &file_name, const std::string &description)
Definition: Doc.cpp:60
Definition: ObjectFactory.hpp:99
static std::vector< std::string > get_ID()
Definition: ObjectFactory.hpp:154
static BaseClass * new_object(const std::string &)
Definition: ObjectFactory.hpp:131
static std::map< const std::string, std::function< BaseClass *()> > & get_map()
Definition: ObjectFactory.hpp:147
ObjectFactory()
Definition: ObjectFactory.hpp:107
static void record(std::function< BaseClass *()>, const std::string &, const std::string file="", const std::string desc="")
Definition: ObjectFactory.hpp:119
virtual ~ObjectFactory()
Definition: ObjectFactory.hpp:110
Definition: ObjectFactory.hpp:235
ObjectFactoryInterface()
Definition: ObjectFactory.hpp:258
static BaseClass * build()
Definition: ObjectFactory.hpp:268
virtual ~ObjectFactoryInterface()
Definition: ObjectFactory.hpp:263
static bool record(const std::string &id, std::string file_name="", std::string desc="")
Definition: ObjectFactory.hpp:276
Definition: ObjectFactory.hpp:167
std::vector< ChildClass * > _registered_object
Definition: ObjectFactory.hpp:186
std::vector< ChildClass * > & get_all_object()
Definition: ObjectFactory.hpp:229
static ObjectFactoryRegistered< ChildClass > * _me
Definition: ObjectFactory.hpp:183
void operator=(const ObjectFactoryRegistered< ChildClass > &)=delete
virtual ~ObjectFactoryRegistered()
Definition: ObjectFactory.hpp:209
void add_object(ChildClass &)
Definition: ObjectFactory.hpp:216
ChildClass & get_object(unsigned int=0)
Definition: ObjectFactory.hpp:222
ObjectFactoryRegistered(const ObjectFactoryRegistered< ChildClass > &)=delete
ObjectFactoryRegistered()
Definition: ObjectFactory.hpp:203
static ObjectFactoryRegistered< ChildClass > & get()
Definition: ObjectFactory.hpp:196
static GranOO3::Core::Out cerr
Definition: Out.hpp:101
static granoo_endl endl
Definition: Out.hpp:106
static const char * desc
Definition: Between2SetOf.cpp:37
Definition: Common.hpp:198
Definition: ObjectFactory.hpp:249
static ChildClass * build()
Definition: ObjectFactory.hpp:250