null entity
This commit is contained in:
41
README.md
41
README.md
@@ -425,19 +425,6 @@ auto version = registry.version(entity);
|
||||
auto curr = registry.current(entity);
|
||||
```
|
||||
|
||||
Finally, there is also a sort of _null identifier_ made available to users. It's
|
||||
treated as if it were a _null pointer_ that doesn't identify any entity. A
|
||||
registry will reject this identifier in all cases because it isn't considered
|
||||
valid.<br/>
|
||||
The rules that define a _null identifier_ are a bit tricky to explain. However,
|
||||
being `Entity` the type of the entities (for example, `std::uint32_t`), users
|
||||
can easily construct a _null identifier_ by flipping all the bits of the _zero_:
|
||||
|
||||
```cpp
|
||||
using Entity = std::uint32_t;
|
||||
const auto null = ~Entity{};
|
||||
```
|
||||
|
||||
Components can be assigned to or removed from entities at any time with a few
|
||||
calls to member functions of the registry. As for the entities, the registry
|
||||
offers also a set of functionalities users can use to work with the components.
|
||||
@@ -1136,6 +1123,34 @@ A dependency can easily be broken by means of the same function template:
|
||||
entt::dependency<AType, AnotherType>(entt::break_t{}, registry.construction<MyType>());
|
||||
```
|
||||
|
||||
### Null entity
|
||||
|
||||
In `EnTT`, there exists a sort of _null entity_ made available to users that is
|
||||
accessible via the `entt::null` variable.<br/>
|
||||
The framework guarantees that the following expression always returns false:
|
||||
|
||||
```cpp
|
||||
registry.valid(entt::null);
|
||||
```
|
||||
|
||||
In other terms, a registry will reject the null entity in all cases because it
|
||||
isn't considered valid. It means that the null entity cannot own components or
|
||||
tags for obvious reasons.<br/>
|
||||
The type of the null entity is internal and should not be used for any purpose
|
||||
other than defining the null entity itself. However, there exist implicit
|
||||
conversions from the null entity to identifiers of any allowed type:
|
||||
|
||||
```cpp
|
||||
typename entt::DefaultRegistry::entity_type null = entt::null;
|
||||
```
|
||||
|
||||
Similarly, the null entity can be compared to any other identifier:
|
||||
|
||||
```cpp
|
||||
const auto entity = registry.create();
|
||||
const bool null = (entity == entt::null);
|
||||
```
|
||||
|
||||
## View: to persist or not to persist?
|
||||
|
||||
First of all, it is worth answering an obvious question: why views?<br/>
|
||||
|
||||
87
src/entt/entity/entity.hpp
Normal file
87
src/entt/entity/entity.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#ifndef ENTT_ENTITY_ENTITY_HPP
|
||||
#define ENTT_ENTITY_ENTITY_HPP
|
||||
|
||||
|
||||
#include "../config/config.h"
|
||||
#include "entt_traits.hpp"
|
||||
|
||||
|
||||
namespace entt {
|
||||
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
/**
|
||||
* @cond TURN_OFF_DOXYGEN
|
||||
* Internal details not to be documented.
|
||||
*/
|
||||
|
||||
|
||||
template<typename Entity>
|
||||
static constexpr auto null = ~typename entt_traits<Entity>::entity_type{};
|
||||
|
||||
|
||||
struct Null {
|
||||
explicit constexpr Null() = default;
|
||||
|
||||
template<typename Entity>
|
||||
constexpr operator Entity() const ENTT_NOEXCEPT {
|
||||
return null<Entity>;
|
||||
}
|
||||
|
||||
constexpr bool operator==(Null) const ENTT_NOEXCEPT {
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(Null) const ENTT_NOEXCEPT {
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Entity>
|
||||
constexpr bool operator==(const Entity entity) const ENTT_NOEXCEPT {
|
||||
return entity == null<Entity>;
|
||||
}
|
||||
|
||||
template<typename Entity>
|
||||
constexpr bool operator!=(const Entity entity) const ENTT_NOEXCEPT {
|
||||
return entity != null<Entity>;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Entity>
|
||||
constexpr bool operator==(const Entity entity, Null null) ENTT_NOEXCEPT {
|
||||
return null == entity;
|
||||
}
|
||||
|
||||
|
||||
template<typename Entity>
|
||||
constexpr bool operator!=(const Entity entity, Null null) ENTT_NOEXCEPT {
|
||||
return null != entity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal details not to be documented.
|
||||
* @endcond TURN_OFF_DOXYGEN
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Null entity.
|
||||
*
|
||||
* There exist implicit conversions from this variable to entity identifiers of
|
||||
* any allowed type. Similarly, there exist comparision operators between the
|
||||
* null entity and any other entity identifier.
|
||||
*/
|
||||
constexpr auto null = internal::Null{};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // ENTT_ENTITY_ENTITY_HPP
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "core/hashed_string.hpp"
|
||||
#include "core/ident.hpp"
|
||||
#include "entity/actor.hpp"
|
||||
#include "entity/entity.hpp"
|
||||
#include "entity/entt_traits.hpp"
|
||||
#include "entity/helper.hpp"
|
||||
#include "entity/prototype.hpp"
|
||||
|
||||
@@ -53,6 +53,7 @@ ADD_ENTT_TEST(ident entt/core/ident.cpp)
|
||||
# Test entity
|
||||
|
||||
ADD_ENTT_TEST(actor entt/entity/actor.cpp)
|
||||
ADD_ENTT_TEST(entity entt/entity/entity.cpp)
|
||||
ADD_ENTT_TEST(helper entt/entity/helper.cpp)
|
||||
ADD_ENTT_TEST(prototype entt/entity/prototype.cpp)
|
||||
ADD_ENTT_TEST(registry entt/entity/registry.cpp)
|
||||
|
||||
27
test/entt/entity/entity.cpp
Normal file
27
test/entt/entity/entity.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <functional>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/entity/entity.hpp>
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
template<bool>
|
||||
struct S {};
|
||||
|
||||
TEST(Traits, Null) {
|
||||
entt::DefaultRegistry registry{};
|
||||
|
||||
const auto entity = registry.create();
|
||||
registry.assign<int>(entity, 42);
|
||||
|
||||
ASSERT_TRUE(~typename entt::DefaultRegistry::entity_type{} == entt::null);
|
||||
|
||||
ASSERT_TRUE(entt::null == entt::null);
|
||||
ASSERT_FALSE(entt::null != entt::null);
|
||||
|
||||
ASSERT_FALSE(entity == entt::null);
|
||||
ASSERT_FALSE(entt::null == entity);
|
||||
|
||||
ASSERT_TRUE(entity != entt::null);
|
||||
ASSERT_TRUE(entt::null != entity);
|
||||
|
||||
ASSERT_FALSE(registry.valid(entt::null));
|
||||
}
|
||||
Reference in New Issue
Block a user