registry: added discard to free explicitly a pool
This commit is contained in:
1
TODO
1
TODO
@@ -25,6 +25,5 @@
|
||||
- ::group improve, reduce code
|
||||
|
||||
* Mission: get rid of named types
|
||||
- add discard pool functionality (+ test)
|
||||
- update doc: dispatcher, emitter, registry, meta, across boundaries
|
||||
- review and suppress warnings, if any
|
||||
|
||||
@@ -147,7 +147,7 @@ class basic_registry {
|
||||
};
|
||||
|
||||
struct pool_data {
|
||||
ENTT_ID_TYPE id;
|
||||
ENTT_ID_TYPE type_id;
|
||||
std::unique_ptr<sparse_set<Entity>> pool;
|
||||
void(* assure)(basic_registry &, const sparse_set<Entity> &);
|
||||
void(* remove)(sparse_set<Entity> &, basic_registry &, const Entity);
|
||||
@@ -213,15 +213,15 @@ class basic_registry {
|
||||
static_assert(std::is_same_v<Component, std::decay_t<Component>>);
|
||||
static std::size_t index{pools.size()};
|
||||
|
||||
if(!(index < pools.size()) || pools[index].id != type_id_v<Component>) {
|
||||
if(!(index < pools.size()) || pools[index].type_id != type_id_v<Component>) {
|
||||
index = std::find_if(pools.cbegin(), pools.cend(), [](auto &&cpool) {
|
||||
return cpool.id == type_id_v<Component>;
|
||||
return cpool.type_id == type_id_v<Component>;
|
||||
}) - pools.cbegin();
|
||||
|
||||
if(index == pools.size()) {
|
||||
auto &&pdata = pools.emplace_back();
|
||||
|
||||
pdata.id = type_id_v<Component>;
|
||||
pdata.type_id = type_id_v<Component>;
|
||||
pdata.pool = std::make_unique<pool_type<Component>>(std::forward<Args>(args)...);
|
||||
|
||||
pdata.remove = [](sparse_set<Entity> &cpool, basic_registry &owner, const Entity entt) {
|
||||
@@ -273,10 +273,21 @@ public:
|
||||
*/
|
||||
template<typename Component, typename... Args>
|
||||
void prepare(Args &&... args) {
|
||||
ENTT_ASSERT(std::none_of(pools.cbegin(), pools.cend(), [](auto &&pdata) { return pdata.id == type_id_v<Component>; }));
|
||||
ENTT_ASSERT(std::none_of(pools.cbegin(), pools.cend(), [](auto &&pdata) { return pdata.type_id == type_id_v<Component>; }));
|
||||
assure<Component>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Discards the pools for the given components.
|
||||
* @tparam Component Types of components for which to discard the pools.
|
||||
*/
|
||||
template<typename... Component>
|
||||
void discard() {
|
||||
pools.erase(std::remove_if(pools.begin(), pools.end(), [](auto &&pdata) {
|
||||
return ((pdata.type_id == type_id_v<Component>) || ...);
|
||||
}), pools.end());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of existing components of the given type.
|
||||
* @tparam Component Type of component of which to return the size.
|
||||
@@ -1425,7 +1436,7 @@ public:
|
||||
|
||||
std::transform(first, last, selected.begin(), [this](const auto ctype) {
|
||||
const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&pdata) {
|
||||
return pdata.id == ctype;
|
||||
return pdata.type_id == ctype;
|
||||
});
|
||||
|
||||
return it == pools.cend() ? nullptr : it->pool.get();
|
||||
@@ -1476,7 +1487,7 @@ public:
|
||||
|
||||
if constexpr(sizeof...(Component) == 0) {
|
||||
for(size_type pos{}; pos < pools.size(); ++pos) {
|
||||
if(const auto &pdata = pools[pos]; pdata.assure && ((pdata.id != type_id_v<Exclude>) && ...)) {
|
||||
if(const auto &pdata = pools[pos]; pdata.assure && ((pdata.type_id != type_id_v<Exclude>) && ...)) {
|
||||
pdata.assure(other, *pdata.pool);
|
||||
}
|
||||
}
|
||||
@@ -1529,7 +1540,7 @@ public:
|
||||
void stomp(const entity_type dst, const basic_registry &other, const entity_type src, exclude_t<Exclude...> = {}) {
|
||||
if constexpr(sizeof...(Component) == 0) {
|
||||
for(size_type pos{}; pos < other.pools.size(); ++pos) {
|
||||
if(const auto &pdata = other.pools[pos]; pdata.stomp && ((pdata.id != type_id_v<Exclude>) && ...) && pdata.pool->has(src)) {
|
||||
if(const auto &pdata = other.pools[pos]; pdata.stomp && ((pdata.type_id != type_id_v<Exclude>) && ...) && pdata.pool->has(src)) {
|
||||
pdata.stomp(*this, dst, *pdata.pool, src);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,8 +99,8 @@ class dispatcher {
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Discards the pool for the given event.
|
||||
* @tparam Event Type of event for which to discard the pool.
|
||||
* @brief Discards the pools for the given events.
|
||||
* @tparam Event Types of events for which to discard the pools.
|
||||
*/
|
||||
template<typename... Event>
|
||||
void discard() {
|
||||
|
||||
@@ -187,8 +187,8 @@ public:
|
||||
emitter & operator=(emitter &&) = default;
|
||||
|
||||
/**
|
||||
* @brief Discards the pool for the given event.
|
||||
* @tparam Event Type of event for which to discard the pool.
|
||||
* @brief Discards the pools for the given events.
|
||||
* @tparam Event Types of events for which to discard the pools.
|
||||
*/
|
||||
template<typename... Event>
|
||||
void discard() {
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
#include <entt/entity/registry.hpp>
|
||||
#include "types.h"
|
||||
|
||||
ENTT_API void update_position(int delta, entt::registry ®istry) {
|
||||
registry.view<position, velocity>().each([delta](auto &pos, auto &vel) {
|
||||
pos.x += delta * vel.dx;
|
||||
pos.y += delta * vel.dy;
|
||||
ENTT_API void update_position(entt::registry ®istry) {
|
||||
registry.view<position, velocity>().each([](auto &pos, auto &vel) {
|
||||
pos.x += 16 * vel.dx;
|
||||
pos.y += 16 * vel.dy;
|
||||
});
|
||||
}
|
||||
|
||||
ENTT_API void assign_velocity(int vel, entt::registry ®istry) {
|
||||
ENTT_API void assign_velocity(entt::registry ®istry) {
|
||||
for(auto entity: registry.view<position>()) {
|
||||
registry.assign<velocity>(entity, vel, vel);
|
||||
registry.assign<velocity>(entity, 1., 1.);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,26 +4,24 @@
|
||||
#include <entt/entity/registry.hpp>
|
||||
#include "types.h"
|
||||
|
||||
ENTT_API void update_position(int, entt::registry &);
|
||||
ENTT_API void assign_velocity(int, entt::registry &);
|
||||
ENTT_API void update_position(entt::registry &);
|
||||
ENTT_API void assign_velocity(entt::registry &);
|
||||
|
||||
TEST(Lib, Registry) {
|
||||
entt::registry registry;
|
||||
|
||||
for(auto i = 0; i < 3; ++i) {
|
||||
const auto entity = registry.create();
|
||||
registry.assign<position>(entity, i, i+1);
|
||||
registry.assign<position>(entity, i, i);
|
||||
}
|
||||
|
||||
assign_velocity(2, registry);
|
||||
assign_velocity(registry);
|
||||
update_position(registry);
|
||||
|
||||
ASSERT_EQ(registry.size<position>(), 3u);
|
||||
ASSERT_EQ(registry.size<velocity>(), 3u);
|
||||
|
||||
update_position(1, registry);
|
||||
ASSERT_EQ(registry.size<position>(), registry.size<velocity>());
|
||||
|
||||
registry.view<position>().each([](auto entity, auto &position) {
|
||||
ASSERT_EQ(position.x, entt::to_integral(entity) + 2);
|
||||
ASSERT_EQ(position.y, entt::to_integral(entity) + 3);
|
||||
ASSERT_EQ(position.x, entt::to_integral(entity) + 16);
|
||||
ASSERT_EQ(position.y, entt::to_integral(entity) + 16);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ struct ENTT_API position {
|
||||
};
|
||||
|
||||
struct ENTT_API velocity {
|
||||
int dx;
|
||||
int dy;
|
||||
double dx;
|
||||
double dy;
|
||||
};
|
||||
|
||||
#endif // ENTT_LIB_REGISTRY_TYPES_H
|
||||
|
||||
@@ -10,23 +10,19 @@ TEST(Lib, Registry) {
|
||||
|
||||
for(auto i = 0; i < 3; ++i) {
|
||||
const auto entity = registry.create();
|
||||
registry.assign<position>(entity, i, i+1);
|
||||
registry.assign<position>(entity, i, i);
|
||||
}
|
||||
|
||||
ASSERT_FALSE(registry.empty<position>());
|
||||
ASSERT_TRUE(registry.empty<velocity>());
|
||||
|
||||
cr_plugin ctx;
|
||||
ctx.userdata = ®istry;
|
||||
cr_plugin_load(ctx, PLUGIN);
|
||||
cr_plugin_update(ctx);
|
||||
|
||||
ASSERT_FALSE(registry.empty<position>());
|
||||
ASSERT_FALSE(registry.empty<velocity>());
|
||||
ASSERT_EQ(registry.size<position>(), registry.size<velocity>());
|
||||
|
||||
registry.view<position>().each([](auto entity, auto &position) {
|
||||
ASSERT_EQ(position.x, entt::to_integral(entity) + 2);
|
||||
ASSERT_EQ(position.y, entt::to_integral(entity) + 3);
|
||||
ASSERT_EQ(position.x, entt::to_integral(entity) + 16);
|
||||
ASSERT_EQ(position.y, entt::to_integral(entity) + 16);
|
||||
});
|
||||
|
||||
cr_plugin_close(ctx);
|
||||
|
||||
@@ -7,21 +7,22 @@ CR_EXPORT int cr_main(cr_plugin *ctx, cr_op operation) {
|
||||
case CR_STEP:
|
||||
[ctx]() {
|
||||
auto *registry = static_cast<entt::registry *>(ctx->userdata);
|
||||
registry->reset<velocity>();
|
||||
|
||||
for(auto entity: registry->view<position>()) {
|
||||
registry->assign<velocity>(entity, 1, 1);
|
||||
registry->assign<velocity>(entity, 1., 1.);
|
||||
}
|
||||
|
||||
registry->view<position, velocity>().each([](auto &pos, auto &vel) {
|
||||
pos.x += 2 * vel.dx;
|
||||
pos.y += 2 * vel.dy;
|
||||
pos.x += 16 * vel.dx;
|
||||
pos.y += 16 * vel.dy;
|
||||
});
|
||||
}();
|
||||
break;
|
||||
case CR_CLOSE:
|
||||
static_cast<entt::registry *>(ctx->userdata)->discard<velocity>();
|
||||
break;
|
||||
case CR_LOAD:
|
||||
case CR_UNLOAD:
|
||||
case CR_CLOSE:
|
||||
// nothing to do here, this is only a test.
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ struct position {
|
||||
};
|
||||
|
||||
struct velocity {
|
||||
int dx;
|
||||
int dy;
|
||||
double dx;
|
||||
double dy;
|
||||
};
|
||||
|
||||
#endif // ENTT_PLUGIN_REGISTRY_TYPES_H
|
||||
|
||||
Reference in New Issue
Block a user