EnTT 4.0.0
Loading...
Searching...
No Matches
runtime_view.hpp
1#ifndef ENTT_ENTITY_RUNTIME_VIEW_HPP
2#define ENTT_ENTITY_RUNTIME_VIEW_HPP
3
4#include "../stl/algorithm.hpp"
5#include "../stl/cstddef.hpp"
6#include "../stl/iterator.hpp"
7#include "../stl/utility.hpp"
8#include "../stl/vector.hpp"
9#include "entity.hpp"
10#include "fwd.hpp"
11
12namespace entt {
13
15namespace internal {
16
17template<typename Set>
18class runtime_view_iterator final {
19 using iterator_type = Set::iterator;
20 using iterator_traits = stl::iterator_traits<iterator_type>;
21
22 [[nodiscard]] bool valid() const {
23 return (!tombstone_check || *it != tombstone)
24 && stl::all_of(++pools->begin(), pools->end(), [entt = *it](const auto *curr) { return curr->contains(entt); })
25 && stl::none_of(filter->cbegin(), filter->cend(), [entt = *it](const auto *curr) { return curr && curr->contains(entt); });
26 }
27
28public:
29 using value_type = iterator_traits::value_type;
30 using pointer = iterator_traits::pointer;
31 using reference = iterator_traits::reference;
32 using difference_type = iterator_traits::difference_type;
33 using iterator_category = stl::bidirectional_iterator_tag;
34
35 constexpr runtime_view_iterator() noexcept
36 : pools{},
37 filter{},
38 it{},
39 tombstone_check{} {}
40
41 runtime_view_iterator(const stl::vector<Set *> &cpools, iterator_type curr, const stl::vector<Set *> &ignore) noexcept
42 : pools{&cpools},
43 filter{&ignore},
44 it{curr},
45 tombstone_check{pools->size() == 1u && (*pools)[0u]->policy() == deletion_policy::in_place} {
46 if(it != (*pools)[0]->end() && !valid()) {
47 ++(*this);
48 }
49 }
50
51 runtime_view_iterator &operator++() {
52 ++it;
53 for(const auto last = (*pools)[0]->end(); it != last && !valid(); ++it) {}
54 return *this;
55 }
56
57 runtime_view_iterator operator++(int) {
58 const runtime_view_iterator orig = *this;
59 return ++(*this), orig;
60 }
61
62 runtime_view_iterator &operator--() {
63 --it;
64 for(const auto first = (*pools)[0]->begin(); it != first && !valid(); --it) {}
65 return *this;
66 }
67
68 runtime_view_iterator operator--(int) {
69 const runtime_view_iterator orig = *this;
70 return operator--(), orig;
71 }
72
73 [[nodiscard]] pointer operator->() const noexcept {
74 return it.operator->();
75 }
76
77 [[nodiscard]] reference operator*() const noexcept {
78 return *operator->();
79 }
80
81 [[nodiscard]] constexpr bool operator==(const runtime_view_iterator &other) const noexcept {
82 return it == other.it;
83 }
84
85private:
86 const stl::vector<Set *> *pools;
87 const stl::vector<Set *> *filter;
88 iterator_type it;
89 bool tombstone_check;
90};
91
92} // namespace internal
94
118template<typename Type, typename Allocator>
120 using alloc_traits = stl::allocator_traits<Allocator>;
121 static_assert(stl::is_same_v<typename alloc_traits::value_type, Type *>, "Invalid value type");
122 using container_type = stl::vector<Type *, Allocator>;
123
124 [[nodiscard]] auto offset() const noexcept {
125 ENTT_ASSERT(!pools.empty(), "Invalid view");
126 const auto &leading = *pools.front();
127 return (leading.policy() == deletion_policy::swap_only) ? leading.free_list() : leading.size();
128 }
129
130public:
132 using allocator_type = Allocator;
134 using entity_type = Type::entity_type;
136 using size_type = stl::size_t;
138 using difference_type = stl::ptrdiff_t;
140 using common_type = Type;
142 using iterator = internal::runtime_view_iterator<common_type>;
143
147
152 explicit basic_runtime_view(const allocator_type &allocator)
153 : pools{allocator},
154 filter{allocator} {}
155
158
165 : pools{other.pools, allocator},
166 filter{other.filter, allocator} {}
167
170
177 : pools{stl::move(other.pools), allocator},
178 filter{stl::move(other.filter), allocator} {}
179
182
188
194
199 void swap(basic_runtime_view &other) noexcept {
200 using stl::swap;
201 swap(pools, other.pools);
202 swap(filter, other.filter);
203 }
204
209 [[nodiscard]] constexpr allocator_type get_allocator() const noexcept {
210 return pools.get_allocator();
211 }
212
214 void clear() {
215 pools.clear();
216 filter.clear();
217 }
218
225 if(pools.empty() || !(base.size() < pools.front()->size())) {
226 pools.push_back(&base);
227 } else {
228 pools.push_back(stl::exchange(pools.front(), &base));
229 }
230
231 return *this;
232 }
233
240 filter.push_back(&base);
241 return *this;
242 }
243
248 [[nodiscard]] size_type size_hint() const {
249 return pools.empty() ? size_type{} : offset();
250 }
251
260 [[nodiscard]] iterator begin() const {
261 return pools.empty() ? iterator{} : iterator{pools, pools.front()->end() - static_cast<difference_type>(offset()), filter};
262 }
263
270 [[nodiscard]] iterator end() const {
271 return pools.empty() ? iterator{} : iterator{pools, pools.front()->end(), filter};
272 }
273
278 [[nodiscard]] explicit operator bool() const noexcept {
279 return !(pools.empty() && filter.empty());
280 }
281
287 [[nodiscard]] bool contains(const entity_type entt) const {
288 return !pools.empty()
289 && stl::all_of(pools.cbegin(), pools.cend(), [entt](const auto *curr) { return curr->contains(entt); })
290 && stl::none_of(filter.cbegin(), filter.cend(), [entt](const auto *curr) { return curr && curr->contains(entt); })
291 && pools.front()->index(entt) < offset();
292 }
293
308 template<typename Func>
309 void each(Func func) const {
310 for(const auto entity: *this) {
311 func(entity);
312 }
313 }
314
315private:
316 container_type pools;
317 container_type filter;
318};
319
320} // namespace entt
321
322#endif
basic_runtime_view(const basic_runtime_view &)=default
Default copy constructor.
iterator begin() const
Returns an iterator to the first entity that has the given elements.
basic_runtime_view() noexcept
Default constructor to use to create empty, invalid views.
basic_runtime_view(const allocator_type &allocator)
Constructs an empty, invalid view with a given allocator.
internal::runtime_view_iterator< common_type > iterator
basic_runtime_view & operator=(const basic_runtime_view &)=default
Default copy assignment operator.
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
~basic_runtime_view()=default
Default destructor.
bool contains(const entity_type entt) const
Checks if a view contains an entity.
void each(Func func) const
Iterates entities and applies the given function object to them.
basic_runtime_view & exclude(common_type &base)
Adds an opaque storage object as a filter of a runtime view.
void clear()
Clears the view.
iterator end() const
Returns an iterator that is past the last entity that has the given elements.
basic_runtime_view & operator=(basic_runtime_view &&) noexcept=default
Default move assignment operator.
size_type size_hint() const
Estimates the number of entities iterated by the view.
basic_runtime_view(const basic_runtime_view &other, const allocator_type &allocator)
Allocator-extended copy constructor.
void swap(basic_runtime_view &other) noexcept
basic_runtime_view & iterate(common_type &base)
Appends an opaque storage object to a runtime view.
basic_runtime_view(basic_runtime_view &&) noexcept=default
Default move constructor.
size_type size() const noexcept
Returns the number of elements in a sparse set.
EnTT default namespace.
Definition dense_map.hpp:25
entity
Default entity identifier.
Definition fwd.hpp:15
@ swap_only
Swap-only deletion policy.
Definition fwd.hpp:24