EnTT  3.1.0
runtime_view.hpp
1 #ifndef ENTT_ENTITY_RUNTIME_VIEW_HPP
2 #define ENTT_ENTITY_RUNTIME_VIEW_HPP
3 
4 
5 #include <iterator>
6 #include <cassert>
7 #include <vector>
8 #include <utility>
9 #include <algorithm>
10 #include <type_traits>
11 #include "../config/config.h"
12 #include "sparse_set.hpp"
13 #include "entity.hpp"
14 #include "fwd.hpp"
15 
16 
17 namespace entt {
18 
19 
58 template<typename Entity>
59 class basic_runtime_view {
61  friend class basic_registry<Entity>;
62 
63  using underlying_iterator_type = typename sparse_set<Entity>::iterator_type;
65 
66  class iterator {
67  friend class basic_runtime_view<Entity>;
68 
69  iterator(underlying_iterator_type first, underlying_iterator_type last, const sparse_set<Entity> * const *others, const sparse_set<Entity> * const *length) ENTT_NOEXCEPT
70  : begin{first},
71  end{last},
72  from{others},
73  to{length}
74  {
75  if(begin != end && !valid()) {
76  ++(*this);
77  }
78  }
79 
80  bool valid() const ENTT_NOEXCEPT {
81  return std::all_of(from, to, [entt = *begin](const auto *view) {
82  return view->has(entt);
83  });
84  }
85 
86  public:
87  using difference_type = typename underlying_iterator_type::difference_type;
88  using value_type = typename underlying_iterator_type::value_type;
89  using pointer = typename underlying_iterator_type::pointer;
90  using reference = typename underlying_iterator_type::reference;
91  using iterator_category = std::forward_iterator_tag;
92 
93  iterator() ENTT_NOEXCEPT = default;
94 
95  iterator & operator++() ENTT_NOEXCEPT {
96  return (++begin != end && !valid()) ? ++(*this) : *this;
97  }
98 
99  iterator operator++(int) ENTT_NOEXCEPT {
100  iterator orig = *this;
101  return ++(*this), orig;
102  }
103 
104  bool operator==(const iterator &other) const ENTT_NOEXCEPT {
105  return other.begin == begin;
106  }
107 
108  bool operator!=(const iterator &other) const ENTT_NOEXCEPT {
109  return !(*this == other);
110  }
111 
112  pointer operator->() const ENTT_NOEXCEPT {
113  return begin.operator->();
114  }
115 
116  reference operator*() const ENTT_NOEXCEPT {
117  return *operator->();
118  }
119 
120  private:
121  underlying_iterator_type begin;
122  underlying_iterator_type end;
123  const sparse_set<Entity> * const *from;
124  const sparse_set<Entity> * const *to;
125  };
126 
127  basic_runtime_view(std::vector<const sparse_set<Entity> *> others) ENTT_NOEXCEPT
128  : pools{std::move(others)}
129  {
130  const auto it = std::min_element(pools.begin(), pools.end(), [](const auto *lhs, const auto *rhs) {
131  return (!lhs && rhs) || (lhs && rhs && lhs->size() < rhs->size());
132  });
133 
134  // brings the best candidate (if any) on front of the vector
135  std::rotate(pools.begin(), it, pools.end());
136  }
137 
138  bool valid() const ENTT_NOEXCEPT {
139  return !pools.empty() && pools.front();
140  }
141 
142 public:
148  using iterator_type = iterator;
149 
154  size_type size() const ENTT_NOEXCEPT {
155  return valid() ? pools.front()->size() : size_type{};
156  }
157 
162  bool empty() const ENTT_NOEXCEPT {
163  return !valid() || pools.front()->empty();
164  }
165 
180  iterator_type begin() const ENTT_NOEXCEPT {
181  iterator_type it{};
182 
183  if(valid()) {
184  const auto &pool = *pools.front();
185  const auto * const *data = pools.data();
186  it = { pool.begin(), pool.end(), data + 1, data + pools.size() };
187  }
188 
189  return it;
190  }
191 
207  iterator_type end() const ENTT_NOEXCEPT {
208  iterator_type it{};
209 
210  if(valid()) {
211  const auto &pool = *pools.front();
212  it = { pool.end(), pool.end(), nullptr, nullptr };
213  }
214 
215  return it;
216  }
217 
223  bool contains(const entity_type entt) const ENTT_NOEXCEPT {
224  return valid() && std::all_of(pools.cbegin(), pools.cend(), [entt](const auto *view) {
225  return view->find(entt) != view->end();
226  });
227  }
228 
244  template<typename Func>
245  void each(Func func) const {
246  std::for_each(begin(), end(), func);
247  }
248 
249 private:
250  std::vector<const sparse_set<Entity> *> pools;
251 };
252 
253 
254 }
255 
256 
257 #endif // ENTT_ENTITY_RUNTIME_VIEW_HPP
bool contains(const entity_type entt) const ENTT_NOEXCEPT
Checks if a view contains an entity.
Basic sparse set implementation.
Definition: sparse_set.hpp:50
typename sparse_set< Entity >::size_type size_type
Unsigned integer type.
iterator iterator_type
Input iterator type.
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) ENTT_NOEXCEPT
Compares two hashed strings.
EnTT default namespace.
Definition: algorithm.hpp:12
std::size_t size_type
Unsigned integer type.
Definition: sparse_set.hpp:180
typename sparse_set< Entity >::entity_type entity_type
Underlying entity identifier.
iterator_type end() const ENTT_NOEXCEPT
Returns an iterator that is past the last entity that has the given components.
Definition: view.hpp:309
Fast and reliable entity-component system.
Definition: fwd.hpp:14
Multi component view.
Definition: fwd.hpp:18
Entity entity_type
Underlying entity identifier.
Definition: sparse_set.hpp:178
bool empty() const ENTT_NOEXCEPT
Checks if the view is definitely empty.
iterator_type begin() const ENTT_NOEXCEPT
Returns an iterator to the first entity that has the given components.
void each(Func func) const
Iterates entities and applies the given function object to them.
iterator_type find(const entity_type entt) const ENTT_NOEXCEPT
Finds an entity.
Definition: view.hpp:320
basic_view< entity, Types... > view
Alias declaration for the most common use case.
Definition: fwd.hpp:84
size_type size() const ENTT_NOEXCEPT
Estimates the number of entities that have the given components.
iterator_type end() const ENTT_NOEXCEPT
Returns an iterator that is past the last entity that has the given components.
Entity traits.
Definition: entity.hpp:20
Runtime view.
Definition: fwd.hpp:22
iterator iterator_type
Random access iterator type.
Definition: sparse_set.hpp:182