1#ifndef ENTT_ENTITY_HANDLE_HPP
2#define ENTT_ENTITY_HANDLE_HPP
8#include "../core/iterator.hpp"
9#include "../core/type_traits.hpp"
19class handle_storage_iterator final {
20 template<
typename Other>
21 friend class handle_storage_iterator;
23 using underlying_type = std::remove_reference_t<typename It::value_type::second_type>;
24 using entity_type =
typename underlying_type::entity_type;
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;
34 constexpr handle_storage_iterator() noexcept
39 constexpr handle_storage_iterator(entity_type value, It from, It to) noexcept
43 while(it != last && !it->second.contains(
entt)) {
48 constexpr handle_storage_iterator &operator++() noexcept {
49 while(++it != last && !it->second.contains(
entt)) {}
53 constexpr handle_storage_iterator operator++(
int)
noexcept {
54 handle_storage_iterator orig = *
this;
55 return ++(*this), orig;
58 [[nodiscard]]
constexpr reference operator*() const noexcept {
62 [[nodiscard]]
constexpr pointer operator->() const noexcept {
66 template<
typename ILhs,
typename IRhs>
67 friend constexpr bool operator==(
const handle_storage_iterator<ILhs> &,
const handle_storage_iterator<IRhs> &)
noexcept;
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;
80template<
typename ILhs,
typename IRhs>
81[[nodiscard]]
constexpr bool operator!=(
const handle_storage_iterator<ILhs> &lhs,
const handle_storage_iterator<IRhs> &rhs)
noexcept {
96template<
typename Registry,
typename... Scope>
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()}};
144 template<
typename Other,
typename... Args>
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");
164 [[nodiscard]]
explicit operator bool() const noexcept {
165 return reg && reg->valid(
entt);
173 return reg->valid(
entt);
194 reg->destroy(std::exchange(
entt,
null));
202 reg->destroy(std::exchange(
entt,
null), version);
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)...);
225 template<
typename Component,
typename... Args>
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)...);
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)...);
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)...);
262 template<
typename... Component>
265 return reg->template
remove<Component...>(
entt);
272 template<
typename... Component>
283 template<
typename... Component>
284 [[nodiscard]]
decltype(
auto)
all_of()
const {
285 return reg->template
all_of<Component...>(
entt);
294 template<
typename... Component>
295 [[nodiscard]]
decltype(
auto)
any_of()
const {
296 return reg->template
any_of<Component...>(
entt);
304 template<
typename... Component>
305 [[nodiscard]]
decltype(
auto)
get()
const {
307 return reg->template
get<Component...>(
entt);
317 template<
typename Component,
typename... Args>
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)...);
328 template<
typename... Component>
339 return reg->orphan(
entt);
356template<
typename... Args,
typename... Other>
358 return lhs.registry() == rhs.registry() && lhs.entity() == rhs.entity();
370template<
typename... Args,
typename... Other>
372 return !(lhs == rhs);
constexpr null_t null
Compile-time constant for null entities.
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.
void destroy()
Destroys the entity associated with a handle.
void erase() const
Erases the given components from a handle.
typename registry_type::entity_type entity_type
Underlying entity identifier.
decltype(auto) replace(Args &&...args) const
Replaces the given component for a handle.
decltype(auto) get() const
Returns references to the given components for a handle.
decltype(auto) any_of() const
Checks if a handle has at least one of the given components.
decltype(auto) all_of() const
Checks if a handle has all the given components.
decltype(auto) patch(Func &&...func) const
Patches the given component for a handle.
decltype(auto) emplace(Args &&...args) const
Assigns the given component to a handle.
basic_handle() noexcept
Constructs an invalid handle.
basic_handle(registry_type &ref, entity_type value) noexcept
Constructs a handle from a given registry and entity.
void destroy(const version_type version)
Destroys the entity associated with a handle.
decltype(auto) emplace_or_replace(Args &&...args) const
Assigns or replaces the given component for a handle.
bool orphan() const
Checks if a handle has components assigned.
auto try_get() const
Returns pointers to the given components for a handle.
size_type remove() const
Removes the given components from a handle.
typename registry_type::version_type version_type
Underlying version type.
decltype(auto) get_or_emplace(Args &&...args) const
Returns a reference to the given component for a handle.
typename registry_type::size_type size_type
Unsigned integer type.
bool valid() const
Checks if a handle refers to a valid entity or not.
auto storage() const noexcept
Returns an iterable object to use to visit a handle.
entity_type entity() const noexcept
Returns the entity associated with a handle.
Registry registry_type
Type of registry accepted by the handle.
registry_type * registry() const noexcept
Returns a pointer to the underlying registry, if any.
Utility class to create an iterable object from a pair of iterators.
A class to use to push around lists of types, nothing more.