EnTT  3.10.0
handle.hpp
1 #ifndef ENTT_ENTITY_HANDLE_HPP
2 #define ENTT_ENTITY_HANDLE_HPP
3 
4 #include <tuple>
5 #include <type_traits>
6 #include <utility>
7 #include "../config/config.h"
8 #include "../core/type_traits.hpp"
9 #include "fwd.hpp"
10 #include "registry.hpp"
11 
12 namespace entt {
13 
22 template<typename Entity, typename... Type>
23 struct basic_handle {
27  using entity_type = typename registry_type::entity_type;
29  using version_type = typename registry_type::version_type;
31  using size_type = typename registry_type::size_type;
32 
34  basic_handle() ENTT_NOEXCEPT
35  : reg{},
36  entt{null} {}
37 
43  basic_handle(registry_type &ref, entity_type value) ENTT_NOEXCEPT
44  : reg{&ref},
45  entt{value} {}
46 
54  template<typename Other, typename... Args>
55  operator basic_handle<Other, Args...>() const ENTT_NOEXCEPT {
56  static_assert(std::is_same_v<Other, Entity> || std::is_same_v<std::remove_const_t<Other>, Entity>, "Invalid conversion between different handles");
57  static_assert((sizeof...(Type) == 0 || ((sizeof...(Args) != 0 && sizeof...(Args) <= sizeof...(Type)) && ... && (type_list_contains_v<type_list<Type...>, Args>))), "Invalid conversion between different handles");
58 
59  return reg ? basic_handle<Other, Args...>{*reg, entt} : basic_handle<Other, Args...>{};
60  }
61 
66  [[nodiscard]] operator entity_type() const ENTT_NOEXCEPT {
67  return entity();
68  }
69 
74  [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
75  return reg && reg->valid(entt);
76  }
77 
82  [[nodiscard]] bool valid() const {
83  return reg->valid(entt);
84  }
85 
90  [[nodiscard]] registry_type *registry() const ENTT_NOEXCEPT {
91  return reg;
92  }
93 
98  [[nodiscard]] entity_type entity() const ENTT_NOEXCEPT {
99  return entt;
100  }
101 
106  void destroy() {
107  reg->destroy(entt);
108  }
109 
115  void destroy(const version_type version) {
116  reg->destroy(entt, version);
117  }
118 
127  template<typename Component, typename... Args>
128  decltype(auto) emplace(Args &&...args) const {
129  static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v<Component, Type>), "Invalid type");
130  return reg->template emplace<Component>(entt, std::forward<Args>(args)...);
131  }
132 
141  template<typename Component, typename... Args>
142  decltype(auto) emplace_or_replace(Args &&...args) const {
143  static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v<Component, Type>), "Invalid type");
144  return reg->template emplace_or_replace<Component>(entt, std::forward<Args>(args)...);
145  }
146 
155  template<typename Component, typename... Func>
156  decltype(auto) patch(Func &&...func) const {
157  static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v<Component, Type>), "Invalid type");
158  return reg->template patch<Component>(entt, std::forward<Func>(func)...);
159  }
160 
169  template<typename Component, typename... Args>
170  decltype(auto) replace(Args &&...args) const {
171  static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v<Component, Type>), "Invalid type");
172  return reg->template replace<Component>(entt, std::forward<Args>(args)...);
173  }
174 
181  template<typename... Component>
182  size_type remove() const {
183  static_assert(sizeof...(Type) == 0 || (type_list_contains_v<type_list<Type...>, Component> && ...), "Invalid type");
184  return reg->template remove<Component...>(entt);
185  }
186 
192  template<typename... Component>
193  void erase() const {
194  static_assert(sizeof...(Type) == 0 || (type_list_contains_v<type_list<Type...>, Component> && ...), "Invalid type");
195  reg->template erase<Component...>(entt);
196  }
197 
204  template<typename... Component>
205  [[nodiscard]] decltype(auto) all_of() const {
206  return reg->template all_of<Component...>(entt);
207  }
208 
216  template<typename... Component>
217  [[nodiscard]] decltype(auto) any_of() const {
218  return reg->template any_of<Component...>(entt);
219  }
220 
227  template<typename... Component>
228  [[nodiscard]] decltype(auto) get() const {
229  static_assert(sizeof...(Type) == 0 || (type_list_contains_v<type_list<Type...>, Component> && ...), "Invalid type");
230  return reg->template get<Component...>(entt);
231  }
232 
241  template<typename Component, typename... Args>
242  [[nodiscard]] decltype(auto) get_or_emplace(Args &&...args) const {
243  static_assert(((sizeof...(Type) == 0) || ... || std::is_same_v<Component, Type>), "Invalid type");
244  return reg->template get_or_emplace<Component>(entt, std::forward<Args>(args)...);
245  }
246 
253  template<typename... Component>
254  [[nodiscard]] auto try_get() const {
255  static_assert(sizeof...(Type) == 0 || (type_list_contains_v<type_list<Type...>, Component> && ...), "Invalid type");
256  return reg->template try_get<Component...>(entt);
257  }
258 
263  [[nodiscard]] bool orphan() const {
264  return reg->orphan(entt);
265  }
266 
282  template<typename Func>
283  void visit(Func &&func) const {
284  for(auto [id, storage]: reg->storage()) {
285  if(storage.contains(entt)) {
286  func(id, storage);
287  }
288  }
289  }
290 
291 private:
292  registry_type *reg;
294 };
295 
305 template<typename... Args, typename... Other>
306 [[nodiscard]] bool operator==(const basic_handle<Args...> &lhs, const basic_handle<Other...> &rhs) ENTT_NOEXCEPT {
307  return lhs.registry() == rhs.registry() && lhs.entity() == rhs.entity();
308 }
309 
319 template<typename... Args, typename... Other>
320 [[nodiscard]] bool operator!=(const basic_handle<Args...> &lhs, const basic_handle<Other...> &rhs) ENTT_NOEXCEPT {
321  return !(lhs == rhs);
322 }
323 
328 template<typename Entity>
330 
335 template<typename Entity>
337 
338 } // namespace entt
339 
340 #endif
Fast and reliable entity-component system.
Definition: registry.hpp:221
bool contains(const entity_type entt) const
Checks if a sparse set contains an entity.
Definition: sparse_set.hpp:576
Basic storage implementation.
Definition: storage.hpp:234
EnTT default namespace.
Definition: dense_map.hpp:22
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs)
Compares two hashed strings.
basic_handle(basic_registry< Entity > &, Entity) -> basic_handle< Entity >
Deduction guide.
typename constness_as< To, From >::type constness_as_t
Alias template to facilitate the transcription of the constness.
constexpr bool type_list_contains_v
Helper variable template.
bool operator!=(const basic_any< Len, Align > &lhs, const basic_any< Len, Align > &rhs)
Checks if two wrappers differ in their content.
Definition: any.hpp:402
Non-owning handle to an entity.
Definition: handle.hpp:23
decltype(auto) any_of() const
Checks if a handle has at least one of the given components.
Definition: handle.hpp:217
bool orphan() const
Checks if a handle has components assigned.
Definition: handle.hpp:263
typename registry_type::size_type size_type
Unsigned integer type.
Definition: handle.hpp:31
decltype(auto) get() const
Returns references to the given components for a handle.
Definition: handle.hpp:228
void visit(Func &&func) const
Visits a handle and returns the pools for its components.
Definition: handle.hpp:283
entity_type entity() const
Returns the entity associated with a handle.
Definition: handle.hpp:98
decltype(auto) all_of() const
Checks if a handle has all the given components.
Definition: handle.hpp:205
registry_type * registry() const
Returns a pointer to the underlying registry, if any.
Definition: handle.hpp:90
typename registry_type::entity_type entity_type
Underlying entity identifier.
Definition: handle.hpp:27
decltype(auto) replace(Args &&...args) const
Replaces the given component for a handle.
Definition: handle.hpp:170
auto try_get() const
Returns pointers to the given components for a handle.
Definition: handle.hpp:254
decltype(auto) patch(Func &&...func) const
Patches the given component for a handle.
Definition: handle.hpp:156
decltype(auto) emplace_or_replace(Args &&...args) const
Assigns or replaces the given component for a handle.
Definition: handle.hpp:142
decltype(auto) emplace(Args &&...args) const
Assigns the given component to a handle.
Definition: handle.hpp:128
basic_handle(registry_type &ref, entity_type value)
Constructs a handle from a given registry and entity.
Definition: handle.hpp:43
void destroy()
Destroys the entity associated with a handle.
Definition: handle.hpp:106
typename registry_type::version_type version_type
Underlying version type.
Definition: handle.hpp:29
bool valid() const
Checks if a handle refers to a valid entity or not.
Definition: handle.hpp:82
size_type remove() const
Removes the given components from a handle.
Definition: handle.hpp:182
void erase() const
Erases the given components from a handle.
Definition: handle.hpp:193
decltype(auto) get_or_emplace(Args &&...args) const
Returns a reference to the given component for a handle.
Definition: handle.hpp:242
basic_handle()
Constructs an invalid handle.
Definition: handle.hpp:34
constness_as_t< basic_registry< std::remove_const_t< Entity > >, Entity > registry_type
Type of registry accepted by the handle.
Definition: handle.hpp:25
void destroy(const version_type version)
Destroys the entity associated with a handle.
Definition: handle.hpp:115