Bomberman
Entity.hpp
Go to the documentation of this file.
1 //
2 // Created by Zoe Roux on 2021-05-14.
3 //
4 
5 #pragma once
6 
7 #include <string>
8 #include <unordered_map>
9 #include <typeinfo>
10 #include <memory>
11 #include "Component/Component.hpp"
12 #include "Exception/WalError.hpp"
13 #include "Models/TypeHolder.hpp"
14 
15 namespace WAL
16 {
17  class Scene;
18 
20  class Entity
21  {
22  private:
24  unsigned _uid;
26  std::string _name;
28  bool _disabled = false;
30  bool _shouldDelete = false;
34  std::unordered_map<std::type_index, std::unique_ptr<Component>> _components = {};
35 
37  static unsigned nextID;
38 
41  void _componentAdded(const std::type_index &type);
44  void _componentRemoved(const std::type_index &type);
45 
46  friend Scene;
47  friend class Wal;
48  protected:
49  public:
53  unsigned getUid() const;
55  std::string getName() const;
57  void setName(std::string &name);
58 
60  bool isDisable() const;
62  void setDisable(bool disabled);
63 
65  bool shouldDelete() const;
67  void scheduleDeletion();
68 
73  template<typename T>
75  {
76  T *ret = this->tryGetComponent<T>();
77  if (ret == nullptr)
78  throw NotFoundError("No component could be found with the type \"" + std::string(typeid(T).name()) + "\".");
79  return *ret;
80  }
81 
85  template<typename T>
87  {
88  const std::type_index &type = typeid(T);
89  auto existing = this->_components.find(type);
90  if (existing == this->_components.end())
91  return nullptr;
92  return static_cast<T *>(existing->second.get());
93  }
94 
99  template<typename T>
100  const T &getComponent() const
101  {
102  const T *ret = this->tryGetComponent<T>();
103  if (ret == nullptr)
104  throw NotFoundError("No component could be found with the type \"" + std::string(typeid(T).name()) + "\".");
105  return *ret;
106  }
107 
111  template<typename T>
112  const T *tryGetComponent() const
113  {
114  const std::type_index &type = typeid(T);
115  auto existing = this->_components.find(type);
116  if (existing == this->_components.end())
117  return nullptr;
118  return static_cast<T *>(existing->second.get());
119  }
120 
123  template<typename T>
124  bool hasComponent() const
125  {
126  const std::type_info &type = typeid(T);
127  return this->hasComponent(type);
128  }
129 
132  bool hasComponent(const std::type_info &type) const;
133 
136  bool hasComponent(const std::type_index &type) const;
137 
141  template<typename T, typename ...TNested, typename ...Types>
142  Entity &addComponent(Types &&...params)
143  {
144  const std::type_index &type = typeid(T);
145  if (this->hasComponent(type))
146  throw DuplicateError("A component of the type \"" + std::string(type.name()) + "\" already exists on " + this->_name + ".");
147  this->_components[type] = std::make_unique<T>(*this, TypeHolder<TNested>()..., std::forward<Types>(params)...);
148  if (this->_notifyScene)
149  this->_componentAdded(type);
150  return *this;
151  }
152 
155  Entity &addComponent(const Component &component);
156 
160  template<typename T>
162  {
163  const std::type_info &type = typeid(T);
164  auto existing = this->_components.find(type);
165  if (existing == this->_components.end())
166  throw NotFoundError("No component could be found with the type \"" + std::string(type.name()) + "\".");
167  this->_components.erase(existing);
168  if (this->_notifyScene)
169  this->_componentRemoved(type);
170  return *this;
171  }
172 
174  explicit Entity(Scene &wal, std::string name, bool notifyScene = true);
176  Entity(const Entity &);
178  Entity(Entity &&) = default;
180  ~Entity() = default;
182  Entity &operator=(const Entity &) = delete;
183 
185  bool operator==(const Entity &) const;
186  };
187 } // namespace WAL
WAL::Entity::tryGetComponent
T * tryGetComponent()
Get a component of a specific type or null if not found.
Definition: Entity.hpp:86
WAL::Entity::_componentAdded
void _componentAdded(const std::type_index &type)
Callback called when a component is added.
Definition: Entity.cpp:78
WAL::Entity::_scene
Scene & _scene
A reference to the ECS.
Definition: Entity.hpp:51
WAL
Definition: Component.cpp:7
WAL::Entity::_componentRemoved
void _componentRemoved(const std::type_index &type)
Callback called when a component is removed.
Definition: Entity.cpp:83
WAL::Entity::getName
std::string getName() const
Get the name of the entity.
Definition: Entity.cpp:37
WAL::Component
Represent a single component of WAL.
Definition: Component.hpp:17
WAL::Entity::_uid
unsigned _uid
The unique ID of the entity.
Definition: Entity.hpp:24
WAL::Wal
The main WAL class, it is used to setup and run the ECS.
Definition: Wal.hpp:27
WAL::Entity::addComponent
Entity & addComponent(Types &&...params)
Add a component to this entity. The component is constructed in place.
Definition: Entity.hpp:142
WAL::Entity
An entity of the WAL's ECS.
Definition: Entity.hpp:20
WAL::Entity::setDisable
void setDisable(bool disabled)
Disable this entity.
Definition: Entity.cpp:52
Component.hpp
WAL::Entity::Entity
Entity(Scene &wal, std::string name, bool notifyScene=true)
A default constructor.
Definition: Entity.cpp:14
WAL::Entity::hasComponent
bool hasComponent() const
Check if this entity has a component.
Definition: Entity.hpp:124
WalError.hpp
WAL::Entity::nextID
static unsigned nextID
This ID will be the one of the next entity created.
Definition: Entity.hpp:37
WAL::TypeHolder
A class only used to specify template arguments.
Definition: TypeHolder.hpp:12
WAL::Entity::isDisable
bool isDisable() const
Used if the entity is disabled.
Definition: Entity.cpp:47
WAL::Entity::~Entity
~Entity()=default
A default destructor.
WAL::Entity::getUid
unsigned getUid() const
Get the ID of the entity.
Definition: Entity.cpp:32
WAL::Entity::setName
void setName(std::string &name)
Set the name of the entity.
Definition: Entity.cpp:42
WAL::Entity::removeComponent
Entity & removeComponent()
Remove a specific component (by type).
Definition: Entity.hpp:161
WAL::Entity::_components
std::unordered_map< std::type_index, std::unique_ptr< Component > > _components
The list of the components of this entity.
Definition: Entity.hpp:34
WAL::Entity::tryGetComponent
const T * tryGetComponent() const
Get a component of a specific type or null if not found.
Definition: Entity.hpp:112
WAL::Entity::_name
std::string _name
An entity name (this is useful for debugging)
Definition: Entity.hpp:26
WAL::Entity::Scene
friend Scene
Definition: Entity.hpp:46
WAL::Scene
Represent a single scene that contains entities.
Definition: Scene.hpp:17
WAL::Entity::operator==
bool operator==(const Entity &) const
Definition: Entity.cpp:88
WAL::Entity::getComponent
T & getComponent()
Get a component of a specific type.
Definition: Entity.hpp:74
WAL::Entity::scheduleDeletion
void scheduleDeletion()
Schedule this entity for deletion.
Definition: Entity.cpp:98
WAL::Entity::getComponent
const T & getComponent() const
Get a component of a specific type.
Definition: Entity.hpp:100
TypeHolder.hpp
WAL::Entity::operator=
Entity & operator=(const Entity &)=delete
An entity is not assignable.
WAL::Entity::_disabled
bool _disabled
Is this entity enabled?
Definition: Entity.hpp:28
WAL::Entity::_shouldDelete
bool _shouldDelete
Has this entity been scheduled for deletion?
Definition: Entity.hpp:30
WAL::NotFoundError
An exception informing the user that something could not be found.
Definition: WalError.hpp:43
WAL::Entity::shouldDelete
bool shouldDelete() const
Has this entity been scheduled for deletion?
Definition: Entity.cpp:93
WAL::DuplicateError
An exception informing the user that something already exists.
Definition: WalError.hpp:29
WAL::Entity::_notifyScene
bool _notifyScene
Should this entity notify the scene of component changes?
Definition: Entity.hpp:32