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

manipulator.hpp
Go to the documentation of this file.
1 #ifndef EAGINE_ECS_MANIPULATOR_HPP
9 #define EAGINE_ECS_MANIPULATOR_HPP
10 
11 #include "../assert.hpp"
12 #include "../optional_ref.hpp"
13 #include <type_traits>
14 #include <utility>
15 
16 namespace eagine::ecs {
17 
18 template <typename Component, bool Const>
19 class basic_manipulator;
20 
21 template <typename Component>
22 class basic_manipulator<Component, false> {
23 private:
24  Component* _ptr{nullptr};
25 
26 protected:
27  void _reset_cmp(Component& cmp) noexcept {
28  _ptr = &cmp;
29  }
30 
31 public:
32  basic_manipulator() noexcept = default;
33 
34  basic_manipulator(Component& cmp) noexcept
35  : _ptr{&cmp} {}
36 
37  auto is_valid() const noexcept -> bool {
38  return _ptr != nullptr;
39  }
40 
41  auto read() const -> const Component& {
42  EAGINE_ASSERT(is_valid());
43  return *_ptr;
44  }
45 
46  template <typename T>
47  auto read(T Component::*member) const
48  -> optional_reference_wrapper<const T> {
49  if(_ptr != nullptr) {
50  return {*_ptr.*member};
51  }
52  return {nothing};
53  }
54 
55  auto write() -> Component& {
56  EAGINE_ASSERT(is_valid());
57  return *_ptr;
58  }
59 
60  auto operator->() -> Component* {
61  EAGINE_ASSERT(is_valid());
62  return _ptr;
63  }
64 };
65 
66 template <typename Component>
67 class basic_manipulator<Component, true> {
68 private:
69  const Component* _ptr{nullptr};
70 
71 protected:
72  void _reset_cmp(const Component& cmp) noexcept {
73  _ptr = &cmp;
74  }
75 
76 public:
77  basic_manipulator() noexcept = default;
78 
79  basic_manipulator(const Component& cmp) noexcept
80  : _ptr{&cmp} {}
81 
82  auto is_valid() const noexcept -> bool {
83  return _ptr != nullptr;
84  }
85 
86  auto read() const -> const Component& {
87  EAGINE_ASSERT(is_valid());
88  return *_ptr;
89  }
90 
91  template <typename T>
92  auto read(T Component::*member) const
93  -> optional_reference_wrapper<const T> {
94  if(_ptr != nullptr) {
95  return {*_ptr.*member};
96  }
97  return {nothing};
98  }
99 
100  auto operator->() -> const Component* {
101  EAGINE_ASSERT(is_valid());
102  return _ptr;
103  }
104 };
105 
106 template <typename Component, bool Const>
107 struct get_manipulator {
108  using type = basic_manipulator<Component, Const>;
109 };
110 
111 template <typename Component, bool Const>
112 using get_manipulator_t = typename get_manipulator<Component, Const>::type;
113 
114 template <typename Component>
115 class manipulator
116  : public get_manipulator_t<
117  std::remove_const_t<Component>,
118  std::is_const_v<Component>> {
119 private:
120  using _base = get_manipulator_t<
121  std::remove_const_t<Component>,
122  std::is_const_v<Component>>;
123 
124  using _nonconstC = std::remove_const_t<Component>;
125  _nonconstC* _add_place{nullptr};
126 
127 protected:
128  const bool _can_rem{false};
129  bool _removed{false};
130  bool _added{false};
131 
132 public:
133  manipulator() = default;
134 
135  manipulator(bool can_rem)
136  : _can_rem{can_rem} {}
137 
138  manipulator(Component& cmp, bool can_rem)
139  : _base{cmp}
140  , _can_rem{can_rem} {}
141 
142  manipulator(Component& cmp, _nonconstC& add, bool can_rem)
143  : _base(cmp)
144  , _add_place{&add}
145  , _can_rem(can_rem) {}
146 
147  manipulator(std::nullptr_t, _nonconstC& add, bool can_rem)
148  : _add_place{&add}
149  , _can_rem{can_rem} {}
150 
151  auto can_add() const noexcept -> bool {
152  return _add_place != nullptr;
153  }
154 
155  void add(std::remove_const_t<Component>&& cmp) {
156  EAGINE_ASSERT(can_add());
157  EAGINE_ASSERT(_add_place);
158  *_add_place = std::move(cmp);
159  this->_reset_cmp(*_add_place);
160  _added = true;
161  }
162 
163  auto can_remove() const noexcept -> bool {
164  return _can_rem && this->is_valid();
165  }
166 
167  void remove() {
168  _removed = true;
169  }
170 };
171 
172 template <typename Component>
173 class concrete_manipulator : public manipulator<Component> {
174 public:
175  using manipulator<Component>::manipulator;
176 
177  void reset(Component& cmp) noexcept {
178  this->_reset_cmp(cmp);
179  this->_added = false;
180  this->_removed = false;
181  }
182 
183  auto add_requested() const noexcept -> bool {
184  return this->_added;
185  }
186 
187  auto remove_requested() const noexcept -> bool {
188  return this->_removed;
189  }
190 };
191 
192 } // namespace eagine::ecs
193 
194 #endif // EAGINE_ECS_MANIPULATOR_HPP
static constexpr nothing_t nothing
Constant of nothing_t type.
Definition: nothing.hpp:30

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