EnTT: src/entt/entity/handle.hpp Source File

EnTT 3.16.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 "../config/config.h"
9#include "../core/iterator.hpp"
10#include "../core/type_traits.hpp"
11#include "entity.hpp"
12#include "fwd.hpp"
13
14namespace entt {
15
17namespace internal {
18
19template<typename It>
20class handle_storage_iterator final {
21 template<typename Other>
22 friend class handle_storage_iterator;
23
24 using underlying_type = std::remove_reference_t<typename It::value_type::second_type>;
25 using entity_type = typename underlying_type::entity_type;
26
27public:
28 using value_type = typename std::iterator_traits<It>::value_type;
29 using pointer = input_iterator_pointer<value_type>;
30 using reference = value_type;
31 using difference_type = std::ptrdiff_t;
32 using iterator_category = std::input_iterator_tag;
33 using iterator_concept = std::forward_iterator_tag;
34
35 constexpr handle_storage_iterator() noexcept
36 : entt{null},
37 it{},
38 last{} {}
39
40 constexpr handle_storage_iterator(entity_type value, It from, It to) noexcept
41 : entt{value},
42 it{from},
43 last{to} {
44 while(it != last && !it->second.contains(entt)) {
45 ++it;
46 }
47 }
48
49 constexpr handle_storage_iterator &operator++() noexcept {
50 for(++it; it != last && !it->second.contains(entt); ++it) {}
51 return *this;
52 }
53
54 constexpr handle_storage_iterator operator++(int) noexcept {
55 const handle_storage_iterator orig = *this;
56 return ++(*this), orig;
57 }
58
59 [[nodiscard]] constexpr reference operator*() const noexcept {
60 return *it;
61 }
62
63 [[nodiscard]] constexpr pointer operator->() const noexcept {
64 return operator*();
65 }
66
67 template<typename ILhs, typename IRhs>
68 friend constexpr bool operator==(const handle_storage_iterator<ILhs> &, const handle_storage_iterator<IRhs> &) noexcept;
69
70private:
71 entity_type entt;
72 It it;
73 It last;
74};
75
76template<typename ILhs, typename IRhs>
77[[nodiscard]] constexpr bool operator==(const handle_storage_iterator<ILhs> &lhs, const handle_storage_iterator<IRhs> &rhs) noexcept {
78 return lhs.it == rhs.it;
79}
80
81template<typename ILhs, typename IRhs>
82[[nodiscard]] constexpr bool operator!=(const handle_storage_iterator<ILhs> &lhs, const handle_storage_iterator<IRhs> &rhs) noexcept {
83 return !(lhs == rhs);
84}
85
86} // namespace internal
88
97template<typename Registry, typename... Scope>
98 class basic_handle {
99 using traits_type = entt_traits<typename Registry::entity_type>;
100
101 [[nodiscard]] auto &owner_or_assert() const noexcept {
102 ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
103 return static_cast<Registry &>(*owner);
104 }
105
106public:
108 using registry_type = Registry;
110 using entity_type = typename traits_type::value_type;
112 using version_type = typename traits_type::version_type;
114 using size_type = std::size_t;
116 using iterable = iterable_adaptor<internal::handle_storage_iterator<typename decltype(std::declval<registry_type>().storage())::iterator>>;
117
119 basic_handle() noexcept
120 : owner{},
121 entt{null} {}
122
128 basic_handle(registry_type &ref, entity_type value) noexcept
129 : owner{&ref},
130 entt{value} {}
131
142 [[nodiscard]] iterable storage() const noexcept {
143 auto underlying = owner_or_assert().storage();
144 return iterable{{entt, underlying.begin(), underlying.end()}, {entt, underlying.end(), underlying.end()}};
145 }
146
148 [[nodiscard]] explicit operator bool() const noexcept {
149 return owner && owner->valid(entt);
150 }
151
157 [[nodiscard]] bool valid() const {
158 return static_cast<bool>(*this);
159 }
160
165 [[nodiscard]] registry_type *registry() const noexcept {
166 return owner;
167 }
168
173 [[nodiscard]] entity_type entity() const noexcept {
174 return entt;
175 }
176
178 [[nodiscard]] operator entity_type() const noexcept {
179 return entity();
180 }
181
183 void destroy() {
184 owner_or_assert().destroy(std::exchange(entt, null));
185 }
186
191 void destroy(const version_type version) {
192 owner_or_assert().destroy(std::exchange(entt, null), version);
193 }
194
202 template<typename Type, typename... Args>
203 // NOLINTNEXTLINE(modernize-use-nodiscard)
204 decltype(auto) emplace(Args &&...args) const {
205 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>), "Invalid type");
206 return owner_or_assert().template emplace<Type>(entt, std::forward<Args>(args)...);
207 }
208
216 template<typename Type, typename... Args>
217 decltype(auto) emplace_or_replace(Args &&...args) const {
218 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>), "Invalid type");
219 return owner_or_assert().template emplace_or_replace<Type>(entt, std::forward<Args>(args)...);
220 }
221
229 template<typename Type, typename... Func>
230 decltype(auto) patch(Func &&...func) const {
231 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>), "Invalid type");
232 return owner_or_assert().template patch<Type>(entt, std::forward<Func>(func)...);
233 }
234
242 template<typename Type, typename... Args>
243 decltype(auto) replace(Args &&...args) const {
244 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>), "Invalid type");
245 return owner_or_assert().template replace<Type>(entt, std::forward<Args>(args)...);
246 }
247
253 template<typename... Type>
254 // NOLINTNEXTLINE(modernize-use-nodiscard)
255 size_type remove() const {
256 static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Type> && ...), "Invalid type");
257 return owner_or_assert().template remove<Type...>(entt);
258 }
259
264 template<typename... Type>
265 void erase() const {
266 static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Type> && ...), "Invalid type");
267 owner_or_assert().template erase<Type...>(entt);
268 }
269
275 template<typename... Type>
276 [[nodiscard]] decltype(auto) all_of() const {
277 return owner_or_assert().template all_of<Type...>(entt);
278 }
279
286 template<typename... Type>
287 [[nodiscard]] decltype(auto) any_of() const {
288 return owner_or_assert().template any_of<Type...>(entt);
289 }
290
296 template<typename... Type>
297 [[nodiscard]] decltype(auto) get() const {
298 static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Type> && ...), "Invalid type");
299 return owner_or_assert().template get<Type...>(entt);
300 }
301
309 template<typename Type, typename... Args>
310 [[nodiscard]] decltype(auto) get_or_emplace(Args &&...args) const {
311 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Type, Scope>), "Invalid type");
312 return owner_or_assert().template get_or_emplace<Type>(entt, std::forward<Args>(args)...);
313 }
314
320 template<typename... Type>
321 [[nodiscard]] auto try_get() const {
322 static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Type> && ...), "Invalid type");
323 return owner_or_assert().template try_get<Type...>(entt);
324 }
325
330 [[nodiscard]] bool orphan() const {
331 return owner_or_assert().orphan(entt);
332 }
333
341 template<typename Other, typename... Args>
342 operator basic_handle<Other, Args...>() const noexcept {
343 static_assert(std::is_same_v<Other, Registry> || std::is_same_v<std::remove_const_t<Other>, Registry>, "Invalid conversion between different handles");
344 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");
345 return owner ? basic_handle<Other, Args...>{*owner, entt} : basic_handle<Other, Args...>{};
346 }
347
348private:
349 registry_type *owner;
350 entity_type entt;
351};
352
362template<typename... Args, typename... Other>
363[[nodiscard]] bool operator==(const basic_handle<Args...> &lhs, const basic_handle<Other...> &rhs) noexcept {
364 return lhs.registry() == rhs.registry() && lhs.entity() == rhs.entity();
365}
366
376template<typename... Args, typename... Other>
377[[nodiscard]] bool operator!=(const basic_handle<Args...> &lhs, const basic_handle<Other...> &rhs) noexcept {
378 return !(lhs == rhs);
379}
380
388template<typename... Args>
389[[nodiscard]] constexpr bool operator==(const basic_handle<Args...> &lhs, const null_t rhs) noexcept {
390 return (lhs.entity() == rhs);
391}
392
400template<typename... Args>
401[[nodiscard]] constexpr bool operator==(const null_t lhs, const basic_handle<Args...> &rhs) noexcept {
402 return (rhs == lhs);
403}
404
412template<typename... Args>
413[[nodiscard]] constexpr bool operator!=(const basic_handle<Args...> &lhs, const null_t rhs) noexcept {
414 return (lhs.entity() != rhs);
415}
416
424template<typename... Args>
425[[nodiscard]] constexpr bool operator!=(const null_t lhs, const basic_handle<Args...> &rhs) noexcept {
426 return (rhs != lhs);
427}
428
429} // namespace entt
430
431#endif
entt::basic_entt_traits< internal::entt_traits< Type > >::value_type
typename internal::entt_traits< Type >::value_type value_type
Definition entity.hpp:69
entt::basic_entt_traits< internal::entt_traits< Type > >::version_type
typename internal::entt_traits< Type >::version_type version_type
Definition entity.hpp:73
entt::basic_handle
Non-owning handle to an entity.
Definition handle.hpp:98
entt::basic_handle::destroy
void destroy()
Destroys the entity associated with a handle.
Definition handle.hpp:183
entt::basic_handle::erase
void erase() const
Erases the given elements from a handle.
Definition handle.hpp:265
entt::basic_handle::replace
decltype(auto) replace(Args &&...args) const
Replaces the given element for a handle.
Definition handle.hpp:243
entt::basic_handle::get
decltype(auto) get() const
Returns references to the given elements for a handle.
Definition handle.hpp:297
entt::basic_handle::any_of
decltype(auto) any_of() const
Checks if a handle has at least one of the given elements.
Definition handle.hpp:287
entt::basic_handle::all_of
decltype(auto) all_of() const
Checks if a handle has all the given elements.
Definition handle.hpp:276
entt::basic_handle::storage
iterable storage() const noexcept
Returns an iterable object to use to visit a handle.
Definition handle.hpp:142
entt::basic_handle::patch
decltype(auto) patch(Func &&...func) const
Patches the given element for a handle.
Definition handle.hpp:230
entt::basic_handle::emplace
decltype(auto) emplace(Args &&...args) const
Assigns the given element to a handle.
Definition handle.hpp:204
entt::basic_handle< registry >::iterable
iterable_adaptor< internal::handle_storage_iterator< typename decltype(std::declval< registry_type >().storage())::iterator > > iterable
Definition handle.hpp:116
entt::basic_handle::basic_handle
basic_handle() noexcept
Constructs an invalid handle.
Definition handle.hpp:119
entt::basic_handle< registry >::size_type
std::size_t size_type
Definition handle.hpp:114
entt::basic_handle::basic_handle
basic_handle(registry_type &ref, entity_type value) noexcept
Constructs a handle from a given registry and entity.
Definition handle.hpp:128
entt::basic_handle::destroy
void destroy(const version_type version)
Destroys the entity associated with a handle.
Definition handle.hpp:191
entt::basic_handle::emplace_or_replace
decltype(auto) emplace_or_replace(Args &&...args) const
Assigns or replaces the given element for a handle.
Definition handle.hpp:217
entt::basic_handle::orphan
bool orphan() const
Checks if a handle has elements assigned.
Definition handle.hpp:330
entt::basic_handle::try_get
auto try_get() const
Returns pointers to the given elements for a handle.
Definition handle.hpp:321
entt::basic_handle::remove
size_type remove() const
Removes the given elements from a handle.
Definition handle.hpp:255
entt::basic_handle< registry >::version_type
typename traits_type::version_type version_type
Definition handle.hpp:112
entt::basic_handle::get_or_emplace
decltype(auto) get_or_emplace(Args &&...args) const
Returns a reference to the given element for a handle.
Definition handle.hpp:310
entt::basic_handle::valid
bool valid() const
Checks if a handle refers to a valid registry and entity.
Definition handle.hpp:157
entt::basic_handle::entity
entity_type entity() const noexcept
Returns the entity associated with a handle.
Definition handle.hpp:173
entt::basic_handle< registry >::registry_type
registry registry_type
Definition handle.hpp:108
entt::basic_handle::registry
registry_type * registry() const noexcept
Returns a pointer to the underlying registry, if any.
Definition handle.hpp:165
entt::basic_handle< registry >::entity_type
typename traits_type::value_type entity_type
Definition handle.hpp:110
entt
EnTT default namespace.
Definition dense_map.hpp:22
entt::null
constexpr null_t null
Compile-time constant for null entities.
Definition entity.hpp:375
entt::type_list_contains_v
constexpr bool type_list_contains_v
Helper variable template.
Definition type_traits.hpp:313
entt::operator!=
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Definition hashed_string.hpp:238
entt::any_policy::ref
@ ref
Aliasing mode, non-const reference.
Definition fwd.hpp:19
entt::operator==
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Definition hashed_string.hpp:226
entt::entt_traits
Entity traits.
Definition entity.hpp:163
entt::iterable_adaptor
Utility class to create an iterable object from a pair of iterators.
Definition iterator.hpp:141
entt::null_t
Null object for all identifiers.
Definition entity.hpp:204
entt::type_list
A class to use to push around lists of types, nothing more.
Definition type_traits.hpp:111