runtime_view: support for storage policy (tombstones)

This commit is contained in:
Michele Caini
2021-06-21 15:18:13 +02:00
parent cdf67a1421
commit 8aa4d46ce0
2 changed files with 60 additions and 8 deletions

View File

@@ -8,6 +8,7 @@
#include <algorithm>
#include <type_traits>
#include "../config/config.h"
#include "entity.hpp"
#include "sparse_set.hpp"
#include "fwd.hpp"
@@ -60,8 +61,11 @@ class basic_runtime_view final {
class view_iterator final {
[[nodiscard]] bool valid() const {
return std::all_of(pools->begin()++, pools->end(), [entt = *it](const auto *curr) { return curr->contains(entt); })
&& std::none_of(filter->cbegin(), filter->cend(), [entt = *it](const auto *curr) { return curr && curr->contains(entt); });
const auto entt = *it;
return (!stable_storage || (entt != tombstone))
&& std::all_of(pools->begin()++, pools->end(), [entt](const auto *curr) { return curr->contains(entt); })
&& std::none_of(filter->cbegin(), filter->cend(), [entt](const auto *curr) { return curr && curr->contains(entt); });
}
public:
@@ -76,7 +80,8 @@ class basic_runtime_view final {
view_iterator(const std::vector<const basic_common_type *> &cpools, const std::vector<const basic_common_type *> &ignore, underlying_iterator curr) ENTT_NOEXCEPT
: pools{&cpools},
filter{&ignore},
it{curr}
it{curr},
stable_storage{std::any_of(pools->cbegin(), pools->cend(), [](const basic_common_type *curr) { return (curr->policy() == deletion_policy::in_place); })}
{
if(it != (*pools)[0]->end() && !valid()) {
++(*this);
@@ -123,6 +128,7 @@ class basic_runtime_view final {
const std::vector<const basic_common_type *> *pools;
const std::vector<const basic_common_type *> *filter;
underlying_iterator it;
bool stable_storage;
};
[[nodiscard]] bool valid() const {
@@ -152,12 +158,10 @@ public:
: pools{std::move(cpools)},
filter{std::move(epools)}
{
const auto it = std::min_element(pools.begin(), pools.end(), [](const auto *lhs, const auto *rhs) {
return (!lhs && rhs) || (lhs && rhs && lhs->size() < rhs->size());
});
// brings the best candidate (if any) on front of the vector
std::rotate(pools.begin(), it, pools.end());
std::rotate(pools.begin(), std::min_element(pools.begin(), pools.end(), [](const auto *lhs, const auto *rhs) {
return (!lhs && rhs) || (lhs && rhs && lhs->size() < rhs->size());
}), pools.end());
}
/**

View File

@@ -5,6 +5,14 @@
#include <entt/entity/registry.hpp>
#include <entt/entity/runtime_view.hpp>
struct stable_type { int value; };
template<>
struct entt::component_traits<stable_type> {
using in_place_delete = std::true_type;
using ignore_if_empty = std::true_type;
};
TEST(RuntimeView, Functionalities) {
entt::registry registry;
@@ -224,3 +232,43 @@ TEST(RuntimeView, ExcludedComponents) {
ASSERT_EQ(e0, entity);
});
}
TEST(RuntimeView, StableType) {
entt::registry registry;
const auto e0 = registry.create();
const auto e1 = registry.create();
const auto e2 = registry.create();
registry.emplace<int>(e0);
registry.emplace<int>(e1);
registry.emplace<int>(e2);
registry.emplace<stable_type>(e0);
registry.emplace<stable_type>(e1);
registry.remove<stable_type>(e1);
entt::id_type components[] = { entt::type_hash<int>::value(), entt::type_hash<stable_type>::value() };
auto view = registry.runtime_view(std::begin(components), std::end(components));
ASSERT_EQ(view.size_hint(), 2u);
ASSERT_TRUE(view.contains(e0));
ASSERT_FALSE(view.contains(e1));
ASSERT_EQ(*view.begin(), e0);
ASSERT_EQ(++view.begin(), view.end());
view.each([e0](const auto entt) {
ASSERT_EQ(e0, entt);
});
for(auto entt: view) {
static_assert(std::is_same_v<decltype(entt), entt::entity>);
ASSERT_EQ(e0, entt);
}
registry.compact();
ASSERT_EQ(view.size_hint(), 1u);
}