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

std_map.hpp
Go to the documentation of this file.
1 #ifndef EAGINE_ECS_STORAGE_STD_MAP_HPP
9 #define EAGINE_ECS_STORAGE_STD_MAP_HPP
10 
11 #include "../../assert.hpp"
12 #include "../cmp_storage.hpp"
13 #include "../rel_storage.hpp"
14 #include <map>
15 #include <set>
16 
17 namespace eagine {
18 namespace ecs {
19 
20 template <typename Entity, typename Component>
21 class std_map_cmp_storage;
22 
23 template <typename Entity, typename Component>
24 class std_map_cmp_storage_iterator
25  : public component_storage_iterator_intf<Entity> {
26 private:
27  using _map_t = typename std::map<Entity, Component>;
28  using _iter_t = typename _map_t::iterator;
29  _map_t* _map{nullptr};
30  _iter_t _i;
31 
32  friend class std_map_cmp_storage<Entity, Component>;
33 
34 public:
35  std_map_cmp_storage_iterator(_map_t& m) noexcept
36  : _map{&m}
37  , _i{m.begin()} {
38  EAGINE_ASSERT(_map);
39  }
40 
41  void reset() override {
42  EAGINE_ASSERT(_map);
43  _i = _map->begin();
44  }
45 
46  auto done() -> bool override {
47  EAGINE_ASSERT(_map);
48  return _i == _map->end();
49  }
50 
51  void next() override {
52  EAGINE_ASSERT(!done());
53  ++_i;
54  }
55 
56  auto find(Entity e) -> bool override {
57  if(done()) {
58  return false;
59  }
60  if(e == _i->first) {
61  return true;
62  }
63  if(e < _i->first) {
64  return false;
65  }
66 
67  while(++_i != _map->end()) {
68  if(_i->first == e) {
69  return true;
70  }
71  }
72  return false;
73  }
74 
75  auto current() -> Entity override {
76  return _i->first;
77  }
78 };
79 
80 template <typename Entity, typename Component>
81 class std_map_cmp_storage : public component_storage<Entity, Component> {
82 private:
83  std::map<Entity, Component> _components{};
84  std::set<Entity> _hidden{};
85 
86  using _map_iter_t = std_map_cmp_storage_iterator<Entity, Component>;
87 
88  auto _iter_cast(component_storage_iterator<Entity>& i) noexcept -> auto& {
89  EAGINE_ASSERT(dynamic_cast<_map_iter_t*>(i.ptr()));
90  return *static_cast<_map_iter_t*>(i.ptr());
91  }
92 
93  auto _iter_entity(component_storage_iterator<Entity>& i) noexcept {
94  return _iter_cast(i)._i->first;
95  }
96 
97  auto _remove(typename std::map<Entity, Component>::iterator p) {
98  EAGINE_ASSERT(p != _components.end());
99  _hidden.erase(p->first);
100  return _components.erase(p);
101  }
102 
103 public:
104  using entity_param = entity_param_t<Entity>;
105  using iterator_t = component_storage_iterator<Entity>;
106 
107  auto capabilities() -> storage_caps override {
108  return storage_caps{
109  storage_cap_bit::hide | storage_cap_bit::remove |
110  storage_cap_bit::store | storage_cap_bit::modify};
111  }
112 
113  auto new_iterator() -> iterator_t override {
114  return iterator_t(new _map_iter_t(_components));
115  }
116 
117  void delete_iterator(iterator_t&& i) override {
118  delete i.release();
119  }
120 
121  auto has(entity_param e) -> bool override {
122  return _components.find(e) != _components.end();
123  }
124 
125  auto is_hidden(entity_param e) -> bool override {
126  return _hidden.find(e) != _hidden.end();
127  }
128 
129  auto is_hidden(iterator_t& i) -> bool override {
130  EAGINE_ASSERT(!i.done());
131  return is_hidden(_iter_entity(i));
132  }
133 
134  auto hide(entity_param e) -> bool override {
135  if(has(e)) {
136  _hidden.insert(e);
137  return true;
138  }
139  return false;
140  }
141 
142  void hide(iterator_t& i) override {
143  EAGINE_ASSERT(!i.done());
144  _hidden.insert(_iter_entity(i));
145  }
146 
147  auto show(entity_param e) -> bool override {
148  return _hidden.erase(e) > 0;
149  }
150 
151  auto show(iterator_t& i) -> bool override {
152  return _hidden.erase(_iter_entity(i)) > 0;
153  }
154 
155  auto copy(entity_param ef, entity_param et) -> bool override {
156  if(is_hidden(ef)) {
157  return false;
158  }
159  auto pf = _components.find(ef);
160  if(pf == _components.end()) {
161  return false;
162  }
163  return store(et, Component(pf->second));
164  }
165 
166  auto swap(entity_param ea, entity_param eb) -> bool override {
167  auto pa = _components.find(ea);
168  auto pb = _components.find(eb);
169  bool ha = is_hidden(ea);
170  bool hb = is_hidden(eb);
171 
172  if(pa != _components.end() && pb != _components.end()) {
173  using std::swap;
174  swap(pa->second, pb->second);
175  if(ha && !hb) {
176  show(ea);
177  }
178  if(hb && !ha) {
179  show(eb);
180  }
181  } else if(pa != _components.end()) {
182  store(eb, std::move(pa->second));
183  remove(ea);
184  if(ha) {
185  hide(eb);
186  }
187  } else if(pb != _components.end()) {
188  store(ea, std::move(pb->second));
189  remove(eb);
190  if(hb) {
191  hide(ea);
192  }
193  }
194  return true;
195  }
196 
197  auto remove(entity_param e) -> bool override {
198  _hidden.erase(e);
199  return _components.erase(e) > 0;
200  }
201 
202  void remove(iterator_t& i) override {
203  EAGINE_ASSERT(!i.done());
204  _hidden.erase(_iter_entity(i));
205  _iter_cast(i)._i = _components.erase(_iter_cast(i)._i);
206  }
207 
208  auto store(entity_param e, Component&& c) -> bool override {
209  _hidden.erase(e);
210  _components.emplace(e, std::move(c));
211  return true;
212  }
213 
214  auto store(iterator_t& i, entity_param e, Component&& c) -> bool override {
215  _hidden.erase(e);
216  auto& p = _iter_cast(i)._i;
217  p = _components.emplace_hint(p, e, std::move(c));
218  return true;
219  }
220 
221  void for_single(
222  callable_ref<void(entity_param, manipulator<const Component>&)> func,
223  entity_param e) override {
224  auto p = _components.find(e);
225  if(p != _components.end()) {
226  if(!is_hidden(e)) {
227  concrete_manipulator<const Component> m(
228  p->second, true /*can_remove*/
229  );
230  func(p->first, m);
231  if(m.remove_requested()) {
232  _remove(p);
233  }
234  }
235  }
236  }
237 
238  void for_single(
239  callable_ref<void(entity_param, manipulator<const Component>&)> func,
240  iterator_t& i) override {
241  EAGINE_ASSERT(!i.done());
242  auto& p = _iter_cast(i)._i;
243  EAGINE_ASSERT(p != _components.end());
244  if(!is_hidden(p->first)) {
245  concrete_manipulator<const Component> m(
246  p->second, true /*can_remove*/
247  );
248  func(p->first, m);
249  if(m.remove_requested()) {
250  p = _remove(p);
251  }
252  }
253  }
254 
255  void for_single(
256  callable_ref<void(entity_param, manipulator<Component>&)> func,
257  entity_param e) override {
258  auto p = _components.find(e);
259  if(p != _components.end()) {
260  if(!is_hidden(e)) {
261  // TODO: modify notification
262  concrete_manipulator<Component> m(
263  p->second, true /*can_remove*/
264  );
265  func(p->first, m);
266  if(m.remove_requested()) {
267  _remove(p);
268  }
269  }
270  }
271  }
272 
273  void for_single(
274  callable_ref<void(entity_param, manipulator<Component>&)> func,
275  iterator_t& i) override {
276  EAGINE_ASSERT(!i.done());
277  auto& p = _iter_cast(i)._i;
278  EAGINE_ASSERT(p != _components.end());
279  if(!is_hidden(p->first)) {
280  // TODO: modify notification
281  concrete_manipulator<Component> m(
282  p->second, true /*can_remove*/
283  );
284  func(p->first, m);
285  if(m.remove_requested()) {
286  p = _remove(p);
287  }
288  }
289  }
290 
291  void for_each(
292  callable_ref<void(entity_param, manipulator<const Component>&)> func)
293  override {
294  concrete_manipulator<const Component> m(true /*can_remove*/);
295  auto p = _components.begin();
296  while(p != _components.end()) {
297  if(!is_hidden(p->first)) {
298  m.reset(p->second);
299  func(p->first, m);
300  if(m.remove_requested()) {
301  p = _remove(p);
302  } else {
303  ++p;
304  }
305  } else {
306  ++p;
307  }
308  }
309  }
310 
311  void for_each(
312  callable_ref<void(entity_param, manipulator<Component>&)> func) override {
313  concrete_manipulator<Component> m(true /*can_remove*/);
314  auto p = _components.begin();
315  while(p != _components.end()) {
316  if(!is_hidden(p->first)) {
317  // TODO: modify notification
318  m.reset(p->second);
319  func(p->first, m);
320  if(m.remove_requested()) {
321  p = _remove(p);
322  } else {
323  ++p;
324  }
325  } else {
326  ++p;
327  }
328  }
329  }
330 };
331 
332 template <typename Entity, typename Relation>
333 class std_map_rel_storage;
334 
335 template <typename Entity, typename Relation>
336 class std_map_rel_storage_iterator
337  : public relation_storage_iterator_intf<Entity> {
338 private:
339  using _pair_t = std::pair<Entity, Entity>;
340  using _map_t = typename std::map<_pair_t, Relation>;
341  using _iter_t = typename _map_t::iterator;
342  _map_t* _map{nullptr};
343  _iter_t _i;
344 
345  friend class std_map_rel_storage<Entity, Relation>;
346 
347 public:
348  std_map_rel_storage_iterator(_map_t& m) noexcept
349  : _map{&m}
350  , _i(m.begin()) {
351  EAGINE_ASSERT(_map);
352  }
353 
354  void reset() override {
355  EAGINE_ASSERT(_map);
356  _i = _map->begin();
357  }
358 
359  auto done() -> bool override {
360  EAGINE_ASSERT(_map);
361  return _i == _map->end();
362  }
363 
364  void next() override {
365  EAGINE_ASSERT(!done());
366  ++_i;
367  }
368 
369  auto subject() -> Entity override {
370  return _i->first.first;
371  }
372 
373  auto object() -> Entity override {
374  return _i->first.second;
375  }
376 };
377 
378 template <typename Entity, typename Relation>
379 class std_map_rel_storage : public relation_storage<Entity, Relation> {
380 private:
381  using _pair_t = std::pair<Entity, Entity>;
382  std::map<_pair_t, Relation> _relations;
383 
384  using _map_iter_t = std_map_rel_storage_iterator<Entity, Relation>;
385 
386  auto _iter_cast(relation_storage_iterator<Entity>& i) noexcept -> auto& {
387  EAGINE_ASSERT(dynamic_cast<_map_iter_t*>(i.ptr()) != nullptr);
388  return *static_cast<_map_iter_t*>(i.ptr());
389  }
390 
391  auto _remove(typename std::map<_pair_t, Relation>::iterator p) {
392  EAGINE_ASSERT(p != _relations.end());
393  return _relations.erase(p);
394  }
395 
396 public:
397  using entity_param = entity_param_t<Entity>;
398  using iterator_t = relation_storage_iterator<Entity>;
399 
400  auto capabilities() -> storage_caps override {
401  return storage_caps{
402  storage_cap_bit::remove | storage_cap_bit::store |
403  storage_cap_bit::modify};
404  }
405 
406  auto new_iterator() -> iterator_t override {
407  return iterator_t(new _map_iter_t(_relations));
408  }
409 
410  void delete_iterator(iterator_t&& i) override {
411  delete i.release();
412  }
413 
414  auto has(entity_param s, entity_param o) -> bool override {
415  return _relations.find(_pair_t(s, o)) != _relations.end();
416  }
417 
418  auto store(entity_param s, entity_param o) -> bool override {
419  _relations.emplace(_pair_t(s, o), Relation());
420  return true;
421  }
422 
423  auto store(entity_param s, entity_param o, Relation&& r) -> bool override {
424  _relations.emplace(_pair_t(s, o), std::move(r));
425  return true;
426  }
427 
428  auto remove(entity_param s, entity_param o) -> bool override {
429  return _relations.erase(_pair_t(s, o)) > 0;
430  }
431 
432  void remove(iterator_t& i) override {
433  EAGINE_ASSERT(!i.done());
434  _iter_cast(i)._i = _relations.erase(_iter_cast(i)._i);
435  }
436 
437  void for_single(
438  callable_ref<
439  void(entity_param, entity_param, manipulator<const Relation>&)> func,
440  entity_param subject,
441  entity_param object) override {
442  auto po = _relations.find(_pair_t(subject, object));
443  if(po != _relations.end()) {
444  concrete_manipulator<const Relation> m(
445  po->second, true /*can_erase*/
446  );
447  func(po->first.first, po->first.second, m);
448  if(m.remove_requested()) {
449  _remove(po);
450  }
451  }
452  }
453 
454  void for_single(
455  callable_ref<
456  void(entity_param, entity_param, manipulator<const Relation>&)> func,
457  iterator_t& i) override {
458  EAGINE_ASSERT(!i.done());
459  auto& po = _iter_cast(i)._i;
460  EAGINE_ASSERT(po != _relations.end());
461 
462  concrete_manipulator<const Relation> m(
463  po->second, true /*can_erase*/
464  );
465  func(po->first.first, po->first.second, m);
466  if(m.remove_requested()) {
467  po = _remove(po);
468  }
469  }
470 
471  void for_single(
472  callable_ref<void(entity_param, entity_param, manipulator<Relation>&)>
473  func,
474  entity_param subject,
475  entity_param object) override {
476  auto po = _relations.find(_pair_t(subject, object));
477  if(po != _relations.end()) {
478  // TODO: modify notification
479  concrete_manipulator<Relation> m(
480  po->second, true /*can_erase*/
481  );
482  func(po->first.first, po->first.second, m);
483  if(m.remove_requested()) {
484  _remove(po);
485  }
486  }
487  }
488 
489  void for_single(
490  callable_ref<void(entity_param, entity_param, manipulator<Relation>&)>
491  func,
492  iterator_t& i) override {
493  EAGINE_ASSERT(!i.done());
494  auto& po = _iter_cast(i)._i;
495  EAGINE_ASSERT(po != _relations.end());
496 
497  // TODO: modify notification
498  concrete_manipulator<Relation> m(
499  po->second, true /*can_erase*/
500  );
501  func(po->first.first, po->first.second, m);
502  if(m.remove_requested()) {
503  po = _remove(po);
504  }
505  }
506 
507  void for_each(
508  callable_ref<void(entity_param, entity_param)> func,
509  entity_param subject) override {
510  entity_param object = entity_traits<Entity>::minimum();
511  auto po = _relations.lower_bound(_pair_t(subject, object));
512  while((po != _relations.end()) && (po->first.first == subject)) {
513  func(subject, po->first.second);
514  ++po;
515  }
516  }
517 
518  void for_each(callable_ref<void(entity_param, entity_param)> func) override {
519  for(auto& p : _relations) {
520  func(p.first.first, p.first.second);
521  }
522  }
523 
524  void for_each(
525  callable_ref<
526  void(entity_param, entity_param, manipulator<const Relation>&)> func,
527  entity_param subject) override {
528  concrete_manipulator<const Relation> m(true /*can_remove*/);
529  entity_param object = entity_traits<Entity>::minimum();
530  auto po = _relations.lower_bound(_pair_t(subject, object));
531  while((po != _relations.end()) && (po->first.first == subject)) {
532  m.reset(po->second);
533  func(subject, po->first.second, m);
534  if(m.remove_requested()) {
535  po = _remove(po);
536  } else {
537  ++po;
538  }
539  }
540  }
541 
542  void for_each(
543  callable_ref<void(entity_param, entity_param, manipulator<Relation>&)>
544  func,
545  entity_param subject) override {
546  concrete_manipulator<Relation> m(true /*can_remove*/);
547  entity_param object = entity_traits<Entity>::minimum();
548  auto po = _relations.lower_bound(_pair_t(subject, object));
549  while((po != _relations.end()) && (po->first.first == subject)) {
550  // TODO: modify notification
551  m.reset(po->second);
552  func(subject, po->first.second, m);
553  if(m.remove_requested()) {
554  po = _remove(po);
555  } else {
556  ++po;
557  }
558  }
559  }
560 
561  void for_each(
562  callable_ref<void(entity_param, entity_param, manipulator<const Relation>&)>
563  func) override {
564  concrete_manipulator<const Relation> m(true /*can_remove*/);
565  auto po = _relations.begin();
566  while(po != _relations.end()) {
567  m.reset(po->second);
568  func(po->first.first, po->first.second, m);
569  if(m.remove_requested()) {
570  po = _remove(po);
571  } else {
572  ++po;
573  }
574  }
575  }
576 
577  void for_each(
578  callable_ref<void(entity_param, entity_param, manipulator<Relation>&)>
579  func) override {
580  concrete_manipulator<Relation> m(true /*can_remove*/);
581  auto po = _relations.begin();
582  while(po != _relations.end()) {
583  // TODO: modify notification
584  m.reset(po->second);
585  func(po->first.first, po->first.second, m);
586  if(m.remove_requested()) {
587  po = _remove(po);
588  } else {
589  ++po;
590  }
591  }
592  }
593 };
594 
595 } // namespace ecs
596 } // namespace eagine
597 
598 #endif // EAGINE_ECS_STORAGE_STD_MAP_HPP
Common code is placed in this namespace.
Definition: eagine.hpp:21
basic_callable_ref< Sig, is_noexcept_function_v< Sig > > callable_ref
Alias for callable object references.
Definition: callable_ref.hpp:191
static auto find(basic_span< T1, P1, S1 > where, basic_span< T2, P2, S2 > what) -> basic_span< T1, P1, S1 >
Finds the position of the last occurrence of what in a span.
Definition: span_algo.hpp:374
static constexpr auto minimum(T a, T b) noexcept
Returns the minimum value of a and b.
Definition: functions.hpp:47

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