more on context variables
This commit is contained in:
1
TODO
1
TODO
@@ -21,3 +21,4 @@
|
||||
* add a sort of "fast each" for when users know they are not to add/remove components, it can use directly raw access and improve even further performance
|
||||
* types defined at runtime that refer to the same compile-time type (but to different pools) are possible, the library is almost there
|
||||
* view/group iterators that return entities and components? I'd still like to have it :-)
|
||||
* use try_get in the multi component view (each), it should have better perf
|
||||
|
||||
@@ -838,15 +838,16 @@ newly created instance later on:
|
||||
// creates a new context variable initialized with the given values
|
||||
registry.set<my_type>(42, 'c');
|
||||
|
||||
// gets a context variable associated with a registry
|
||||
auto &var = registry.ctx<my_type>();
|
||||
if(auto *var = registry.ctx<my_type>(); var) {
|
||||
// uses the context variable associated with a registry, if any
|
||||
}
|
||||
```
|
||||
|
||||
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 requires that the context variable exist to work properly and doesn't
|
||||
create it silently under the hood.
|
||||
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
|
||||
|
||||
|
||||
@@ -1605,7 +1605,8 @@ public:
|
||||
std::swap(vars[ctype], vars.back());
|
||||
wrapper = vars[ctype].get();
|
||||
} else if(!wrapper) {
|
||||
wrapper = vars.emplace_back(std::make_unique<type_wrapper<Type>>()).get();
|
||||
vars[ctype] = std::make_unique<type_wrapper<Type>>();
|
||||
wrapper = vars[ctype].get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1617,19 +1618,13 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a reference to an object in the context of the registry.
|
||||
*
|
||||
* @warning
|
||||
* Attempting to get an object that doesn't exist in the context of the
|
||||
* registry results in undefined behavior.<br/>
|
||||
* An assertion will abort the execution at runtime in debug mode if the
|
||||
* object isn't part of the context of the registry.
|
||||
*
|
||||
* @brief Returns a pointer to an object in the context of the registry.
|
||||
* @tparam Type Type of object to get.
|
||||
* @return A reference to the object.
|
||||
* @return A pointer to the object if it exists in the context of the
|
||||
* registry, a null pointer otherwise.
|
||||
*/
|
||||
template<typename Type>
|
||||
const Type & ctx() const ENTT_NOEXCEPT {
|
||||
const Type * ctx() const ENTT_NOEXCEPT {
|
||||
const auto ctype = runtime_type<Type, context_family>();
|
||||
|
||||
if constexpr(is_named_type_v<Type>) {
|
||||
@@ -1637,18 +1632,17 @@ public:
|
||||
return candidate && candidate->runtime_type == ctype;
|
||||
});
|
||||
|
||||
assert(it != vars.cend());
|
||||
return static_cast<const type_wrapper<Type> *>(it->get())->value;
|
||||
return (it == vars.cend()) ? nullptr : &static_cast<const type_wrapper<Type> &>(**it).value;
|
||||
} else {
|
||||
assert(ctype < vars.size() && vars[ctype] && vars[ctype]->runtime_type == ctype);
|
||||
return static_cast<const type_wrapper<Type> *>(vars[ctype].get())->value;
|
||||
const bool valid = ctype < vars.size() && vars[ctype] && vars[ctype]->runtime_type == ctype;
|
||||
return valid ? &static_cast<const type_wrapper<Type> &>(*vars[ctype]).value : nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*! @copydoc ctx */
|
||||
template<typename Type>
|
||||
Type & ctx() ENTT_NOEXCEPT {
|
||||
return const_cast<Type &>(std::as_const(*this).template ctx<Type>());
|
||||
Type * ctx() ENTT_NOEXCEPT {
|
||||
return const_cast<Type *>(std::as_const(*this).template ctx<Type>());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -35,22 +35,24 @@ struct listener {
|
||||
TEST(Registry, Context) {
|
||||
entt::registry registry;
|
||||
|
||||
const auto &ivalue = registry.set<int>(0);
|
||||
const auto &cvalue = registry.set<char>('c');
|
||||
const auto &dvalue = registry.set<double>(1.);
|
||||
registry.set<char>('c');
|
||||
registry.set<int>(0);
|
||||
registry.set<double>(1.);
|
||||
registry.set<int>(42);
|
||||
|
||||
ASSERT_EQ(ivalue, 42);
|
||||
ASSERT_EQ(ivalue, registry.ctx<int>());
|
||||
ASSERT_EQ(registry.ctx<int>(), std::as_const(registry).ctx<int>());
|
||||
|
||||
ASSERT_EQ(cvalue, 'c');
|
||||
ASSERT_EQ(cvalue, registry.ctx<char>());
|
||||
ASSERT_EQ(*registry.ctx<char>(), 'c');
|
||||
ASSERT_NE(registry.ctx<char>(), nullptr);
|
||||
ASSERT_EQ(registry.ctx<char>(), std::as_const(registry).ctx<char>());
|
||||
|
||||
ASSERT_EQ(dvalue, 1.);
|
||||
ASSERT_EQ(dvalue, registry.ctx<double>());
|
||||
ASSERT_EQ(*registry.ctx<int>(), 42);
|
||||
ASSERT_NE(registry.ctx<int>(), nullptr);
|
||||
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>(), std::as_const(registry).ctx<double>());
|
||||
|
||||
ASSERT_EQ(registry.ctx<float>(), nullptr);
|
||||
}
|
||||
|
||||
TEST(Registry, Types) {
|
||||
|
||||
Reference in New Issue
Block a user