more on context variables
This commit is contained in:
2
TODO
2
TODO
@@ -20,5 +20,5 @@
|
||||
- each components only return actual component, so shared components are returned only once
|
||||
* types defined at runtime that refer to the same compile-time type (but to different pools) are possible, the library is almost there
|
||||
* add take functionality, eg registry.take(entity, other); where it takes the entity and all its components from registry and move them to other
|
||||
* what about paged pools? vector of fixed-size blocks (ease shared components, multi-ownership, etc).
|
||||
* add entity function to views/groups (component -> owner, see sparse sets)
|
||||
* what about paged pools? vector of fixed-size blocks
|
||||
|
||||
@@ -831,8 +831,9 @@ const bool null = (entity == entt::null);
|
||||
It is often convenient to assign context variables to a registry, so as to make
|
||||
it the only _source of truth_ of an application.<br/>
|
||||
This is possible by means of a member function named `set` to use to create a
|
||||
context variable from a given type. Later on, `ctx` can be used to retrieve the
|
||||
newly created instance and `unset` is there to literally reset it if needed.
|
||||
context variable from a given type. Later on, either `ctx` or `try_ctx` can be
|
||||
used to retrieve the newly created instance and `unset` is there to literally
|
||||
reset it if needed.
|
||||
|
||||
Example of use:
|
||||
|
||||
@@ -840,7 +841,11 @@ Example of use:
|
||||
// creates a new context variable initialized with the given values
|
||||
registry.set<my_type>(42, 'c');
|
||||
|
||||
if(auto *var = registry.ctx<my_type>(); var) {
|
||||
// gets the context variable
|
||||
const auto &var = registry.ctx<my_type>();
|
||||
|
||||
// if in doubts, probe the registry to avoid assertions in case of errors
|
||||
if(auto *ptr = registry.try_ctx<my_type>(); var) {
|
||||
// uses the context variable associated with a registry, if any
|
||||
}
|
||||
|
||||
@@ -850,9 +855,10 @@ registry.unset<my_type>();
|
||||
|
||||
The type of a context variable must be such that it's default constructible and
|
||||
can be moved. The `set` member function either creates a new instance of the
|
||||
context variable or overwrites an already existing one if any. The `ctx` member
|
||||
function returns a pointer to the context variable if it exists, otherwise it
|
||||
returns a null pointer. This fits well with the `if` statement with initializer.
|
||||
context variable or overwrites an already existing one if any. The `try_ctx`
|
||||
member function returns a pointer to the context variable if it exists,
|
||||
otherwise it returns a null pointer. This fits well with the `if` statement with
|
||||
initializer.
|
||||
|
||||
# Views and Groups
|
||||
|
||||
|
||||
@@ -1645,7 +1645,7 @@ public:
|
||||
* registry, a null pointer otherwise.
|
||||
*/
|
||||
template<typename Type>
|
||||
const Type * ctx() const ENTT_NOEXCEPT {
|
||||
const Type * try_ctx() const ENTT_NOEXCEPT {
|
||||
const auto ctype = runtime_type<Type, context_family>();
|
||||
|
||||
if constexpr(is_named_type_v<Type>) {
|
||||
@@ -1660,10 +1660,35 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/*! @copydoc try_ctx */
|
||||
template<typename Type>
|
||||
inline Type * try_ctx() ENTT_NOEXCEPT {
|
||||
return const_cast<Type *>(std::as_const(*this).template try_ctx<Type>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a reference to an object in the context of the registry.
|
||||
*
|
||||
* @warning
|
||||
* Attempting to get a context variable that doesn't exist results in
|
||||
* undefined behavior.<br/>
|
||||
* An assertion will abort the execution at runtime in debug mode in case of
|
||||
* invalid requests.
|
||||
*
|
||||
* @tparam Type Type of object to get.
|
||||
* @return A valid reference to the object in the context of the registry.
|
||||
*/
|
||||
template<typename Type>
|
||||
const Type & ctx() const ENTT_NOEXCEPT {
|
||||
const auto *instance = try_ctx<Type>();
|
||||
assert(instance);
|
||||
return *instance;
|
||||
}
|
||||
|
||||
/*! @copydoc ctx */
|
||||
template<typename Type>
|
||||
Type * ctx() ENTT_NOEXCEPT {
|
||||
return const_cast<Type *>(std::as_const(*this).template ctx<Type>());
|
||||
inline Type & ctx() ENTT_NOEXCEPT {
|
||||
return const_cast<Type &>(std::as_const(*this).template ctx<Type>());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -35,42 +35,45 @@ struct listener {
|
||||
TEST(Registry, Context) {
|
||||
entt::registry registry;
|
||||
|
||||
ASSERT_EQ(registry.ctx<char>(), nullptr);
|
||||
ASSERT_EQ(registry.ctx<int>(), nullptr);
|
||||
ASSERT_EQ(registry.ctx<double>(), nullptr);
|
||||
ASSERT_EQ(registry.try_ctx<char>(), nullptr);
|
||||
ASSERT_EQ(registry.try_ctx<int>(), nullptr);
|
||||
ASSERT_EQ(registry.try_ctx<double>(), nullptr);
|
||||
|
||||
registry.set<char>();
|
||||
registry.set<int>();
|
||||
registry.set<double>();
|
||||
|
||||
ASSERT_NE(registry.ctx<char>(), nullptr);
|
||||
ASSERT_NE(registry.ctx<int>(), nullptr);
|
||||
ASSERT_NE(registry.ctx<double>(), nullptr);
|
||||
ASSERT_NE(registry.try_ctx<char>(), nullptr);
|
||||
ASSERT_NE(registry.try_ctx<int>(), nullptr);
|
||||
ASSERT_NE(registry.try_ctx<double>(), nullptr);
|
||||
|
||||
registry.unset<int>();
|
||||
registry.unset<double>();
|
||||
|
||||
ASSERT_NE(registry.ctx<char>(), nullptr);
|
||||
ASSERT_EQ(registry.ctx<int>(), nullptr);
|
||||
ASSERT_EQ(registry.ctx<double>(), nullptr);
|
||||
ASSERT_NE(registry.try_ctx<char>(), nullptr);
|
||||
ASSERT_EQ(registry.try_ctx<int>(), nullptr);
|
||||
ASSERT_EQ(registry.try_ctx<double>(), nullptr);
|
||||
|
||||
registry.set<char>('c');
|
||||
registry.set<int>(42);
|
||||
registry.set<double>(1.);
|
||||
|
||||
ASSERT_EQ(*registry.ctx<char>(), 'c');
|
||||
ASSERT_NE(registry.ctx<char>(), nullptr);
|
||||
ASSERT_EQ(registry.ctx<char>(), 'c');
|
||||
ASSERT_NE(registry.try_ctx<char>(), nullptr);
|
||||
ASSERT_EQ(registry.try_ctx<char>(), ®istry.ctx<char>());
|
||||
ASSERT_EQ(registry.ctx<char>(), std::as_const(registry).ctx<char>());
|
||||
|
||||
ASSERT_EQ(*registry.ctx<int>(), 42);
|
||||
ASSERT_NE(registry.ctx<int>(), nullptr);
|
||||
ASSERT_EQ(registry.ctx<int>(), 42);
|
||||
ASSERT_NE(registry.try_ctx<int>(), nullptr);
|
||||
ASSERT_EQ(registry.try_ctx<int>(), ®istry.ctx<int>());
|
||||
ASSERT_EQ(registry.ctx<int>(), std::as_const(registry).ctx<int>());
|
||||
|
||||
ASSERT_EQ(*registry.ctx<double>(), 1.);
|
||||
ASSERT_NE(registry.ctx<double>(), nullptr);
|
||||
ASSERT_EQ(registry.ctx<double>(), 1.);
|
||||
ASSERT_NE(registry.try_ctx<double>(), nullptr);
|
||||
ASSERT_EQ(registry.try_ctx<double>(), ®istry.ctx<double>());
|
||||
ASSERT_EQ(registry.ctx<double>(), std::as_const(registry).ctx<double>());
|
||||
|
||||
ASSERT_EQ(registry.ctx<float>(), nullptr);
|
||||
ASSERT_EQ(registry.try_ctx<float>(), nullptr);
|
||||
}
|
||||
|
||||
TEST(Registry, Types) {
|
||||
|
||||
Reference in New Issue
Block a user