registry: rebind pools from move constructor/assignment operator
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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, ®istry);
|
||||
|
||||
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, ®istry);
|
||||
|
||||
test.parent = nullptr;
|
||||
registry = std::move(registry);
|
||||
registry.remove<int>(entity);
|
||||
|
||||
ASSERT_EQ(test.parent, ®istry);
|
||||
}
|
||||
|
||||
TEST(Registry, ReplaceAggregate) {
|
||||
entt::registry registry;
|
||||
const auto entity = registry.create();
|
||||
|
||||
Reference in New Issue
Block a user