registry: rebind pools from move constructor/assignment operator

This commit is contained in:
Michele Caini
2021-02-15 18:11:02 +01:00
parent ea1f010b1a
commit 91db153710
2 changed files with 81 additions and 4 deletions

View File

@@ -115,6 +115,7 @@ class basic_registry {
if(auto &&pdata = pools[index]; !pdata.pool) {
pdata.pool.reset(new storage_type<Component>());
pdata.poly = std::ref(*static_cast<storage_type<Component> *>(pdata.pool.get()));
pdata.pool->payload(this);
}
return static_cast<storage_type<Component> *>(pools[index].pool.get());
@@ -146,6 +147,14 @@ class basic_registry {
available = entity_type{entt};
}
void rebind_pools() ENTT_NOEXCEPT {
for(auto &&pdata: pools) {
if(pdata.pool) {
pdata.pool->payload(this);
}
}
}
public:
/*! @brief Underlying entity identifier. */
using entity_type = Entity;
@@ -177,11 +186,38 @@ public:
/*! @brief Default constructor. */
basic_registry() = default;
/*! @brief Default move constructor. */
basic_registry(basic_registry &&) = default;
/**
* @brief Move constructor.
* @param other The instance to move from.
*/
basic_registry(basic_registry &&other) ENTT_NOEXCEPT
: vars{std::move(other.vars)},
pools{std::move(other.pools)},
groups{std::move(other.groups)},
entities{std::move(other.entities)},
available{other.available}
{
rebind_pools();
}
/*! @brief Default move assignment operator. @return This registry. */
basic_registry & operator=(basic_registry &&) = default;
/**
* @brief Move assignment operator.
* @param other The instance to assign from.
* @return This registry.
*/
basic_registry & operator=(basic_registry &&other) ENTT_NOEXCEPT {
if(this != &other) {
vars = std::move(other.vars);
pools = std::move(other.pools);
groups = std::move(other.groups);
entities = std::move(other.entities);
available = other.available;
rebind_pools();
}
return *this;
}
/**
* @brief Prepares a pool for the given type if required.

View File

@@ -42,6 +42,14 @@ struct listener {
int counter{0};
};
struct owner {
void receive(const entt::registry &ref) {
parent = &ref;
}
const entt::registry *parent{nullptr};
};
TEST(Registry, Context) {
entt::registry registry;
@@ -258,6 +266,39 @@ TEST(Registry, Functionalities) {
ASSERT_EQ(registry.capacity<char>(), 0u);
}
TEST(Registry, Move) {
entt::registry registry;
const auto entity = registry.create();
owner test{};
registry.on_construct<int>().connect<&owner::receive>(test);
registry.on_destroy<int>().connect<&owner::receive>(test);
ASSERT_EQ(test.parent, nullptr);
registry.emplace<int>(entity);
ASSERT_EQ(test.parent, &registry);
entt::registry other{std::move(registry)};
other.remove<int>(entity);
registry.emplace<int>(registry.create(entity));
ASSERT_EQ(test.parent, &other);
registry = std::move(other);
registry.emplace<int>(entity);
registry.emplace<int>(registry.create(entity));
ASSERT_EQ(test.parent, &registry);
test.parent = nullptr;
registry = std::move(registry);
registry.remove<int>(entity);
ASSERT_EQ(test.parent, &registry);
}
TEST(Registry, ReplaceAggregate) {
entt::registry registry;
const auto entity = registry.create();