wPlot2D version: 0.1.0
A lightweight C++ library for clear and customizable 2D scientific plots.
Loading...
Searching...
No Matches
wEntity.hpp
Go to the documentation of this file.
1/*
2+---------------------------------------------------------------------------------------------------------------------------------------------------+
3Created by Wilfried Koch.
4Copyright @ 2025 Wilfried Koch. All rights reserved.
5+---------------------------------------------------------------------------------------------------------------------------------------------------+
6*/
7
8#ifndef W_ENTITY_HPP
9#define W_ENTITY_HPP
10
11#include <memory>
12#include <unordered_map>
13#include <stdexcept>
14#include <type_traits>
15
16#include "wComponent.hpp"
17
18namespace wEngine
19{
20
21 /*
22 * @brief Generates a new unique component type ID.
23 * @return A unique integer for component type identification.
24 */
25 inline std::size_t getNextComponentTypeID( )
26 {
27 static std::size_t componentTypeCounter = 0;
28 return componentTypeCounter++;
29 }
30
31 /*
32 * @brief Returns the unique type ID associated with a specific component type.
33 * @tparam ComponentType The type of the component.
34 * @return A unique integer identifying the component type.
35 */
36 template< typename ComponentType >
37 std::size_t getComponentTypeID( ) noexcept
38 {
39 static std::size_t componentTypeID = getNextComponentTypeID( );
40 return componentTypeID;
41 }
42
59 class Entity
60 {
61 public:
62 /*
63 * @brief Default constructor. Generates a new entity with a unique ID.
64 */
65 Entity( );
66
67 /*
68 * @brief Destructor. Disables all attached components before destruction.
69 */
70 virtual ~Entity( );
71
76 [[nodiscard]] unsigned int getEntityID( ) const;
77
81 void clearComponents( );
82
89 static void resetEntityIDCounter( );
90
103 template< typename T, typename... Args >
104 std::shared_ptr< T > addComponent( Args&&... args )
105 {
106 static_assert( std::is_base_of< Component, T >::value, "T must be derived from Component" );
107
108 auto typeID = getComponentTypeID< T >( );
109 if (mComponents.contains( typeID ))
110 {
111 std::cerr << "Warning: Component " << typeid( T ).name( )
112 << " already exists in entity " << mEntityID << std::endl;
113 throw std::runtime_error( "Component already exists in entity" );
114 }
115
116 auto component = std::make_shared< T >( std::forward< Args >( args )... );
117 component->setParent( this );
118 mComponents[ typeID ] = component;
119
120 return component;
121 }
122
130 template< typename T >
132 {
133 static_assert( std::is_base_of< Component, T >::value, "T must be derived from Component" );
134
135 auto typeID = getComponentTypeID< T >( );
136 mComponents.erase( typeID );
137 }
138
145 template< typename T >
146 [[nodiscard]] bool hasComponent( ) const noexcept
147 {
148 static_assert( std::is_base_of< Component, T >::value, "T must be derived from Component" );
149
150 return mComponents.contains( getComponentTypeID< T >( ) );
151 }
152
159 template< typename T >
160 [[nodiscard]] std::shared_ptr< T > getComponent( ) const
161 {
162 static_assert( std::is_base_of< Component, T >::value, "T must be derived from Component" );
163
164 auto typeID = getComponentTypeID< T >( );
165 auto it = mComponents.find( typeID );
166 if (it != mComponents.end( ))
167 {
168 return std::dynamic_pointer_cast< T >( it->second );
169 }
170
171 return nullptr;
172 }
173
186 template< typename T >
187 [[nodiscard]] std::shared_ptr< T > requireComponent( const std::string& context = "" ) const
188 {
189 static_assert( std::is_base_of< Component, T >::value, "T must be derived from Component" );
190
191 if (!hasComponent< T >( ))
192 {
193 std::string msg = "Missing required component: ";
194 msg += typeid( T ).name( );
195 if (!context.empty( ))
196 {
197 msg += " in context: " + context;
198 }
199 throw std::runtime_error( msg );
200 }
201
202 return getComponent< T >( );
203 }
204
214 template< typename Interface >
215 [[nodiscard]] std::shared_ptr< Interface > getInterfaceComponent( ) const
216 {
217 for (const auto& [ typeID, component ] : mComponents)
218 {
219 auto interfaceComponent = std::dynamic_pointer_cast< Interface >( component );
220 if (interfaceComponent)
221 {
222 return interfaceComponent;
223 }
224 }
225 return nullptr;
226 }
227
228 private:
229 unsigned int mEntityID;
230 std::unordered_map< std::size_t, std::shared_ptr< Component > > mComponents;
231
232 static unsigned int sEntityIDCounter;
233 static unsigned int generateNextEntityID( );
234 };
235
236}// End of namespace wEngine
237
238#endif
unsigned int getEntityID() const
Returns the unique ID associated with this entity.
Definition wEntity.cpp:37
std::shared_ptr< T > addComponent(Args &&... args)
Adds a new component of type T to the entity.
Definition wEntity.hpp:104
std::shared_ptr< T > requireComponent(const std::string &context="") const
Retrieves the component of type T and throws if it's missing.
Definition wEntity.hpp:187
void clearComponents()
Removes all components currently attached to the entity.
Definition wEntity.cpp:42
void removeComponent()
Removes the component of type T from the entity.
Definition wEntity.hpp:131
virtual ~Entity()
Definition wEntity.cpp:23
std::shared_ptr< T > getComponent() const
Retrieves the component of type T attached to the entity.
Definition wEntity.hpp:160
std::shared_ptr< Interface > getInterfaceComponent() const
Returns the first component that implements the specified interface.
Definition wEntity.hpp:215
bool hasComponent() const noexcept
Checks whether the entity has a component of type T.
Definition wEntity.hpp:146
Entity()
Definition wEntity.cpp:17
static void resetEntityIDCounter()
Resets the global entity ID counter to zero.
Definition wEntity.cpp:55
Definition wColorComponent.cpp:9
std::size_t getComponentTypeID() noexcept
Definition wEntity.hpp:37
std::size_t getNextComponentTypeID()
Definition wEntity.hpp:25