diff --git a/src/entt/entity/group.hpp b/src/entt/entity/group.hpp index b46c45b85..7d8a6b3e5 100644 --- a/src/entt/entity/group.hpp +++ b/src/entt/entity/group.hpp @@ -734,7 +734,8 @@ public: }, std::forward(args)...); } else { algo(copy.rbegin(), copy.rend(), [compare = std::move(compare), this](const auto lhs, const auto rhs) { - return compare(from_index(lhs)..., from_index(rhs)...); + // useless this-> used to suppress a warning with clang + return compare(this->from_index(lhs)..., this->from_index(rhs)...); }, std::forward(args)...); } diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index 54761a910..fc9840730 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -63,15 +63,19 @@ class basic_registry { template struct pool_handler: sparse_set { - using underlying_type = sparse_set; - sigh on_construct; sigh on_replace; sigh on_destroy; void *group{}; + pool_handler() ENTT_NOEXCEPT = default; + + pool_handler(const sparse_set &other) + : sparse_set{other} + {} + template - Component & construct(basic_registry ®istry, const Entity entt, Args &&... args) { + Component & assign(basic_registry ®istry, const Entity entt, Args &&... args) { auto &component = sparse_set::construct(entt, std::forward(args)...); on_construct.publish(registry, entt, component); return component; @@ -90,7 +94,7 @@ class basic_registry { return component; } - void destroy(basic_registry ®istry, const Entity entt) { + void remove(basic_registry ®istry, const Entity entt) { on_destroy.publish(registry, entt); sparse_set::destroy(entt); } @@ -178,7 +182,7 @@ class basic_registry { struct pool_data { std::unique_ptr> pool; std::unique_ptr> (* clone)(const sparse_set &); - void (* destroy)(basic_registry &, const Entity); + void (* remove)(basic_registry &, const Entity); ENTT_ID_TYPE runtime_type; }; @@ -259,20 +263,17 @@ class basic_registry { pdata->runtime_type = ctype; pdata->pool = std::make_unique>(); - pdata->clone = +[](const sparse_set &cpool) -> std::unique_ptr> { + pdata->clone = +[](const sparse_set &other) -> std::unique_ptr> { if constexpr(std::is_copy_constructible_v>) { - using underlying_type = typename pool_type::underlying_type; - std::unique_ptr ptr = std::make_unique>(); - *ptr = static_cast(cpool); - return std::move(ptr); + return std::make_unique>(static_cast &>(other)); } else { ENTT_ASSERT(false); return nullptr; } }; - pdata->destroy = [](basic_registry ®istry, const Entity entt) { - registry.pool()->destroy(registry, entt); + pdata->remove = [](basic_registry ®istry, const Entity entt) { + registry.pool()->remove(registry, entt); }; } @@ -635,7 +636,7 @@ public: for(auto pos = pools.size(); pos; --pos) { if(auto &pdata = pools[pos-1]; pdata.pool && pdata.pool->has(entity)) { - pdata.destroy(*this, entity); + pdata.remove(*this, entity); } }; @@ -658,7 +659,7 @@ public: if(auto &pdata = pools[pos-1]; pdata.pool) { std::for_each(first, last, [&pdata, this](const auto entity) { if(pdata.pool->has(entity)) { - pdata.destroy(*this, entity); + pdata.remove(*this, entity); } }); } @@ -695,7 +696,7 @@ public: template Component & assign(const entity_type entity, Args &&... args) { ENTT_ASSERT(valid(entity)); - return assure()->construct(*this, entity, std::forward(args)...); + return assure()->assign(*this, entity, std::forward(args)...); } /** @@ -714,7 +715,7 @@ public: template void remove(const entity_type entity) { ENTT_ASSERT(valid(entity)); - pool()->destroy(*this, entity); + pool()->remove(*this, entity); } /** @@ -800,7 +801,7 @@ public: ENTT_ASSERT(valid(entity)); auto *cpool = assure(); auto *comp = cpool->try_get(entity); - return comp ? *comp : cpool->construct(*this, entity, std::forward(args)...); + return comp ? *comp : cpool->assign(*this, entity, std::forward(args)...); } /** @@ -887,7 +888,7 @@ public: template Component & assign_or_replace(const entity_type entity, Args &&... args) { auto *cpool = assure(); - return cpool->has(entity) ? cpool->replace(*this, entity, std::forward(args)...) : cpool->construct(*this, entity, std::forward(args)...); + return cpool->has(entity) ? cpool->replace(*this, entity, std::forward(args)...) : cpool->assign(*this, entity, std::forward(args)...); } /** @@ -1083,7 +1084,7 @@ public: ENTT_ASSERT(valid(entity)); if(auto *cpool = assure(); cpool->has(entity)) { - cpool->destroy(*this, entity); + cpool->remove(*this, entity); } } @@ -1102,7 +1103,7 @@ public: cpool->reset(); } else { for(const auto entity: static_cast &>(*cpool)) { - cpool->destroy(*this, entity); + cpool->remove(*this, entity); } } } @@ -1307,7 +1308,7 @@ public: groups.push_back(group_data{ { sizeof...(Owned), sizeof...(Get), sizeof...(Exclude) }, - decltype(group_data::group){new handler_type, +[](void *gptr) { delete static_cast(gptr); }}, + decltype(group_data::group){new handler_type{}, +[](void *gptr) { delete static_cast(gptr); }}, +[](const ENTT_ID_TYPE *other) { const std::size_t ctypes[] = { type()..., type()..., type()... }; return std::equal(std::begin(ctypes), std::end(ctypes), other); diff --git a/test/entt/entity/registry.cpp b/test/entt/entity/registry.cpp index 258404580..d70b9ec10 100644 --- a/test/entt/entity/registry.cpp +++ b/test/entt/entity/registry.cpp @@ -1292,3 +1292,10 @@ TEST(Registry, BatchCreateAmbiguousCall) { // this should work, no other tests required registry.assign(entity, foo, bar); } + +TEST(Registry, MoveOnlyComponent) { + // the purpose is to ensure that move only components are always accepted + entt::registry registry; + const auto entity = registry.create(); + registry.assign>(entity); +}