registry no longer uses named types

This commit is contained in:
Michele Caini
2019-12-01 23:02:46 +01:00
parent 63a4e67174
commit c3b0fa6c93
2 changed files with 40 additions and 82 deletions

4
TODO
View File

@@ -42,9 +42,7 @@
* Mission: get rid of named types
- make it possible to use custom generators (eg for plugins)
- registry::ctx_variable can be removed
- dispatcher::wrapper_data can be removed
- emitter::handler_data can be removed
- registry::assure -> pool_type<T> &
- registry::group improve, reduce code
- Make the following parts work across boundaries (define proper macros):
* dispatcher

View File

@@ -157,7 +157,6 @@ class basic_registry {
void(* assure)(basic_registry &, const sparse_set<Entity> &);
void(* remove)(sparse_set<Entity> &, basic_registry &, const Entity);
void(* stomp)(basic_registry &, const Entity, const sparse_set<Entity> &, const Entity);
ENTT_ID_TYPE runtime_type;
};
struct group_data {
@@ -168,19 +167,19 @@ class basic_registry {
bool(* exclude)(const component) ENTT_NOEXCEPT;
};
struct ctx_variable {
std::unique_ptr<void, void(*)(void *)> value;
ENTT_ID_TYPE runtime_type;
struct basic_variable {
virtual ~basic_variable() = default;
};
template<typename Type, typename Family>
static ENTT_ID_TYPE runtime_type() ENTT_NOEXCEPT {
if constexpr(is_named_type_v<Type>) {
return named_type_traits_v<Type>;
} else {
return Family::template type<std::decay_t<Type>>;
}
}
template<typename Type>
struct variable_handler: basic_variable {
template<typename... Args>
variable_handler(Args &&... args)
: value{std::forward<Args>(args)...}
{}
Type value;
};
auto generate() {
Entity entt;
@@ -212,50 +211,30 @@ class basic_registry {
template<typename Component, typename... Args>
const pool_type<Component> * assure(Args &&... args) const {
const auto ctype = to_integer(type<Component>());
pool_data *pdata = nullptr;
if constexpr(is_named_type_v<Component>) {
const auto it = std::find_if(pools.begin(), pools.end(), [ctype](const auto &candidate) {
return candidate.runtime_type == ctype;
});
pdata = (it == pools.cend() ? &pools.emplace_back() : &(*it));
} else {
if(!(ctype < pools.size())) {
pools.resize(ctype+1);
} else if(pools[ctype].pool && pools[ctype].runtime_type != ctype) {
pools.emplace_back();
std::swap(pools[ctype], pools.back());
}
pdata = &pools[ctype];
if(!(ctype < pools.size())) {
pools.resize(ctype+1);
}
if constexpr(sizeof...(Args) != 0) {
ENTT_ASSERT(!pdata->pool || !pdata->pool->size());
pdata->pool.reset();
}
if(!pools[ctype].pool) {
pools[ctype].pool = std::make_unique<pool_type<Component>>(std::forward<Args>(args)...);
if(!pdata->pool) {
pdata->runtime_type = ctype;
pdata->pool = std::make_unique<pool_type<Component>>(std::forward<Args>(args)...);
pdata->remove = [](sparse_set<Entity> &cpool, basic_registry &owner, const Entity entt) {
pools[ctype].remove = [](sparse_set<Entity> &cpool, basic_registry &owner, const Entity entt) {
static_cast<pool_type<Component> &>(cpool).remove(owner, entt);
};
if constexpr(std::is_copy_constructible_v<std::decay_t<Component>>) {
pdata->assure = [](basic_registry &other, const sparse_set<Entity> &cpool) {
pools[ctype].assure = [](basic_registry &other, const sparse_set<Entity> &cpool) {
other.assure<Component>(static_cast<const pool_type<Component> &>(cpool));
};
pdata->stomp = [](basic_registry &other, const Entity dst, const sparse_set<Entity> &cpool, const Entity src) {
pools[ctype].stomp = [](basic_registry &other, const Entity dst, const sparse_set<Entity> &cpool, const Entity src) {
other.assign_or_replace<Component>(dst, static_cast<const pool_type<Component> &>(cpool).get(src));
};
}
}
return static_cast<pool_type<Component> *>(pdata->pool.get());
return static_cast<pool_type<Component> *>(pools[ctype].pool.get());
}
template<typename Component>
@@ -291,7 +270,7 @@ public:
*/
template<typename Component>
static component type() ENTT_NOEXCEPT {
return component{runtime_type<Component, component_family>()};
return component{component_family::template type<std::decay_t<Component>>};
}
/**
@@ -302,10 +281,7 @@ public:
*/
template<typename Component, typename... Args>
void prepare(Args &&... args) {
ENTT_ASSERT(std::none_of(pools.cbegin(), pools.cend(), [ctype = to_integer(type<Component>())](auto &&pdata) {
return pdata.pool && pdata.runtime_type == ctype;
}));
ENTT_ASSERT(to_integer(type<Component>()) < pools.size() || !pools[to_integer(type<Component>())].pool);
[[maybe_unused]] auto *cpool = assure<Component>(std::forward<Args>(args)...);
ENTT_ASSERT(cpool->size() == 0);
}
@@ -1453,11 +1429,7 @@ public:
std::vector<const sparse_set<Entity> *> selected(std::distance(first, last));
std::transform(first, last, selected.begin(), [this](const component ctype) {
auto it = std::find_if(pools.begin(), pools.end(), [ctype = to_integer(ctype)](const auto &pdata) {
return pdata.pool && pdata.runtime_type == ctype;
});
return it != pools.cend() && it->pool ? it->pool.get() : nullptr;
return to_integer(ctype) < pools.size() ? pools[to_integer(ctype)].pool.get() : nullptr;
});
return { std::move(selected) };
@@ -1504,11 +1476,11 @@ public:
other.entities = entities;
if constexpr(sizeof...(Component) == 0) {
std::for_each(pools.cbegin(), pools.cend(), [&other](const auto &pdata) {
if(pdata.assure && ((pdata.runtime_type != to_integer(type<Exclude>())) && ...)) {
for(size_type pos{}; pos < pools.size(); ++pos) {
if(const auto &pdata = pools[pos]; pdata.assure && ((pos != to_integer(type<Exclude>())) && ...)) {
pdata.assure(other, *pdata.pool);
}
});
}
} else {
static_assert(sizeof...(Exclude) == 0 && std::conjunction_v<std::is_copy_constructible<Component>...>);
(other.assure<Component>(*assure<Component>()), ...);
@@ -1557,11 +1529,11 @@ public:
template<typename... Component, typename... Exclude>
void stomp(const entity_type dst, const basic_registry &other, const entity_type src, exclude_t<Exclude...> = {}) {
if constexpr(sizeof...(Component) == 0) {
std::for_each(other.pools.cbegin(), other.pools.cend(), [this, dst, src](const auto &pdata) {
if(pdata.stomp && ((pdata.runtime_type != to_integer(type<Exclude>())) && ...) && pdata.pool->has(src)) {
for(size_type pos{}; pos < other.pools.size(); ++pos) {
if(const auto &pdata = other.pools[pos]; pdata.stomp && ((pos != to_integer(type<Exclude>())) && ...) && pdata.pool->has(src)) {
pdata.stomp(*this, dst, *pdata.pool, src);
}
});
}
} else {
static_assert(sizeof...(Exclude) == 0 && std::conjunction_v<std::is_copy_constructible<Component>...>);
(assign_or_replace<Component>(dst, other.template get<Component>(src)), ...);
@@ -1654,23 +1626,14 @@ public:
*/
template<typename Type, typename... Args>
Type & set(Args &&... args) {
const auto ctype = runtime_type<Type, context_family>();
auto it = std::find_if(vars.begin(), vars.end(), [ctype](const auto &candidate) {
return candidate.runtime_type == ctype;
});
const auto vtype = context_family::type<std::decay_t<Type>>;
if(it == vars.cend()) {
vars.push_back({
decltype(ctx_variable::value){new Type{std::forward<Args>(args)...}, [](void *ptr) { delete static_cast<Type *>(ptr); }},
ctype
});
it = std::prev(vars.end());
} else {
it->value.reset(new Type{std::forward<Args>(args)...});
if(!(vtype < vars.size())) {
vars.resize(vtype+1);
}
return *static_cast<Type *>(it->value.get());
vars[vtype] = std::make_unique<variable_handler<Type>>(std::forward<Args>(args)...);
return static_cast<variable_handler<Type> &>(*vars[vtype]).value;
}
/**
@@ -1679,9 +1642,9 @@ public:
*/
template<typename Type>
void unset() {
vars.erase(std::remove_if(vars.begin(), vars.end(), [](auto &var) {
return var.runtime_type == runtime_type<Type, context_family>();
}), vars.end());
if(const auto vtype = context_family::template type<std::decay_t<Type>>; vtype < vars.size()) {
vars[vtype].reset();
}
}
/**
@@ -1709,11 +1672,8 @@ public:
*/
template<typename Type>
const Type * try_ctx() const {
const auto it = std::find_if(vars.begin(), vars.end(), [](const auto &var) {
return var.runtime_type == runtime_type<Type, context_family>();
});
return (it == vars.cend()) ? nullptr : static_cast<const Type *>(it->value.get());
const auto vtype = context_family::type<std::decay_t<Type>>;
return vtype < vars.size() && vars[vtype] ? &static_cast<variable_handler<Type> &>(*vars[vtype]).value : nullptr;
}
/*! @copydoc try_ctx */
@@ -1750,7 +1710,7 @@ public:
private:
mutable std::vector<pool_data> pools{};
std::vector<group_data> groups{};
std::vector<ctx_variable> vars{};
std::vector<std::unique_ptr<basic_variable>> vars{};
std::vector<entity_type> entities{};
entity_type destroyed{null};
};