2#include "Core/Engine/ECS/Entity.h"
3#include "Core/Engine/ECS/Component.h"
4#include "Core/Engine/ECS/System.h"
5#include "Core/Engine/ECS/Event.h"
6#include "Core/Engine/ECS/Context.h"
10#pragma region Entity Component Iterator
11 template<
typename... Types>
16 , m_includePendingDestroy(includePendingDestroy)
24 template<
typename... Types>
27 return m_isEnd || m_index >= m_context->GetEntityCount();
30 template<
typename... Types>
36 return m_context->GetEntityByIndex(m_index);
39 template<
typename... Types>
56 while (m_index < m_context->GetEntityCount()
57 && (GetEntity() ==
nullptr
58 || !GetEntity()->
template Has<Types...>()
59 || (GetEntity()->IsPendingDestroy() && !m_includePendingDestroy)))
64 if (m_index >= m_context->GetEntityCount())
71#pragma region Entity Component View
72 template<
typename... Types>
88 || !m_first.
GetEntity()->template Has<Types...>())
95#pragma region Entity Iterator
100 , m_includePendingDestroy(includePendingDestroy)
110 return m_isEnd || m_index >= m_context->GetEntityCount();
118 return m_context->GetEntityByIndex(m_index);
126 while (m_index < m_context->GetEntityCount()
127 && (GetEntity() ==
nullptr
128 || (GetEntity()->IsPendingDestroy() && !m_includePendingDestroy)))
133 if (m_index >= m_context->GetEntityCount())
140#pragma region Component Container
150 template<
typename T,
typename ...Args>
153 auto found = m_components.find(GetTypeIndex<T>());
154 if (found != m_components.end())
158 container->m_data = T(std::forward<Args>(args)...);
167 std::unique_ptr<Internal::ComponentContainer<T>> container = std::make_unique<Internal::ComponentContainer<T>>(T(std::forward<Args>(args)...));
172 m_components.insert({ GetTypeIndex<T>(), std::move(container) });
185 auto found = m_components.find(GetTypeIndex<T>());
186 if (found != m_components.end())
198 auto found = m_components.find(GetTypeIndex<T>());
199 if (found != m_components.end())
201 found->second->OnRemove(
this);
202 found->second->OnDestroy(m_context);
204 m_components.erase(found);
213#pragma region Context
219 for (std::unique_ptr<SystemBase>& system : m_systems)
221 system->OnShutdown(
this);
225 for (std::unique_ptr<Entity>& ent : m_entities)
227 if (!ent->IsPendingDestroy())
229 ent->m_pendingDestroy =
true;
230 EmitEvent<Events::OnEntityDestroy>({ ent.get()});
237 for (std::unique_ptr<SystemBase>& system : m_systems)
249 for (std::unique_ptr<Entity>& ent : m_entities)
251 if (ent->GetId() == id)
260 if (index >= m_entities.size())
263 return m_entities[index].get();
269 m_entities.push_back(std::make_unique<Entity>(
this, m_lastEntityId));
271 Entity* ent = m_entities.front().get();
273 EmitEvent<Events::OnEntityCreate>({ ent });
289 m_entities.begin(), m_entities.end(),
290 [e] (
const std::unique_ptr<Entity>& ptr)
292 return ptr.get() == e;
300 e->m_pendingDestroy =
true;
302 EmitEvent<Events::OnEntityDestroy>({ e });
308 m_entities.begin(), m_entities.end(),
309 [e] (
const std::unique_ptr<Entity>& ptr)
311 return ptr.get() == e;
322 m_entities.begin(), m_entities.end(),
323 [&,
this](std::unique_ptr<Entity>& ent)
325 if (ent->IsPendingDestroy())
342 for (std::unique_ptr<Entity>& ent : m_entities)
344 if (!ent->IsPendingDestroy())
346 ent->m_pendingDestroy =
true;
358 for (std::unique_ptr<SystemBase>& system : m_systems)
360 system->OnShutdown(
this);
366 template <
typename T,
typename... Args>
370 for (
const std::unique_ptr<SystemBase>& system : m_systems)
372 if (
dynamic_cast<T*
>(system.get()))
378 std::unique_ptr<SystemBase> system = std::make_unique<T>(std::forward<Args>(args)...);
379 system->OnInit(
this);
381 m_systems.push_back(std::move(system));
383 return dynamic_cast<T*
>(m_systems.back().get());
386 template <
typename T>
390 auto it = std::remove_if(
391 m_systems.begin(), m_systems.end(),
392 [&] (std::unique_ptr<SystemBase>& system)
394 if (dynamic_cast<T*>(system.get()) != nullptr)
396 system->OnShutdown(this);
404 if (it != m_systems.end())
406 m_systems.erase(it, m_systems.end());
413 for (std::unique_ptr<SystemBase>& system : m_systems)
415 if (T* typedSystem =
dynamic_cast<T*
>(system.get()))
423 template <
typename T>
426 for (std::unique_ptr<SystemBase>& system : m_systems)
428 if (
dynamic_cast<T*
>(system.get()) !=
nullptr)
430 system->SetIsEnabled(
true);
435 template <
typename T>
438 for (std::unique_ptr<SystemBase>& system : m_systems)
440 if (
dynamic_cast<T*
>(system.get()) !=
nullptr)
442 system->SetIsEnabled(
false);
447 template <
typename T>
450 for (std::unique_ptr<SystemBase>& system : m_systems)
452 if (
dynamic_cast<T*
>(system.get()) !=
nullptr)
454 return system->IsEnabled();
462 TypeIndex index = GetTypeIndex<T>();
463 auto found = m_subscribers.find(index);
465 if (found == m_subscribers.end())
468 std::vector<Internal::EventSubscriberBase*> subList;
469 subList.push_back(subscriber);
470 m_subscribers.insert({ index, subList });
475 found->second.push_back(subscriber);
482 TypeIndex index = GetTypeIndex<T>();
483 auto found = m_subscribers.find(index);
485 if (found != m_subscribers.end())
489 found->second.begin(), found->second.end(),
494 if (found->second.size() == 0)
496 m_subscribers.erase(found);
503 for (
auto& [typeIndex, subList] : m_subscribers)
507 subList.begin(), subList.end(),
512 if (subList.size() == 0)
514 m_subscribers.erase(typeIndex);
528 for (
auto* ent :
All(includePendingDestroy))
537 TypeIndex index = GetTypeIndex<T>();
538 auto found = m_subscribers.find(index);
540 if (found != m_subscribers.end())
550 template<
typename ...Types>
558 template<
typename ...Types>
561 for (
Entity* ent :
Each<Types...>(includePendingDestroy))
563 viewFunc(ent, ent->template Get<Types>()...);
571 for (std::unique_ptr<SystemBase>& system : m_systems)
573 system->OnUpdate(
this, dt);
This class provides a handle to a component.
Definition Component.h:52
The ECS context class manages entities, systems, and events in the ECS framework.
Definition Context.h:17
void UnregisterSystem()
Unregisters a system from the ECS context.
Definition ECS.h:387
void UnregisterAllSystems()
Un-registers all systems from the ECS context.
Definition ECS.h:355
Internal::EntityComponentView< Types... > Each(bool includePendingDestroy=false)
Iterates over all entities in the ECS context (used in ranged loops)
Definition ECS.h:551
void DisableSystem()
Disables a system in the ECS context.
Definition ECS.h:436
Internal::EntityView All(bool includePendingDestroy=false)
Iterates over all entities in the ECS context (used in ranged loops)
Definition ECS.h:519
void SubscribeEvent(EventSubscriber< T > *subscriber)
Subscribes to an event in the ECS context.
Definition ECS.h:460
void UnsubscribeAll(void *subscriber)
Un-subscribes from all events in the ECS context (usually called in the system destructor)
Definition ECS.h:501
void Reset()
Resets the ECS context, clearing all entities but keeping the systems.
Definition ECS.h:340
void Tick(const F64 dt)
Updates the ECS context (updates all the systems)
Definition ECS.h:567
Entity * CreateEntity()
Creates a new entity in the ECS context.
Definition ECS.h:266
bool ClearPending()
Clears all entities pending destruction in the ECS context.
Definition ECS.h:317
void EmitEvent(const T &event)
Emits an event in the ECS context to all subscribers.
Definition ECS.h:535
U64 GetEntityCount() const noexcept
Gets the total count of entities in the ECS context.
Definition Context.h:40
virtual ~Context()
Destroys the ECS context.
Definition ECS.h:216
void UnsubscribeEvent(EventSubscriber< T > *subscriber)
Unsubscribes from an event in the ECS context.
Definition ECS.h:480
T * RegisterSystem(Args &&... args)
Registers a new system in the ECS context.
Definition ECS.h:367
bool IsSystmEnabled()
Checks if a system is enabled in the ECS context.
Definition ECS.h:448
void EnableSystem()
Enables a system in the ECS context.
Definition ECS.h:424
void DestroyEntity(Entity *e, bool immediate=false)
Destroys an entity in the ECS context.
Definition ECS.h:278
Entity * GetEntityById(U64 id)
Retrieves an entity by its unique identifier.
Definition ECS.h:243
Context()
Constructs a new ECS context.
Entity * GetEntityByIndex(U64 index)
Retrieves an entity by its index.
Definition ECS.h:258
T * GetSystem()
Gets a system from the ECS context.
Definition ECS.h:411
Class to represent an entity in an ECS Context.
Definition Entity.h:10
ComponentHandle< T > Add(Args &&... args)
Adds a component to the entity.
Definition ECS.h:151
bool Remove()
Gets a component from the entity.
Definition ECS.h:196
static constexpr U64 InvalidId
Invalid entity ID.
Definition Entity.h:16
Context * GetContext() const noexcept
Gets the ECS context associated with the entity.
Definition Entity.h:40
bool IsPendingDestroy() const noexcept
Whether the entity has pending destruction.
Definition Entity.h:52
ComponentHandle< T > Get()
Gets a component from the entity.
Definition ECS.h:183
Base class for all event subscribers.
Definition Event.h:27
virtual void OnEvent(Context *context, const T &event)=0
Pure virtual function for handling event callback.
Iterator class to allow easy iteration over entities with components.
Definition Entity.h:157
bool IsEnd() const noexcept
Checks if the iterator is at the end.
Definition ECS.h:25
EntityComponentIterator< Types... > & operator++()
Moves the iterator to the next entity and skips over entities based on input criteria.
Definition ECS.h:40
Entity * GetEntity() const noexcept
Gets the current entity held by the iterator.
Definition ECS.h:31
bool IncludePendingDestroy() const noexcept
Whether the iterator should include pending destruction entities.
Definition Entity.h:178
EntityComponentIterator(Context *context, U64 index, bool isEnd, bool includePendingDestroy)
Initializes the iterator with necessary information.
Definition ECS.h:12
Class to represent a view over a range of entities in an ECS Context.
Definition Entity.h:273
EntityComponentView(const EntityComponentIterator< Types... > &first, const EntityComponentIterator< Types... > &last)
Initializes the view with iterator range.
Definition ECS.h:73
Iterator class to allow easy iteration over entities.
Definition Entity.h:316
Entity * GetEntity() const noexcept
Gets the current entity held by the iterator.
Definition ECS.h:113
bool IsEnd() const noexcept
Checks if the iterator is at the end.
Definition ECS.h:108
EntityIterator(Context *context, U64 index, bool isEnd, bool includePendingDestroy)
Initializes the iterator with necessary information.
Definition ECS.h:96
EntityIterator & operator++()
Moves the iterator to the next entity and skips over entities based on input criteria.
Definition ECS.h:121
Class to represent a view over a range of entities in an ECS Context.
Definition Entity.h:427
Base class for all event subscribers usually systems.
Definition Event.h:12
A concept that checks if a class derives from SystemBase.
Definition Context.h:11
Event for when component is added.
Definition Event.h:75
Event for when component is removed.
Definition Event.h:93
Template class for component containers (concrete implementation of ComponentContainerBase)
Definition Component.h:31
virtual void OnRemove(Entity *entity) override
Method called when an entity is removed.
Definition ECS.h:142