EnTT 3.14.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 while(++it != last && !it->second.contains(entt)) {}
51 return *this;
52 }
53
54 constexpr handle_storage_iterator operator++(int) noexcept {
55 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
97template<typename Registry, typename... Scope>
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:
114 using size_type = std::size_t;
117
120 : owner{},
121 entt{null} {}
122
129 : owner{&ref},
130 entt{value} {}
131
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
166 return owner;
167 }
168
174 return entt;
175 }
176
179 return entity();
180 }
181
183 void destroy() {
184 owner_or_assert().destroy(std::exchange(entt, null));
185 }
186
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)
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;
351};
352
362template<typename... Args, typename... Other>
364 return lhs.registry() == rhs.registry() && lhs.entity() == rhs.entity();
365}
366
376template<typename... Args, typename... Other>
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
typename Traits::value_type value_type
Value type.
Definition entity.hpp:69
typename Traits::version_type version_type
Underlying version type.
Definition entity.hpp:73
Non-owning handle to an entity.
Definition handle.hpp:98
void destroy()
Destroys the entity associated with a handle.
Definition handle.hpp:183
void erase() const
Erases the given elements from a handle.
Definition handle.hpp:265
decltype(auto) replace(Args &&...args) const
Replaces the given element for a handle.
Definition handle.hpp:243
decltype(auto) get() const
Returns references to the given elements for a handle.
Definition handle.hpp:297
decltype(auto) any_of() const
Checks if a handle has at least one of the given elements.
Definition handle.hpp:287
decltype(auto) all_of() const
Checks if a handle has all the given elements.
Definition handle.hpp:276
iterable storage() const noexcept
Returns an iterable object to use to visit a handle.
Definition handle.hpp:142
decltype(auto) patch(Func &&...func) const
Patches the given element for a handle.
Definition handle.hpp:230
decltype(auto) emplace(Args &&...args) const
Assigns the given element to a handle.
Definition handle.hpp:204
basic_handle() noexcept
Constructs an invalid handle.
Definition handle.hpp:119
std::size_t size_type
Unsigned integer type.
Definition handle.hpp:114
basic_handle(registry_type &ref, entity_type value) noexcept
Constructs a handle from a given registry and entity.
Definition handle.hpp:128
void destroy(const version_type version)
Destroys the entity associated with a handle.
Definition handle.hpp:191
decltype(auto) emplace_or_replace(Args &&...args) const
Assigns or replaces the given element for a handle.
Definition handle.hpp:217
bool orphan() const
Checks if a handle has elements assigned.
Definition handle.hpp:330
auto try_get() const
Returns pointers to the given elements for a handle.
Definition handle.hpp:321
size_type remove() const
Removes the given elements from a handle.
Definition handle.hpp:255
typename traits_type::version_type version_type
Underlying version type.
Definition handle.hpp:112
decltype(auto) get_or_emplace(Args &&...args) const
Returns a reference to the given element for a handle.
Definition handle.hpp:310
bool valid() const
Checks if a handle refers to a valid registry and entity.
Definition handle.hpp:157
entity_type entity() const noexcept
Returns the entity associated with a handle.
Definition handle.hpp:173
Registry registry_type
Type of registry accepted by the handle.
Definition handle.hpp:108
registry_type * registry() const noexcept
Returns a pointer to the underlying registry, if any.
Definition handle.hpp:165
typename traits_type::value_type entity_type
Underlying entity identifier.
Definition handle.hpp:110
EnTT default namespace.
Definition dense_map.hpp:22
constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args)
Uses-allocator construction utility (waiting for C++20).
Definition memory.hpp:219
constexpr null_t null
Compile-time constant for null entities.
Definition entity.hpp:375
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.
@ ref
Aliasing mode, the object points to a non-const element.
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Entity traits.
Definition entity.hpp:163
Utility class to create an iterable object from a pair of iterators.
Definition iterator.hpp:141
Null object for all identifiers.
Definition entity.hpp:204
A class to use to push around lists of types, nothing more.