registry: use entt::any to store context variables

This commit is contained in:
Michele Caini
2021-02-04 09:21:27 +01:00
parent 146faa6008
commit 1912350cc6
2 changed files with 15 additions and 19 deletions

1
TODO
View File

@@ -18,6 +18,7 @@
- ...
WIP:
* HP: registry::ctx can return entt::any objects directly
* HP: merge view and view pack
* HP: invalid view auto-refresh
* HP: paginate pools

View File

@@ -13,6 +13,7 @@
#include <vector>
#include "../config/config.h"
#include "../core/algorithm.hpp"
#include "../core/any.hpp"
#include "../core/fwd.hpp"
#include "../core/type_info.hpp"
#include "../core/type_traits.hpp"
@@ -103,11 +104,6 @@ class basic_registry {
bool (* exclude)(const id_type) ENTT_NOEXCEPT;
};
struct variable_data {
type_info info;
std::unique_ptr<void, void(*)(void *)> value;
};
template<typename Component>
[[nodiscard]] storage_type<Component> * assure() {
const auto index = type_seq<Component>::value();
@@ -1485,8 +1481,8 @@ public:
template<typename Type, typename... Args>
Type & set(Args &&... args) {
unset<Type>();
vars.push_back(variable_data{type_id<Type>(), { new Type{std::forward<Args>(args)...}, [](void *instance) { delete static_cast<Type *>(instance); } }});
return *static_cast<Type *>(vars.back().value.get());
vars.push_back(entt::any{std::in_place_type<Type>, std::forward<Args>(args)...});
return any_cast<Type &>(vars.back());
}
/**
@@ -1495,9 +1491,7 @@ public:
*/
template<typename Type>
void unset() {
vars.erase(std::remove_if(vars.begin(), vars.end(), [](auto &&var) {
return var.info.hash() == type_hash<Type>::value();
}), vars.end());
vars.erase(std::remove_if(vars.begin(), vars.end(), [type = type_id<Type>()](auto &&var) { return var.type() == type; }), vars.end());
}
/**
@@ -1525,14 +1519,15 @@ public:
*/
template<typename Type>
[[nodiscard]] const Type * try_ctx() const {
auto it = std::find_if(vars.cbegin(), vars.cend(), [](auto &&var) { return var.info.hash() == type_hash<Type>::value(); });
return it == vars.cend() ? nullptr : static_cast<const Type *>(it->value.get());
auto it = std::find_if(vars.cbegin(), vars.cend(), [type = type_id<Type>()](auto &&var) { return var.type() == type; });
return it == vars.cend() ? nullptr : any_cast<const Type>(&*it);
}
/*! @copydoc try_ctx */
template<typename Type>
[[nodiscard]] Type * try_ctx() {
return const_cast<Type *>(std::as_const(*this).template try_ctx<Type>());
auto it = std::find_if(vars.begin(), vars.end(), [type = type_id<Type>()](auto &&var) { return var.type() == type; });
return it == vars.end() ? nullptr : any_cast<Type>(&*it);
}
/**
@@ -1547,15 +1542,15 @@ public:
*/
template<typename Type>
[[nodiscard]] const Type & ctx() const {
const auto *instance = try_ctx<Type>();
ENTT_ASSERT(instance);
return *instance;
auto it = std::find_if(vars.cbegin(), vars.cend(), [type = type_id<Type>()](auto &&var) { return var.type() == type; });
return (ENTT_ASSERT(it != vars.cend()), any_cast<const Type &>(*it));
}
/*! @copydoc ctx */
template<typename Type>
[[nodiscard]] Type & ctx() {
return const_cast<Type &>(std::as_const(*this).template ctx<Type>());
auto it = std::find_if(vars.begin(), vars.end(), [type = type_id<Type>()](auto &&var) { return var.type() == type; });
return (ENTT_ASSERT(it != vars.end()), any_cast<Type &>(*it));
}
/**
@@ -1582,15 +1577,15 @@ public:
template<typename Func>
void ctx(Func func) const {
for(auto pos = vars.size(); pos; --pos) {
func(vars[pos-1].info);
func(vars[pos-1].type());
}
}
private:
std::vector<entt::any> vars{};
std::vector<pool_data> pools{};
std::vector<group_data> groups{};
std::vector<entity_type> entities{};
std::vector<variable_data> vars{};
entity_type available{null};
};