EnTT  3.9.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 Type>
24 class runtime_view_iterator final {
25  [[nodiscard]] bool valid() const {
26  return std::all_of(pools->begin(), pools->end(), [entt = *it](const auto *curr) { return curr->contains(entt); })
27  && std::none_of(filter->cbegin(), filter->cend(), [entt = *it](const auto *curr) { return curr && curr->contains(entt); });
28  }
29 
30 public:
31  using iterator_type = typename Type::iterator;
32  using difference_type = typename iterator_type::difference_type;
33  using value_type = typename iterator_type::value_type;
34  using pointer = typename iterator_type::pointer;
35  using reference = typename iterator_type::reference;
36  using iterator_category = std::bidirectional_iterator_tag;
37 
38  runtime_view_iterator() ENTT_NOEXCEPT = default;
39 
40  runtime_view_iterator(const std::vector<const Type *> &cpools, const std::vector<const Type *> &ignore, iterator_type curr) ENTT_NOEXCEPT
41  : pools{&cpools},
42  filter{&ignore},
43  it{curr} {
44  if(it != (*pools)[0]->end() && !valid()) {
45  ++(*this);
46  }
47  }
48 
49  runtime_view_iterator &operator++() {
50  while(++it != (*pools)[0]->end() && !valid()) {}
51  return *this;
52  }
53 
54  runtime_view_iterator operator++(int) {
55  runtime_view_iterator orig = *this;
56  return ++(*this), orig;
57  }
58 
59  runtime_view_iterator &operator--() ENTT_NOEXCEPT {
60  while(--it != (*pools)[0]->begin() && !valid()) {}
61  return *this;
62  }
63 
64  runtime_view_iterator operator--(int) ENTT_NOEXCEPT {
65  runtime_view_iterator orig = *this;
66  return operator--(), orig;
67  }
68 
69  [[nodiscard]] pointer operator->() const {
70  return it.operator->();
71  }
72 
73  [[nodiscard]] reference operator*() const {
74  return *operator->();
75  }
76 
77  [[nodiscard]] bool operator==(const runtime_view_iterator &other) const ENTT_NOEXCEPT {
78  return it == other.it;
79  }
80 
81  [[nodiscard]] bool operator!=(const runtime_view_iterator &other) const ENTT_NOEXCEPT {
82  return !(*this == other);
83  }
84 
85 private:
86  const std::vector<const Type *> *pools;
87  const std::vector<const Type *> *filter;
88  iterator_type it;
89 };
90 
91 } // namespace internal
92 
136 template<typename Entity>
137 class basic_runtime_view final {
139 
140  [[nodiscard]] bool valid() const {
141  return !pools.empty() && pools.front();
142  }
143 
144 public:
146  using entity_type = Entity;
148  using size_type = std::size_t;
150  using iterator = internal::runtime_view_iterator<basic_common_type>;
151 
153  basic_runtime_view() ENTT_NOEXCEPT
154  : pools{},
155  filter{} {}
156 
162  basic_runtime_view(std::vector<const basic_common_type *> cpools, std::vector<const basic_common_type *> epools) ENTT_NOEXCEPT
163  : pools{std::move(cpools)},
164  filter{std::move(epools)} {
165  auto candidate = std::min_element(pools.begin(), pools.end(), [](const auto *lhs, const auto *rhs) {
166  return (!lhs && rhs) || (lhs && rhs && lhs->size() < rhs->size());
167  });
168 
169  // brings the best candidate (if any) on front of the vector
170  std::rotate(pools.begin(), candidate, pools.end());
171  }
172 
177  [[nodiscard]] size_type size_hint() const {
178  return valid() ? pools.front()->size() : size_type{};
179  }
180 
191  [[nodiscard]] iterator begin() const {
192  return valid() ? iterator{pools, filter, pools[0]->begin()} : iterator{};
193  }
194 
206  [[nodiscard]] iterator end() const {
207  return valid() ? iterator{pools, filter, pools[0]->end()} : iterator{};
208  }
209 
215  [[nodiscard]] bool contains(const entity_type entt) const {
216  return valid() && std::all_of(pools.cbegin(), pools.cend(), [entt](const auto *curr) { return curr->contains(entt); })
217  && std::none_of(filter.cbegin(), filter.cend(), [entt](const auto *curr) { return curr && curr->contains(entt); });
218  }
219 
235  template<typename Func>
236  void each(Func func) const {
237  for(const auto entity: *this) {
238  func(entity);
239  }
240  }
241 
242 private:
243  std::vector<const basic_common_type *> pools;
244  std::vector<const basic_common_type *> filter;
245 };
246 
247 } // namespace entt
248 
249 #endif
internal::runtime_view_iterator< basic_common_type > iterator
Bidirectional iterator type.
basic_runtime_view()
Default constructor to use to create empty, invalid views.
basic_runtime_view(std::vector< const basic_common_type * > cpools, std::vector< const basic_common_type * > epools)
Constructs a runtime view from a set of storage classes.
iterator end() const
Returns an iterator that is past the last entity that has the given components.
void each(Func func) const
Iterates entities and applies the given function object to them.
Entity entity_type
Underlying entity identifier.
iterator begin() const
Returns an iterator to the first entity that has the given components.
std::size_t size_type
Unsigned integer type.
bool contains(const entity_type entt) const
Checks if a view contains an entity.
size_type size_hint() const
Estimates the number of entities iterated by the view.
Basic sparse set implementation.
Definition: sparse_set.hpp:174
EnTT default namespace.
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
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:406