group: avoid swapping observed types - close #1100
This commit is contained in:
@@ -109,27 +109,28 @@ class group_handler<owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>> fin
|
||||
using base_type = std::common_type_t<typename Owned::base_type..., typename Get::base_type..., typename Exclude::base_type...>;
|
||||
using entity_type = typename base_type::entity_type;
|
||||
|
||||
void swap_elements(const std::size_t pos, const entity_type entt) {
|
||||
std::apply([pos, entt](auto *...cpool) { (cpool->swap_elements(cpool->data()[pos], entt), ...); }, pools);
|
||||
template<std::size_t... Index>
|
||||
void swap_elements(const std::size_t pos, const entity_type entt, std::index_sequence<Index...>) {
|
||||
(std::get<Index>(pools)->swap_elements(std::get<Index>(pools)->data()[pos], entt), ...);
|
||||
}
|
||||
|
||||
void push_on_construct(const entity_type entt) {
|
||||
if(std::apply([entt, len = len](auto *cpool, auto *...other) { return cpool->contains(entt) && !(cpool->index(entt) < len) && (other->contains(entt) && ...); }, pools)
|
||||
&& std::apply([entt](auto *...cpool) { return (!cpool->contains(entt) && ...); }, filter)) {
|
||||
swap_elements(len++, entt);
|
||||
swap_elements(len++, entt, std::index_sequence_for<Owned...>{});
|
||||
}
|
||||
}
|
||||
|
||||
void push_on_destroy(const entity_type entt) {
|
||||
if(std::apply([entt, len = len](auto *cpool, auto *...other) { return cpool->contains(entt) && !(cpool->index(entt) < len) && (other->contains(entt) && ...); }, pools)
|
||||
&& std::apply([entt](auto *...cpool) { return (0u + ... + cpool->contains(entt)) == 1u; }, filter)) {
|
||||
swap_elements(len++, entt);
|
||||
swap_elements(len++, entt, std::index_sequence_for<Owned...>{});
|
||||
}
|
||||
}
|
||||
|
||||
void remove_if(const entity_type entt) {
|
||||
if(std::get<0>(pools)->contains(entt) && (std::get<0>(pools)->index(entt) < len)) {
|
||||
swap_elements(--len, entt);
|
||||
swap_elements(--len, entt, std::index_sequence_for<Owned...>{});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,13 +164,11 @@ public:
|
||||
return len;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
Type pools_as() const noexcept {
|
||||
auto pools_as_tuple() const noexcept {
|
||||
return pools;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
Type filter_as() const noexcept {
|
||||
auto filter_as_tuple() const noexcept {
|
||||
return filter;
|
||||
}
|
||||
|
||||
@@ -231,13 +230,11 @@ public:
|
||||
return elem;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
Type pools_as() const noexcept {
|
||||
auto pools_as_tuple() const noexcept {
|
||||
return pools;
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
Type filter_as() const noexcept {
|
||||
auto filter_as_tuple() const noexcept {
|
||||
return filter;
|
||||
}
|
||||
|
||||
@@ -291,12 +288,12 @@ class basic_group<owned_t<>, get_t<Get...>, exclude_t<Exclude...>> {
|
||||
|
||||
auto pools() const noexcept {
|
||||
using return_type = std::tuple<Get *...>;
|
||||
return descriptor ? descriptor->template pools_as<return_type>() : return_type{};
|
||||
return descriptor ? descriptor->pools_as_tuple() : return_type{};
|
||||
}
|
||||
|
||||
auto filter() const noexcept {
|
||||
using return_type = std::tuple<Exclude *...>;
|
||||
return descriptor ? descriptor->template filter_as<return_type>() : return_type{};
|
||||
return descriptor ? descriptor->filter_as_tuple() : return_type{};
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -712,12 +709,12 @@ class basic_group<owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>> {
|
||||
|
||||
auto pools() const noexcept {
|
||||
using return_type = std::tuple<Owned *..., Get *...>;
|
||||
return descriptor ? descriptor->template pools_as<return_type>() : return_type{};
|
||||
return descriptor ? descriptor->pools_as_tuple() : return_type{};
|
||||
}
|
||||
|
||||
auto filter() const noexcept {
|
||||
using return_type = std::tuple<Exclude *...>;
|
||||
return descriptor ? descriptor->template filter_as<return_type>() : return_type{};
|
||||
return descriptor ? descriptor->filter_as_tuple() : return_type{};
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@@ -1503,6 +1503,25 @@ TEST(OwningGroup, PreventEarlyOptOut) {
|
||||
});
|
||||
}
|
||||
|
||||
TEST(OwningGroup, SwapElements) {
|
||||
entt::registry registry;
|
||||
std::array entity{registry.create(), registry.create(), registry.create()};
|
||||
|
||||
registry.emplace<int>(entity[1u]);
|
||||
registry.emplace<int>(entity[0u]);
|
||||
|
||||
registry.emplace<char>(entity[2u]);
|
||||
registry.emplace<char>(entity[0u]);
|
||||
|
||||
ASSERT_EQ(registry.storage<int>().index(entity[0u]), 1u);
|
||||
ASSERT_EQ(registry.storage<char>().index(entity[0u]), 1u);
|
||||
|
||||
const auto group = registry.group<int>(entt::get<char>);
|
||||
|
||||
ASSERT_EQ(registry.storage<int>().index(entity[0u]), 0u);
|
||||
ASSERT_EQ(registry.storage<char>().index(entity[0u]), 1u);
|
||||
}
|
||||
|
||||
TEST(OwningGroup, SwappingValuesIsAllowed) {
|
||||
entt::registry registry;
|
||||
const auto group = registry.group<test::boxed_int>(entt::get<test::empty>);
|
||||
|
||||
Reference in New Issue
Block a user