OGLplus  (0.59.0) a C++ wrapper for rendering APIs

basic_manager.hpp
Go to the documentation of this file.
1 #ifndef EAGINE_ECS_BASIC_MANAGER_HPP
9 #define EAGINE_ECS_BASIC_MANAGER_HPP
10 
11 #include "../mp_list.hpp"
12 #include "../type_name.hpp"
13 #include "cmp_storage.hpp"
14 #include "component.hpp"
15 #include "entity_traits.hpp"
16 #include <memory>
17 #include <type_traits>
18 
19 namespace eagine::ecs {
20 //------------------------------------------------------------------------------
21 template <typename Entity>
22 class basic_manager;
23 //------------------------------------------------------------------------------
24 template <typename Entity, typename PL>
25 class component_relation;
26 
27 template <typename Entity, typename... PL>
28 class component_relation<Entity, mp_list<PL...>> {
29 private:
30  basic_manager<Entity>& _m;
31 
32  template <typename F, typename... C, typename... X>
33  static inline auto _apply(
34  basic_manager<Entity>& m,
35  const F& func,
36  mp_list<mp_list<C...>>,
37  X&&... x) {
38  const auto wrap = [&func, &x...](
39  entity_param_t<Entity> e, manipulator<C>&... c) {
40  func(std::forward<X>(x)..., e, c...);
41  };
42  m.for_each(
43  callable_ref<void(entity_param_t<Entity>, manipulator<C> & ...)>{
44  wrap});
45  }
46 
47  template <typename F, typename... C, typename L, typename... Ls, typename... X>
48  static inline auto _apply(
49  basic_manager<Entity>& m,
50  const F& func,
51  mp_list<mp_list<C...>, L, Ls...>,
52  X&&... x) {
53  const auto wrap = [&m, &func, &x...](
54  entity_param_t<Entity> e, manipulator<C>&... c) {
55  _apply(
56  m, func, mp_list<L, Ls...>(), std::forward<X>(x)..., e, c...);
57  };
58  ;
59  m.for_each(
60  callable_ref<void(entity_param_t<Entity>, manipulator<C> & ...)>{
61  wrap});
62  }
63 
64 public:
65  component_relation(basic_manager<Entity>& m)
66  : _m(m) {}
67 
68  template <typename... C>
69  auto cross() -> component_relation<Entity, mp_list<PL..., mp_list<C...>>> {
70  return {_m};
71  }
72 
73  template <typename Func>
74  void for_each(const Func& func) {
75  _apply(_m, func, mp_list<PL...>());
76  }
77 };
78 //------------------------------------------------------------------------------
79 template <typename Entity>
80 class basic_manager {
81 public:
82  using entity_param = entity_param_t<Entity>;
83 
84 private:
85  using _base_cmp_storage_t = base_component_storage<Entity>;
86  using _base_cmp_storage_ptr_t = std::unique_ptr<_base_cmp_storage_t>;
87 
88  component_uid_map<_base_cmp_storage_ptr_t> _cmp_storages{};
89 
90  auto _get_storages(std::false_type) noexcept -> auto& {
91  return _cmp_storages;
92  }
93 
94  auto _get_storages(std::false_type) const noexcept -> auto& {
95  return _cmp_storages;
96  }
97 
98  using _base_rel_storage_t = base_relation_storage<Entity>;
99  using _base_rel_storage_ptr_t = std::unique_ptr<_base_rel_storage_t>;
100 
101  component_uid_map<_base_rel_storage_ptr_t> _rel_storages{};
102 
103  auto _get_storages(std::true_type) noexcept -> auto& {
104  return _rel_storages;
105  }
106 
107  auto _get_storages(std::true_type) const noexcept -> auto& {
108  return _rel_storages;
109  }
110 
111  template <bool IsR>
112  auto _get_storages() noexcept -> auto& {
113  return _get_storages(std::integral_constant<bool, IsR>());
114  }
115 
116  template <bool IsR>
117  auto _get_storages() const noexcept -> auto& {
118  return _get_storages(std::integral_constant<bool, IsR>());
119  }
120 
121  template <typename C>
122  using _bare_t = std::remove_const_t<std::remove_reference_t<C>>;
123 
124  static constexpr auto _count_true() -> unsigned {
125  return 0U;
126  }
127 
128  template <typename T, typename... P>
129  static constexpr auto _count_true(T v, P... p) -> unsigned {
130  return (bool(v) ? 1U : 0U) + _count_true(p...);
131  }
132 
133  template <typename C>
134  static auto _cmp_name_getter() -> std::string (*)() {
135  return &type_name<C>;
136  }
137 
138  template <typename Data, bool IsR>
139  auto _find_storage() -> storage<Entity, Data, IsR>&;
140 
141  template <typename C>
142  auto _find_cmp_storage() -> auto& {
143  return _find_storage<C, false>();
144  }
145 
146  template <typename R>
147  auto _find_rel_storage() -> auto& {
148  return _find_storage<R, true>();
149  }
150 
151  template <bool IsR>
152  void _do_reg_stg_type(
153  std::unique_ptr<base_storage<Entity, IsR>>&&,
154  component_uid_t,
155  std::string (*)());
156 
157  template <bool IsR>
158  void _do_unr_stg_type(component_uid_t, std::string (*)());
159 
160  template <bool IsR>
161  auto _does_know_stg_type(component_uid_t) const -> bool;
162 
163  template <bool IsR, typename Result, typename Func>
164  auto
165  _apply_on_base_stg(Result, const Func&, component_uid_t, std::string (*)())
166  const -> Result;
167 
168  template <typename D, bool IsR, typename Result, typename Func>
169  auto _apply_on_stg(Result, const Func&) const -> Result;
170 
171  template <bool IsR>
172  auto _get_stg_type_caps(component_uid_t, std::string (*)()) const
173  -> storage_caps;
174 
175  auto _does_have_c(entity_param, component_uid_t, std::string (*)()) -> bool;
176 
177  auto _does_have_r(
178  entity_param,
179  entity_param,
180  component_uid_t,
181  std::string (*)()) -> bool;
182 
183  auto _is_hidn(entity_param, component_uid_t, std::string (*)()) -> bool;
184 
185  auto _do_show(entity_param, component_uid_t, std::string (*)()) -> bool;
186 
187  auto _do_hide(entity_param, component_uid_t, std::string (*)()) -> bool;
188 
189  template <typename Component>
190  auto _do_add_c(entity_param, Component&& component) -> bool;
191 
192  template <typename Relation>
193  auto _do_add_r(entity_param, entity_param, Relation&& relation) -> bool;
194 
195  auto
196  _do_add_r(entity_param, entity_param, component_uid_t, std::string (*)())
197  -> bool;
198 
199  auto
200  _do_cpy(entity_param f, entity_param t, component_uid_t, std::string (*)())
201  -> bool;
202 
203  auto
204  _do_swp(entity_param f, entity_param t, component_uid_t, std::string (*)())
205  -> bool;
206 
207  auto _do_rem_c(entity_param, component_uid_t, std::string (*)()) -> bool;
208 
209  auto
210  _do_rem_r(entity_param, entity_param, component_uid_t, std::string (*)())
211  -> bool;
212 
213  template <typename C, typename Func>
214  auto _call_for_single_c(entity_param, const Func&) -> bool;
215 
216  template <typename C, typename Func>
217  void _call_for_each_c(const Func&);
218 
219  template <typename R, typename Func>
220  void _call_for_each_r(const Func&);
221 
222  template <typename... C, typename Func>
223  void _call_for_each_c_m_p(const Func&);
224 
225  template <typename... C, typename Func>
226  void _call_for_each_c_m_r(const Func&);
227 
228  template <typename T, typename C>
229  auto _do_get_c(T C::*, entity_param, T) -> T;
230 
231 public:
232  basic_manager() = default;
233 
234  template <typename Component>
235  auto register_component_type(
236  std::unique_ptr<component_storage<Entity, Component>>&& storage)
237  -> auto& {
238  _do_reg_stg_type<false>(
239  _base_cmp_storage_ptr_t(std::move(storage)),
240  Component::uid(),
241  _cmp_name_getter<Component>());
242  return *this;
243  }
244 
245  template <typename Relation>
246  auto register_relation_type(
247  std::unique_ptr<relation_storage<Entity, Relation>>&& storage) -> auto& {
248  _do_reg_stg_type<true>(
249  _base_rel_storage_ptr_t(std::move(storage)),
250  Relation::uid(),
251  _cmp_name_getter<Relation>());
252  return *this;
253  }
254 
255  template <
256  template <class, class>
257  class Storage,
258  typename Component,
259  typename... P>
260  auto register_component_storage(P&&... p) -> auto& {
261  register_component_type<Component>(
262  std::make_unique<Storage<Entity, Component>>(std::forward<P>(p)...));
263  return *this;
264  }
265 
266  template <
267  template <class, class>
268  class Storage,
269  typename Relation,
270  typename... P>
271  auto register_relation_storage(P&&... p) -> auto& {
272  register_relation_type<Relation>(
273  std::make_unique<Storage<Entity, Relation>>(std::forward<P>(p)...));
274  return *this;
275  }
276 
277  template <typename Component>
278  auto unregister_component_type() -> auto& {
279  _do_unr_stg_type<false>(
280  Component::uid(), _cmp_name_getter<Component>());
281  return *this;
282  }
283 
284  template <typename Relation>
285  auto unregister_relation_type() -> auto& {
286  _do_unr_stg_type<true>(Relation::uid(), _cmp_name_getter<Relation>());
287  return *this;
288  }
289 
290  template <typename Component>
291  auto knows_component_type() const -> bool {
292  return _does_know_stg_type<false>(Component::uid());
293  }
294 
295  template <typename Relation>
296  auto knows_relation_type() const -> bool {
297  return _does_know_stg_type<true>(Relation::uid());
298  }
299 
300  template <typename Component>
301  auto component_storage_caps() const -> storage_caps {
302  return _get_stg_type_caps<false>(
303  Component::uid(), _cmp_name_getter<Component>());
304  }
305 
306  template <typename Relation>
307  auto relation_storage_caps() const -> storage_caps {
308  return _get_stg_type_caps<true>(
309  Relation::uid(), _cmp_name_getter<Relation>());
310  }
311 
312  template <typename Component>
313  auto component_storage_can(storage_cap_bit cap) const -> bool {
314  return _get_stg_type_caps<false>(
315  Component::uid(), _cmp_name_getter<Component>())
316  .has(cap);
317  }
318 
319  template <typename Relation>
320  auto relation_storage_can(storage_cap_bit cap) const -> bool {
321  return _get_stg_type_caps<true>(
322  Relation::uid(), _cmp_name_getter<Relation>())
323  .has(cap);
324  }
325 
326  void forget(entity_param ent);
327 
328  template <typename Component>
329  auto has(entity_param ent) -> bool {
330  return _does_have_c(
331  ent, Component::uid(), _cmp_name_getter<Component>());
332  }
333 
334  template <typename Relation>
335  auto has(entity_param subject, entity_param object) -> bool {
336  return _does_have_r(
337  subject, object, Relation::uid(), _cmp_name_getter<Relation>());
338  }
339 
340  template <typename... Components>
341  auto has_all(entity_param ent) -> bool {
342  return _count_true(_does_have_c(
343  ent, Components::uid(), _cmp_name_getter<Components>())...) ==
344  (sizeof...(Components));
345  }
346 
347  template <typename Relation>
348  auto is(entity_param object, entity_param subject) -> bool {
349  return _does_have_r(
350  subject, object, Relation::uid(), _cmp_name_getter<Relation>());
351  }
352 
353  template <typename Component>
354  auto hidden(entity_param ent) -> bool {
355  return _is_hidn(ent, Component::uid(), _cmp_name_getter<Component>());
356  }
357 
358  template <typename... Components>
359  auto all_hidden(entity_param ent) -> bool {
360  return _count_true(_is_hidn(
361  ent, Components::uid(), _cmp_name_getter<Components>())...) ==
362  (sizeof...(Components));
363  }
364 
365  template <typename... Components>
366  auto show(entity_param ent) -> auto& {
367  (..., _do_show(ent, Components::uid(), _cmp_name_getter<Components>()));
368  return *this;
369  }
370 
371  template <typename... Components>
372  auto hide(entity_param ent) -> auto& {
373  (..., _do_hide(ent, Components::uid(), _cmp_name_getter<Components>()));
374  return *this;
375  }
376 
377  template <typename... Components>
378  auto add(entity_param ent, Components&&... components) -> auto& {
379  (..., _do_add_c(ent, std::move(components)));
380  return *this;
381  }
382 
383  template <typename Relation>
384  auto add_relation(entity_param subject, entity_param object, Relation&& rel)
385  -> auto& {
386  _do_add_r(subject, object, std::forward<Relation>(rel));
387  return *this;
388  }
389 
390  template <typename Relation>
391  auto add_relation(entity_param subject, entity_param object) -> auto& {
392  _do_add_r(
393  subject, object, Relation::uid(), _cmp_name_getter<Relation>());
394  return *this;
395  }
396 
397  template <typename... Components>
398  auto copy(entity_param from, entity_param to) -> auto& {
399  (...,
400  _do_cpy(from, to, Components::uid(), _cmp_name_getter<Components>()));
401  return *this;
402  }
403 
404  template <typename... Components>
405  auto swap(entity_param e1, entity_param e2) -> auto& {
406  (...,
407  _do_swp(e1, e2, Components::uid(), _cmp_name_getter<Components>()));
408  return *this;
409  }
410 
411  template <typename... Components>
412  auto remove(entity_param ent) -> auto& {
413  (...,
414  _do_rem_c(ent, Components::uid(), _cmp_name_getter<Components>()));
415  return *this;
416  }
417 
418  template <typename Relation>
419  auto remove_relation(entity_param subject, entity_param object) -> auto& {
420  _do_rem_r(
421  subject, object, Relation::uid(), _cmp_name_getter<Relation>());
422  return *this;
423  }
424 
425  template <typename T, typename Component>
426  auto get(T Component::*mvp, entity_param ent, T res = T()) -> T {
427  return _do_get_c(mvp, ent, res);
428  }
429 
430  template <typename Component>
431  auto for_single(
432  entity_param ent,
433  const callable_ref<void(entity_param, manipulator<const Component>&)>&
434  func) -> auto& {
435  _call_for_single_c<Component>(ent, func);
436  return *this;
437  }
438 
439  template <typename Component>
440  auto for_single(
441  const callable_ref<void(entity_param, manipulator<Component>&)>& func,
442  entity_param ent) -> auto& {
443  _call_for_single_c<Component>(func, ent);
444  return *this;
445  }
446 
447  template <typename Component>
448  auto for_each(
449  const callable_ref<void(entity_param, manipulator<const Component>&)>&
450  func) -> auto& {
451  _call_for_each_c<Component>(func);
452  return *this;
453  }
454 
455  template <typename Component>
456  auto for_each(
457  const callable_ref<void(entity_param, manipulator<Component>&)>& func)
458  -> auto& {
459  _call_for_each_c<Component>(func);
460  return *this;
461  }
462 
463  template <typename Relation>
464  auto for_each(const callable_ref<void(entity_param, entity_param)>& func)
465  -> auto& {
466  _call_for_each_r<Relation>(func);
467  return *this;
468  }
469 
470  template <typename Relation>
471  auto for_each(
472  const callable_ref<
473  void(entity_param, entity_param, manipulator<const Relation>&)>& func)
474  -> auto& {
475  _call_for_each_r<Relation>(func);
476  return *this;
477  }
478 
479  template <typename Relation>
480  auto
481  for_each(const callable_ref<
482  void(entity_param, entity_param, manipulator<Relation>&)>& func)
483  -> auto& {
484  _call_for_each_r<Relation>(func);
485  return *this;
486  }
487 
488  template <typename... Components>
489  auto for_each_opt(
490  const callable_ref<void(entity_param, manipulator<Components>&...)>& func)
491  -> auto& {
492  _call_for_each_c_m_p<Components...>(func);
493  return *this;
494  }
495 
496  template <typename... Components, typename Func>
497  auto for_each_with_opt(const Func& func) -> auto& {
498  callable_ref<void(entity_param, manipulator<Components> & ...)> wrap(
499  func);
500  return for_each_opt<Components...>(wrap);
501  }
502 
503  template <typename... Components>
504  auto for_each(
505  const callable_ref<void(entity_param, manipulator<Components>&...)>& func)
506  -> std::enable_if_t<(sizeof...(Components) > 1), basic_manager&> {
507  _call_for_each_c_m_r<Components...>(func);
508  return *this;
509  }
510 
511  template <typename... Components, typename Func>
512  auto for_each_with(const Func& func) -> auto& {
513  return for_each<Components...>(
514  callable_ref<void(entity_param, manipulator<Components> & ...)>{
515  construct_from, func});
516  }
517 
518  template <typename... Components>
519  auto select()
520  -> component_relation<Entity, mp_list<mp_list<Components...>>> {
521  return {*this};
522  }
523 };
524 //------------------------------------------------------------------------------
525 } // namespace eagine::ecs
526 
527 #include <eagine/ecs/basic_manager.inl>
528 
529 #endif // EAGINE_ECS_BASIC_MANAGER_HPP
basic_callable_ref< Sig, is_noexcept_function_v< Sig > > callable_ref
Alias for callable object references.
Definition: callable_ref.hpp:191
constexpr const construct_from_t construct_from
The construct-from tag-dispatch constant.
Definition: selector.hpp:47
static auto cross(const vector< T, 3, V > &a, const vector< T, 3, V > &b) noexcept
3D vector cross product.
Definition: vector.hpp:326

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).