EnTT 3.13.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
16namespace internal {
17
18template<typename It>
19class handle_storage_iterator final {
20 template<typename Other>
21 friend class handle_storage_iterator;
22
23 using underlying_type = std::remove_reference_t<typename It::value_type::second_type>;
24 using entity_type = typename underlying_type::entity_type;
25
26public:
27 using value_type = typename std::iterator_traits<It>::value_type;
28 using pointer = input_iterator_pointer<value_type>;
29 using reference = value_type;
30 using difference_type = std::ptrdiff_t;
31 using iterator_category = std::input_iterator_tag;
32 using iterator_concept = std::forward_iterator_tag;
33
34 constexpr handle_storage_iterator() noexcept
35 : entt{null},
36 it{},
37 last{} {}
38
39 constexpr handle_storage_iterator(entity_type value, It from, It to) noexcept
40 : entt{value},
41 it{from},
42 last{to} {
43 while(it != last && !it->second.contains(entt)) {
44 ++it;
45 }
46 }
47
48 constexpr handle_storage_iterator &operator++() noexcept {
49 while(++it != last && !it->second.contains(entt)) {}
50 return *this;
51 }
52
53 constexpr handle_storage_iterator operator++(int) noexcept {
54 handle_storage_iterator orig = *this;
55 return ++(*this), orig;
56 }
57
58 [[nodiscard]] constexpr reference operator*() const noexcept {
59 return *it;
60 }
61
62 [[nodiscard]] constexpr pointer operator->() const noexcept {
63 return operator*();
64 }
65
66 template<typename ILhs, typename IRhs>
67 friend constexpr bool operator==(const handle_storage_iterator<ILhs> &, const handle_storage_iterator<IRhs> &) noexcept;
68
69private:
70 entity_type entt;
71 It it;
72 It last;
73};
74
75template<typename ILhs, typename IRhs>
76[[nodiscard]] constexpr bool operator==(const handle_storage_iterator<ILhs> &lhs, const handle_storage_iterator<IRhs> &rhs) noexcept {
77 return lhs.it == rhs.it;
78}
79
80template<typename ILhs, typename IRhs>
81[[nodiscard]] constexpr bool operator!=(const handle_storage_iterator<ILhs> &lhs, const handle_storage_iterator<IRhs> &rhs) noexcept {
82 return !(lhs == rhs);
83}
84
85} // namespace internal
96template<typename Registry, typename... Scope>
99 using registry_type = Registry;
101 using entity_type = typename registry_type::entity_type;
103 using version_type = typename registry_type::version_type;
105 using size_type = typename registry_type::size_type;
106
108 basic_handle() noexcept
109 : reg{},
110 entt{null} {}
111
118 : reg{&ref},
119 entt{value} {}
120
131 [[nodiscard]] auto storage() const noexcept {
132 auto iterable = reg->storage();
133 using iterator_type = internal::handle_storage_iterator<typename decltype(iterable)::iterator>;
134 return iterable_adaptor{iterator_type{entt, iterable.begin(), iterable.end()}, iterator_type{entt, iterable.end(), iterable.end()}};
135 }
136
144 template<typename Other, typename... Args>
145 operator basic_handle<Other, Args...>() const noexcept {
146 static_assert(std::is_same_v<Other, Registry> || std::is_same_v<std::remove_const_t<Other>, Registry>, "Invalid conversion between different handles");
147 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");
148
149 return reg ? basic_handle<Other, Args...>{*reg, entt} : basic_handle<Other, Args...>{};
150 }
151
156 [[nodiscard]] operator entity_type() const noexcept {
157 return entity();
158 }
159
164 [[nodiscard]] explicit operator bool() const noexcept {
165 return reg && reg->valid(entt);
166 }
167
172 [[nodiscard]] bool valid() const {
173 return reg->valid(entt);
174 }
175
180 [[nodiscard]] registry_type *registry() const noexcept {
181 return reg;
182 }
183
188 [[nodiscard]] entity_type entity() const noexcept {
189 return entt;
190 }
191
193 void destroy() {
194 reg->destroy(std::exchange(entt, null));
195 }
196
201 void destroy(const version_type version) {
202 reg->destroy(std::exchange(entt, null), version);
203 }
204
212 template<typename Component, typename... Args>
213 decltype(auto) emplace(Args &&...args) const {
214 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Component, Scope>), "Invalid type");
215 return reg->template emplace<Component>(entt, std::forward<Args>(args)...);
216 }
217
225 template<typename Component, typename... Args>
226 decltype(auto) emplace_or_replace(Args &&...args) const {
227 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Component, Scope>), "Invalid type");
228 return reg->template emplace_or_replace<Component>(entt, std::forward<Args>(args)...);
229 }
230
238 template<typename Component, typename... Func>
239 decltype(auto) patch(Func &&...func) const {
240 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Component, Scope>), "Invalid type");
241 return reg->template patch<Component>(entt, std::forward<Func>(func)...);
242 }
243
251 template<typename Component, typename... Args>
252 decltype(auto) replace(Args &&...args) const {
253 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Component, Scope>), "Invalid type");
254 return reg->template replace<Component>(entt, std::forward<Args>(args)...);
255 }
256
262 template<typename... Component>
264 static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Component> && ...), "Invalid type");
265 return reg->template remove<Component...>(entt);
266 }
267
272 template<typename... Component>
273 void erase() const {
274 static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Component> && ...), "Invalid type");
275 reg->template erase<Component...>(entt);
276 }
277
283 template<typename... Component>
284 [[nodiscard]] decltype(auto) all_of() const {
285 return reg->template all_of<Component...>(entt);
286 }
287
294 template<typename... Component>
295 [[nodiscard]] decltype(auto) any_of() const {
296 return reg->template any_of<Component...>(entt);
297 }
298
304 template<typename... Component>
305 [[nodiscard]] decltype(auto) get() const {
306 static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Component> && ...), "Invalid type");
307 return reg->template get<Component...>(entt);
308 }
309
317 template<typename Component, typename... Args>
318 [[nodiscard]] decltype(auto) get_or_emplace(Args &&...args) const {
319 static_assert(((sizeof...(Scope) == 0) || ... || std::is_same_v<Component, Scope>), "Invalid type");
320 return reg->template get_or_emplace<Component>(entt, std::forward<Args>(args)...);
321 }
322
328 template<typename... Component>
329 [[nodiscard]] auto try_get() const {
330 static_assert(sizeof...(Scope) == 0 || (type_list_contains_v<type_list<Scope...>, Component> && ...), "Invalid type");
331 return reg->template try_get<Component...>(entt);
332 }
333
338 [[nodiscard]] bool orphan() const {
339 return reg->orphan(entt);
340 }
341
342private:
343 registry_type *reg;
345};
346
356template<typename... Args, typename... Other>
357[[nodiscard]] bool operator==(const basic_handle<Args...> &lhs, const basic_handle<Other...> &rhs) noexcept {
358 return lhs.registry() == rhs.registry() && lhs.entity() == rhs.entity();
359}
360
370template<typename... Args, typename... Other>
371[[nodiscard]] bool operator!=(const basic_handle<Args...> &lhs, const basic_handle<Other...> &rhs) noexcept {
372 return !(lhs == rhs);
373}
374
375} // namespace entt
376
377#endif
EnTT default namespace.
Definition dense_map.hpp:21
constexpr null_t null
Compile-time constant for null entities.
Definition entity.hpp:363
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.
Non-owning handle to an entity.
Definition handle.hpp:97
void destroy()
Destroys the entity associated with a handle.
Definition handle.hpp:193
void erase() const
Erases the given components from a handle.
Definition handle.hpp:273
typename registry_type::entity_type entity_type
Underlying entity identifier.
Definition handle.hpp:101
decltype(auto) replace(Args &&...args) const
Replaces the given component for a handle.
Definition handle.hpp:252
decltype(auto) get() const
Returns references to the given components for a handle.
Definition handle.hpp:305
decltype(auto) any_of() const
Checks if a handle has at least one of the given components.
Definition handle.hpp:295
decltype(auto) all_of() const
Checks if a handle has all the given components.
Definition handle.hpp:284
decltype(auto) patch(Func &&...func) const
Patches the given component for a handle.
Definition handle.hpp:239
decltype(auto) emplace(Args &&...args) const
Assigns the given component to a handle.
Definition handle.hpp:213
basic_handle() noexcept
Constructs an invalid handle.
Definition handle.hpp:108
basic_handle(registry_type &ref, entity_type value) noexcept
Constructs a handle from a given registry and entity.
Definition handle.hpp:117
void destroy(const version_type version)
Destroys the entity associated with a handle.
Definition handle.hpp:201
decltype(auto) emplace_or_replace(Args &&...args) const
Assigns or replaces the given component for a handle.
Definition handle.hpp:226
bool orphan() const
Checks if a handle has components assigned.
Definition handle.hpp:338
auto try_get() const
Returns pointers to the given components for a handle.
Definition handle.hpp:329
size_type remove() const
Removes the given components from a handle.
Definition handle.hpp:263
typename registry_type::version_type version_type
Underlying version type.
Definition handle.hpp:103
decltype(auto) get_or_emplace(Args &&...args) const
Returns a reference to the given component for a handle.
Definition handle.hpp:318
typename registry_type::size_type size_type
Unsigned integer type.
Definition handle.hpp:105
bool valid() const
Checks if a handle refers to a valid entity or not.
Definition handle.hpp:172
auto storage() const noexcept
Returns an iterable object to use to visit a handle.
Definition handle.hpp:131
entity_type entity() const noexcept
Returns the entity associated with a handle.
Definition handle.hpp:188
Registry registry_type
Type of registry accepted by the handle.
Definition handle.hpp:99
registry_type * registry() const noexcept
Returns a pointer to the underlying registry, if any.
Definition handle.hpp:180
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.