EnTT  3.10.0
runtime_view.hpp
1 #ifndef ENTT_ENTITY_RUNTIME_VIEW_HPP
2 #define ENTT_ENTITY_RUNTIME_VIEW_HPP
3 
4 #include <algorithm>
5 #include <iterator>
6 #include <type_traits>
7 #include <utility>
8 #include <vector>
9 #include "../config/config.h"
10 #include "entity.hpp"
11 #include "fwd.hpp"
12 #include "sparse_set.hpp"
13 
14 namespace entt {
15 
21 namespace internal {
22 
23 template<typename Set>
24 class runtime_view_iterator final {
25  using iterator_type = typename Set::iterator;
26 
27  [[nodiscard]] bool valid() const {
28  return (!tombstone_check || *it != tombstone)
29  && std::all_of(++pools->begin(), pools->end(), [entt = *it](const auto *curr) { return curr->contains(entt); })
30  && std::none_of(filter->cbegin(), filter->cend(), [entt = *it](const auto *curr) { return curr && curr->contains(entt); });
31  }
32 
33 public:
34  using difference_type = typename iterator_type::difference_type;
35  using value_type = typename iterator_type::value_type;
36  using pointer = typename iterator_type::pointer;
37  using reference = typename iterator_type::reference;
38  using iterator_category = std::bidirectional_iterator_tag;
39 
40  runtime_view_iterator() ENTT_NOEXCEPT
41  : pools{},
42  filter{},
43  it{},
44  tombstone_check{} {}
45 
46  runtime_view_iterator(const std::vector<const Set *> &cpools, const std::vector<const Set *> &ignore, iterator_type curr) ENTT_NOEXCEPT
47  : pools{&cpools},
48  filter{&ignore},
49  it{curr},
50  tombstone_check{pools->size() == 1u && (*pools)[0u]->policy() == deletion_policy::in_place} {
51  if(it != (*pools)[0]->end() && !valid()) {
52  ++(*this);
53  }
54  }
55 
56  runtime_view_iterator &operator++() {
57  while(++it != (*pools)[0]->end() && !valid()) {}
58  return *this;
59  }
60 
61  runtime_view_iterator operator++(int) {
62  runtime_view_iterator orig = *this;
63  return ++(*this), orig;
64  }
65 
66  runtime_view_iterator &operator--() {
67  while(--it != (*pools)[0]->begin() && !valid()) {}
68  return *this;
69  }
70 
71  runtime_view_iterator operator--(int) {
72  runtime_view_iterator orig = *this;
73  return operator--(), orig;
74  }
75 
76  [[nodiscard]] pointer operator->() const ENTT_NOEXCEPT {
77  return it.operator->();
78  }
79 
80  [[nodiscard]] reference operator*() const ENTT_NOEXCEPT {
81  return *operator->();
82  }
83 
84  [[nodiscard]] bool operator==(const runtime_view_iterator &other) const ENTT_NOEXCEPT {
85  return it == other.it;
86  }
87 
88  [[nodiscard]] bool operator!=(const runtime_view_iterator &other) const ENTT_NOEXCEPT {
89  return !(*this == other);
90  }
91 
92 private:
93  const std::vector<const Set *> *pools;
94  const std::vector<const Set *> *filter;
95  iterator_type it;
96  bool tombstone_check;
97 };
98 
99 } // namespace internal
100 
112 template<typename>
113 struct basic_runtime_view;
114 
154 template<typename Entity, typename Allocator>
155 struct basic_runtime_view<basic_sparse_set<Entity, Allocator>> {
157  using entity_type = Entity;
159  using size_type = std::size_t;
163  using iterator = internal::runtime_view_iterator<base_type>;
164 
166  basic_runtime_view() ENTT_NOEXCEPT
167  : pools{},
168  filter{} {}
169 
176  if(pools.empty() || !(base.size() < pools[0u]->size())) {
177  pools.push_back(&base);
178  } else {
179  pools.push_back(std::exchange(pools[0u], &base));
180  }
181 
182  return *this;
183  }
184 
191  filter.push_back(&base);
192  return *this;
193  }
194 
199  [[nodiscard]] size_type size_hint() const {
200  return pools.empty() ? size_type{} : pools.front()->size();
201  }
202 
213  [[nodiscard]] iterator begin() const {
214  return pools.empty() ? iterator{} : iterator{pools, filter, pools[0]->begin()};
215  }
216 
228  [[nodiscard]] iterator end() const {
229  return pools.empty() ? iterator{} : iterator{pools, filter, pools[0]->end()};
230  }
231 
237  [[nodiscard]] bool contains(const entity_type entt) const {
238  return !pools.empty()
239  && std::all_of(pools.cbegin(), pools.cend(), [entt](const auto *curr) { return curr->contains(entt); })
240  && std::none_of(filter.cbegin(), filter.cend(), [entt](const auto *curr) { return curr && curr->contains(entt); });
241  }
242 
258  template<typename Func>
259  void each(Func func) const {
260  for(const auto entity: *this) {
261  func(entity);
262  }
263  }
264 
265 private:
266  std::vector<const base_type *> pools;
267  std::vector<const base_type *> filter;
268 };
269 
270 } // namespace entt
271 
272 #endif
Basic sparse set implementation.
Definition: sparse_set.hpp:174
size_type size() const
Returns the number of elements in a sparse set.
Definition: sparse_set.hpp:465
EnTT default namespace.
Definition: dense_map.hpp:22
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs)
Compares two hashed strings.
entity
Default entity identifier.
Definition: fwd.hpp:47
constexpr tombstone_t tombstone
Compile-time constant for tombstone entities.
Definition: entity.hpp:335
@ in_place
In-place deletion policy.
bool operator!=(const basic_any< Len, Align > &lhs, const basic_any< Len, Align > &rhs)
Checks if two wrappers differ in their content.
Definition: any.hpp:402
bool contains(const entity_type entt) const
Checks if a view contains an entity.
iterator begin() const
Returns an iterator to the first entity that has the given components.
basic_runtime_view()
Default constructor to use to create empty, invalid views.
size_type size_hint() const
Estimates the number of entities iterated by the view.
void each(Func func) const
Iterates entities and applies the given function object to them.
iterator end() const
Returns an iterator that is past the last entity that has the given components.
basic_runtime_view & exclude(const base_type &base)
Adds an opaque storage object as a filter of a runtime view.
basic_runtime_view & iterate(const base_type &base)
Appends an opaque storage object to a runtime view.
internal::runtime_view_iterator< base_type > iterator
Bidirectional iterator type.
Runtime view implementation.
Definition: fwd.hpp:23