EnTT 3.12.0
Loading...
Searching...
No Matches
handle.hpp
1#ifndef ENTT_ENTITY_HANDLE_HPP
2#define ENTT_ENTITY_HANDLE_HPP
3
4#include <iterator>
5#include <tuple>
6#include <type_traits>
7#include <utility>
8#include "../core/iterator.hpp"
9#include "../core/type_traits.hpp"
10#include "entity.hpp"
11#include "fwd.hpp"
12
13namespace entt {
14
20namespace internal {
21
22template<typename It>
23class handle_storage_iterator final {
24 template<typename Other>
25 friend class handle_storage_iterator;
26
27 using underlying_type = std::remove_reference_t<typename It::value_type::second_type>;
28 using entity_type = typename underlying_type::entity_type;
29
30public:
31 using value_type = typename std::iterator_traits<It>::value_type;
32 using pointer = input_iterator_pointer<value_type>;
33 using reference = value_type;
34 using difference_type = std::ptrdiff_t;
35 using iterator_category = std::input_iterator_tag;
36
37 constexpr handle_storage_iterator() noexcept
38 : entt{null},
39 it{},
40 last{} {}
41
42 constexpr handle_storage_iterator(entity_type value, It from, It to) noexcept
43 : entt{value},
44 it{from},
45 last{to} {
46 while(it != last && !it->second.contains(entt)) {
47 ++it;
48 }
49 }
50
51 constexpr handle_storage_iterator &operator++() noexcept {
52 while(++it != last && !it->second.contains(entt)) {}
53 return *this;
54 }
55
56 constexpr handle_storage_iterator operator++(int) noexcept {
57 handle_storage_iterator orig = *this;
58 return ++(*this), orig;
59 }
60
61 [[nodiscard]] constexpr reference operator*() const noexcept {
62 return *it;
63 }
64
65 [[nodiscard]] constexpr pointer operator->() const noexcept {
66 return operator*();
67 }
68
69 template<typename ILhs, typename IRhs>
70 friend constexpr bool operator==(const handle_storage_iterator<ILhs> &, const handle_storage_iterator<IRhs> &) noexcept;
71
72private:
73 entity_type entt;
74 It it;
75 It last;
76};
77
78template<typename ILhs, typename IRhs>
79[[nodiscard]] constexpr bool operator==(const handle_storage_iterator<ILhs> &lhs, const handle_storage_iterator<IRhs> &rhs) noexcept {
80 return lhs.it == rhs.it;
81}
82
83template<typename ILhs, typename IRhs>
84[[nodiscard]] constexpr bool operator!=(const handle_storage_iterator<ILhs> &lhs, const handle_storage_iterator<IRhs> &rhs) noexcept {
85 return !(lhs == rhs);
86}
87
88} // namespace internal
89
103template<typename Registry, typename... Scope>
106 using registry_type = Registry;
108 using entity_type = typename registry_type::entity_type;
110 using version_type = typename registry_type::version_type;
112 using size_type = typename registry_type::size_type;
113
115 basic_handle() noexcept
116 : reg{},
117 entt{null} {}
118
125 : reg{&ref},
126 entt{value} {}
127
138 [[nodiscard]] auto storage() const noexcept {
139 auto iterable = reg->storage();
140 using iterator_type = internal::handle_storage_iterator<typename decltype(iterable)::iterator>;
141 return iterable_adaptor{iterator_type{entt, iterable.begin(), iterable.end()}, iterator_type{entt, iterable.end(), iterable.end()}};
142 }
143
151 template<typename Other, typename... Args>
152 operator basic_handle<Other, Args...>() const noexcept {
153 static_assert(std::is_same_v<Other, Registry> || std::is_same_v<std::remove_const_t<Other>, Registry>, "Invalid conversion between different handles");
154 static_assert((sizeof...(Scope) == 0 || ((sizeof...(Args) != 0 && sizeof...(Args) <= sizeof...(Scope)) && ... && (type_list_contains_v<type_list<Scope...>, Args>))), "Invalid conversion between different handles");
155
156 return reg ? basic_handle<Other, Args...>{*reg, entt} : basic_handle<Other, Args...>{};
157 }
158
163 [[nodiscard]] operator entity_type() const noexcept {
164 return entity();
165 }
166
171 [[nodiscard]] explicit operator bool() const noexcept {
172 return reg && reg->valid(entt);
173 }
174
179 [[nodiscard]] bool valid() const {
180 return reg->valid(entt);
181 }
182
187 [[nodiscard]] registry_type *registry() const noexcept {
188 return reg;
189 }
190
195 [[nodiscard]] entity_type entity() const noexcept {
196 return entt;
197 }
198
200 void destroy() {
201 reg->destroy(std::exchange(entt, null));
202 }
203
208 void destroy(const version_type version) {
209 reg->destroy(std::exchange(entt, null), version);
210 }
211
219 template<typename Component, typename... Args>
220 decltype(auto) emplace(Args &&...args) const {
221 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Component, Scope>), "Invalid type");
222 return reg->template emplace<Component>(entt, std::forward<Args>(args)...);
223 }
224
232 template<typename Component, typename... Args>
233 decltype(auto) emplace_or_replace(Args &&...args) const {
234 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Component, Scope>), "Invalid type");
235 return reg->template emplace_or_replace<Component>(entt, std::forward<Args>(args)...);
236 }
237
245 template<typename Component, typename... Func>
246 decltype(auto) patch(Func &&...func) const {
247 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Component, Scope>), "Invalid type");
248 return reg->template patch<Component>(entt, std::forward<Func>(func)...);
249 }
250
258 template<typename Component, typename... Args>
259 decltype(auto) replace(Args &&...args) const {
260 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Component, Scope>), "Invalid type");
261 return reg->template replace<Component>(entt, std::forward<Args>(args)...);
262 }
263
269 template<typename... Component>
271 static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Component> && ...), "Invalid type");
272 return reg->template remove<Component...>(entt);
273 }
274
279 template<typename... Component>
280 void erase() const {
281 static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Component> && ...), "Invalid type");
282 reg->template erase<Component...>(entt);
283 }
284
290 template<typename... Component>
291 [[nodiscard]] decltype(auto) all_of() const {
292 return reg->template all_of<Component...>(entt);
293 }
294
301 template<typename... Component>
302 [[nodiscard]] decltype(auto) any_of() const {
303 return reg->template any_of<Component...>(entt);
304 }
305
311 template<typename... Component>
312 [[nodiscard]] decltype(auto) get() const {
313 static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Component> && ...), "Invalid type");
314 return reg->template get<Component...>(entt);
315 }
316
324 template<typename Component, typename... Args>
325 [[nodiscard]] decltype(auto) get_or_emplace(Args &&...args) const {
326 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Component, Scope>), "Invalid type");
327 return reg->template get_or_emplace<Component>(entt, std::forward<Args>(args)...);
328 }
329
335 template<typename... Component>
336 [[nodiscard]] auto try_get() const {
337 static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Component> && ...), "Invalid type");
338 return reg->template try_get<Component...>(entt);
339 }
340
345 [[nodiscard]] bool orphan() const {
346 return reg->orphan(entt);
347 }
348
349private:
350 registry_type *reg;
352};
353
363template<typename... Args, typename... Other>
364[[nodiscard]] bool operator==(const basic_handle<Args...> &lhs, const basic_handle<Other...> &rhs) noexcept {
365 return lhs.registry() == rhs.registry() && lhs.entity() == rhs.entity();
366}
367
377template<typename... Args, typename... Other>
378[[nodiscard]] bool operator!=(const basic_handle<Args...> &lhs, const basic_handle<Other...> &rhs) noexcept {
379 return !(lhs == rhs);
380}
381
382} // namespace entt
383
384#endif
EnTT default namespace.
Definition: dense_map.hpp:21
constexpr null_t null
Compile-time constant for null entities.
Definition: entity.hpp:366
constexpr bool type_list_contains_v
Helper variable template.
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Non-owning handle to an entity.
Definition: handle.hpp:104
void destroy()
Destroys the entity associated with a handle.
Definition: handle.hpp:200
void erase() const
Erases the given components from a handle.
Definition: handle.hpp:280
typename registry_type::entity_type entity_type
Underlying entity identifier.
Definition: handle.hpp:108
decltype(auto) replace(Args &&...args) const
Replaces the given component for a handle.
Definition: handle.hpp:259
decltype(auto) get() const
Returns references to the given components for a handle.
Definition: handle.hpp:312
decltype(auto) any_of() const
Checks if a handle has at least one of the given components.
Definition: handle.hpp:302
decltype(auto) all_of() const
Checks if a handle has all the given components.
Definition: handle.hpp:291
decltype(auto) patch(Func &&...func) const
Patches the given component for a handle.
Definition: handle.hpp:246
decltype(auto) emplace(Args &&...args) const
Assigns the given component to a handle.
Definition: handle.hpp:220
basic_handle() noexcept
Constructs an invalid handle.
Definition: handle.hpp:115
basic_handle(registry_type &ref, entity_type value) noexcept
Constructs a handle from a given registry and entity.
Definition: handle.hpp:124
void destroy(const version_type version)
Destroys the entity associated with a handle.
Definition: handle.hpp:208
decltype(auto) emplace_or_replace(Args &&...args) const
Assigns or replaces the given component for a handle.
Definition: handle.hpp:233
bool orphan() const
Checks if a handle has components assigned.
Definition: handle.hpp:345
auto try_get() const
Returns pointers to the given components for a handle.
Definition: handle.hpp:336
size_type remove() const
Removes the given components from a handle.
Definition: handle.hpp:270
typename registry_type::version_type version_type
Underlying version type.
Definition: handle.hpp:110
decltype(auto) get_or_emplace(Args &&...args) const
Returns a reference to the given component for a handle.
Definition: handle.hpp:325
typename registry_type::size_type size_type
Unsigned integer type.
Definition: handle.hpp:112
bool valid() const
Checks if a handle refers to a valid entity or not.
Definition: handle.hpp:179
auto storage() const noexcept
Returns an iterable object to use to visit a handle.
Definition: handle.hpp:138
entity_type entity() const noexcept
Returns the entity associated with a handle.
Definition: handle.hpp:195
Registry registry_type
Type of registry accepted by the handle.
Definition: handle.hpp:106
registry_type * registry() const noexcept
Returns a pointer to the underlying registry, if any.
Definition: handle.hpp:187
Utility class to create an iterable object from a pair of iterators.
Definition: iterator.hpp:141
A class to use to push around lists of types, nothing more.