runtime_view: support for storage policy (tombstones)
This commit is contained in:
@@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user