added exclusion list to registry::clone (close #286)

This commit is contained in:
Michele Caini
2019-08-12 15:43:28 +02:00
parent 9e9e3d43a8
commit e0e51b51b7
2 changed files with 37 additions and 3 deletions

View File

@@ -1447,6 +1447,10 @@ public:
* If no components are provided, the registry will try to clone all the
* existing pools.
*
* This feature supports exclusion lists. The excluded types have higher
* priority than those indicated for cloning. An excluded type will never be
* cloned.
*
* @note
* There isn't an efficient way to know if all the entities are assigned at
* least one component once copied. Therefore, there may be orphans. It is
@@ -1465,17 +1469,21 @@ public:
* be cloned.
*
* @tparam Component Types of components to clone.
* @tparam Exclude Types of components not to be cloned.
* @return A fresh copy of the registry.
*/
template<typename... Component>
basic_registry clone() const {
template<typename... Component, typename... Exclude>
basic_registry clone(exclude_t<Exclude...> = {}) const {
static_assert(std::conjunction_v<std::is_copy_constructible<Component>...>);
basic_registry other;
other.pools.resize(pools.size());
for(auto pos = pools.size(); pos; --pos) {
if(auto &pdata = pools[pos-1]; pdata.pool && (!sizeof...(Component) || ... || (pdata.runtime_type == to_integer(type<Component>())))) {
if(auto &pdata = pools[pos-1]; pdata.pool
&& (!sizeof...(Component) || ... || (pdata.runtime_type == to_integer(type<Component>())))
&& !((pdata.runtime_type == to_integer(type<Exclude>())) || ...))
{
auto &curr = other.pools[pos-1];
curr.clone = pdata.clone;
curr.remove = pdata.remove;

View File

@@ -1377,6 +1377,32 @@ TEST(Registry, Clone) {
other.reset();
}
TEST(Registry, CloneExclude) {
entt::registry registry;
entt::registry other;
const auto entity = registry.create();
registry.assign<int>(entity);
registry.assign<char>(entity);
other = registry.clone<int, char>(entt::exclude<char>);
ASSERT_TRUE(other.has(entity));
ASSERT_TRUE(other.has<int>(entity));
ASSERT_FALSE(other.has<char>(entity));
other = registry.clone(entt::exclude<int>);
ASSERT_TRUE(other.has(entity));
ASSERT_FALSE(other.has<int>(entity));
ASSERT_TRUE(other.has<char>(entity));
other = registry.clone(entt::exclude<int, char>);
ASSERT_TRUE(other.has(entity));
ASSERT_TRUE(other.orphan(entity));
}
TEST(Registry, CloneMoveOnlyComponent) {
entt::registry registry;
const auto entity = registry.create();