Bomberman
View.hpp
Go to the documentation of this file.
1 //
2 // Created by Zoe Roux on 2021-06-03.
3 //
4 
5 
6 #pragma once
7 
8 #include <list>
9 #include <tuple>
10 #include <typeindex>
11 #include <functional>
12 #include <utility>
13 #include <optional>
14 #include "Entity/Entity.hpp"
15 
16 namespace WAL
17 {
18  template<typename ...Components>
19  class ViewEntity
20  {
21  private:
22  std::tuple<std::reference_wrapper<Entity>, std::reference_wrapper<Components>...> &_value;
23  public:
24  explicit ViewEntity(std::tuple<std::reference_wrapper<Entity>, std::reference_wrapper<Components>...> &value)
25  : _value(value)
26  {}
27 
29  {
30  return &(std::get<0>(this->_value).get());
31  }
32 
34  {
35  return std::get<0>(this->_value);
36  }
37 
38  operator Entity &()
39  {
40  return std::get<0>(this->_value);
41  }
42 
43  template<typename T>
44  T &get()
45  {
46  return std::get<std::reference_wrapper<T>>(this->_value);
47  }
48 
49  template<std::size_t I>
50  auto &get()
51  {
52  return std::get<I>(this->_value);
53  }
54  };
55 
56  template<typename It, typename ...Components>
58  {
59  private:
60  It _it;
61  std::optional<ViewEntity<Components...>> _entity;
62 
63  public:
64  using iterator_category = std::forward_iterator_tag;
65  using difference_type = std::ptrdiff_t;
66  using value_type = ViewEntity<Components...>;
67  using pointer = value_type *;
68  using reference = value_type &;
69 
71  {
72  if (!this->_entity)
73  this->_entity.emplace(*this->_it);
74  return *this->_entity;
75  }
76 
78  {
79  if (!this->_entity)
80  this->_entity =(*this->_it);
81  return &this->_entity;
82  }
83 
85  {
86  this->_it++;
87  this->_entity = std::nullopt;
88  return *this;
89  }
90 
92  {
93  ViewIterator copy = *this;
94  this->_it++;
95  this->_entity = std::nullopt;
96  return *this;
97  }
98 
99  bool operator==(const ViewIterator &other) const
100  {
101  return this->_it == other._it;
102  }
103 
104  bool operator!=(const ViewIterator &other) const
105  {
106  return !this->operator==(other);
107  }
108 
109  explicit ViewIterator(It current)
110  : _it(current),
111  _entity(std::nullopt)
112  {}
113  };
114 
116  class IView
117  {
118  public:
120  virtual const std::vector<std::type_index> &getTypes() const = 0;
121 
122  virtual void emplace_back(Entity &) = 0;
123 
124  virtual void erase(const Entity &) = 0;
125 
127  virtual ~IView() = default;
128  };
129 
132  template<typename ...Components>
133  class View : public IView
134  {
135  private:
136  using entity_type = std::tuple<std::reference_wrapper<Entity>, std::reference_wrapper<Components>...>;
137 
139  std::vector<entity_type> _entities = {};
141  std::vector<std::type_index> _types = {};
142  public:
144 
146  {
147  return iterator(this->_entities.begin());
148  }
149 
151  {
152  return iterator(this->_entities.end());
153  }
154 
155  std::size_t size() const
156  {
157  return this->_entities.size();
158  }
159 
160  ViewEntity<Components...> front()
161  {
162  return *iterator(this->_entities.begin());
163  }
164 
165  ViewEntity<Components...> back()
166  {
167  return *iterator(--this->_entities.end());
168  }
169 
170  const std::vector<std::type_index> &getTypes() const override
171  {
172  return this->_types;
173  }
174 
175  void emplace_back(Entity &entity) override
176  {
177  auto tuple = std::make_tuple<Components *...>(entity.tryGetComponent<Components>()...);
178  if (std::apply([](const auto *...component) {return ((component == nullptr) || ...);}, tuple))
179  return;
180  std::apply([&](auto *...component) {
181  this->_entities.emplace_back(entity, *component...);
182  }, tuple);
183  }
184 
185  void erase(const Entity &entity) override
186  {
187  this->_entities.erase(std::remove_if(this->_entities.begin(), this->_entities.end(), [&entity](const auto &ref) {
188  return std::get<0>(ref).get().getUid() == entity.getUid();
189  }), this->_entities.end());
190  }
191 
194  explicit View(std::list<Entity> &scene)
195  {
196  this->_types = {typeid(Components)...};
197  for (auto &entity : scene)
198  this->emplace_back(entity);
199  }
200 
202  View(const View &) = delete;
204  ~View() override = default;
206  View &operator=(const View &) = delete;
207  };
208 }
209 
210 namespace std
211 {
212  template<typename ...Components>
213  struct tuple_size<::WAL::ViewEntity<Components...>>
214  : public std::integral_constant<std::size_t, 1 + sizeof...(Components)>
215  {};
216 
217  template<typename ...Components>
218  struct tuple_element<0, ::WAL::ViewEntity<Components...>>
219  {
220  using type = WAL::Entity &;
221  };
222 
223  template<std::size_t N, typename ...Components>
224  struct tuple_element<N, ::WAL::ViewEntity<Components...>>
225  {
226  using type = typename std::tuple_element<N - 1, std::tuple<Components...>>::type;
227  };
228 }
WAL::Entity::tryGetComponent
T * tryGetComponent()
Get a component of a specific type or null if not found.
Definition: Entity.hpp:86
WAL::View::emplace_back
void emplace_back(Entity &entity) override
Definition: View.hpp:175
WAL::ViewIterator::_it
It _it
Definition: View.hpp:60
WAL::View::View
View(std::list< Entity > &scene)
Construct a view from a list of entities. Those entities are never copied but references to them are ...
Definition: View.hpp:194
std::tuple_element< N, ::WAL::ViewEntity< Components... > >::type
typename std::tuple_element< N - 1, std::tuple< Components... > >::type type
Definition: View.hpp:226
WAL::ViewEntity
Definition: View.hpp:19
WAL
Definition: Component.cpp:7
WAL::View::front
ViewEntity< Components... > front()
Definition: View.hpp:160
WAL::ViewEntity::get
auto & get()
Definition: View.hpp:50
WAL::View::_types
std::vector< std::type_index > _types
The list of types that every entity of the view has.
Definition: View.hpp:141
WAL::ViewEntity::operator*
Entity & operator*()
Definition: View.hpp:33
WAL::View::getTypes
const std::vector< std::type_index > & getTypes() const override
The list of types that every entity of the view has.
Definition: View.hpp:170
Entity.hpp
WAL::ViewEntity::operator->
Entity * operator->()
Definition: View.hpp:28
WAL::IView::~IView
virtual ~IView()=default
A default destructor.
WAL::Entity
An entity of the WAL's ECS.
Definition: Entity.hpp:20
WAL::ViewIterator::_entity
std::optional< ViewEntity< Components... > > _entity
Definition: View.hpp:61
WAL::IView::emplace_back
virtual void emplace_back(Entity &)=0
WAL::ViewIterator::iterator_category
std::forward_iterator_tag iterator_category
Definition: View.hpp:64
WAL::ViewEntity::_value
std::tuple< std::reference_wrapper< Entity >, std::reference_wrapper< Components >... > & _value
Definition: View.hpp:22
WAL::ViewIterator::operator->
pointer operator->()
Definition: View.hpp:77
WAL::View::iterator
ViewIterator< typename std::vector< entity_type >::iterator, Components... > iterator
Definition: View.hpp:143
WAL::View::end
iterator end()
Definition: View.hpp:150
WAL::IView::getTypes
virtual const std::vector< std::type_index > & getTypes() const =0
The list of types that every entity of the view has.
WAL::ViewIterator::operator++
ViewIterator & operator++()
Definition: View.hpp:84
WAL::View::operator=
View & operator=(const View &)=delete
A view is not assignable.
WAL::View::entity_type
std::tuple< std::reference_wrapper< Entity >, std::reference_wrapper< Components >... > entity_type
Definition: View.hpp:136
WAL::ViewIterator::operator==
bool operator==(const ViewIterator &other) const
Definition: View.hpp:99
WAL::View
A view allowing one to easily access entities containing a set list of component. A view is always up...
Definition: View.hpp:133
WAL::ViewIterator::difference_type
std::ptrdiff_t difference_type
Definition: View.hpp:65
WAL::View::size
std::size_t size() const
Definition: View.hpp:155
WAL::ViewIterator::operator++
ViewIterator operator++(int)
Definition: View.hpp:91
std
Definition: View.hpp:210
WAL::View::back
ViewEntity< Components... > back()
Definition: View.hpp:165
WAL::View::~View
~View() override=default
A default destructor.
WAL::IView::erase
virtual void erase(const Entity &)=0
WAL::ViewIterator::operator!=
bool operator!=(const ViewIterator &other) const
Definition: View.hpp:104
WAL::View::_entities
std::vector< entity_type > _entities
The list of entities in the view.
Definition: View.hpp:139
WAL::ViewIterator
Definition: View.hpp:57
WAL::View::begin
iterator begin()
Definition: View.hpp:145
WAL::ViewIterator::ViewIterator
ViewIterator(It current)
Definition: View.hpp:109
WAL::ViewEntity::ViewEntity
ViewEntity(std::tuple< std::reference_wrapper< Entity >, std::reference_wrapper< Components >... > &value)
Definition: View.hpp:24
WAL::View::erase
void erase(const Entity &entity) override
Definition: View.hpp:185
WAL::ViewIterator::operator*
reference operator*()
Definition: View.hpp:70
WAL::ViewEntity::get
T & get()
Definition: View.hpp:44
WAL::IView
A basic view used to manipulate view without knowing their type at compile time.
Definition: View.hpp:116