#pragma once #include "Component.hpp" #include #include #include #include #include struct Entity; struct Entity { std::vector> components; GameContext *context = nullptr; bool queuedForFree = false; /** * Injects the global game context/state so the entity and its components can * stay in sync with the global scroll/meter/reset state and known * entity references. * * @param ctx Current game-wide context containing globals like scroll, entity handles, and * reset flags. */ void SetContext(GameContext *ctx) { context = ctx; for (auto &component : components) { component->context = ctx; } } /** * Adds a component of type T to the entity, wiring ownership, the game * context, and calling `Setup` immediately. * * @tparam T Component subclass type to add. * @return Reference to the newly created component. */ template T> T &AddComponent() { auto &ptr = components.emplace_back(std::make_shared()); ptr->entity = this; ptr->context = context; ptr->Setup(); return static_cast(*ptr); } /** * Finds the first component of type T in this entity and returns a * reference_wrapper if found. * * @tparam T Component subclass to get. * @return Optional ref wrapper to the component if found, otherwise empty. */ template T> std::optional> GetComponent() const { for (auto &c : components) { T *cast = dynamic_cast(c.get()); if (cast) { return *cast; } } return {}; } /** * Propagates the delta time to all owned components so they can run their * per-frame logic while sharing the same global context state. * * @param dt Time elapsed since the last frame. */ void Update(float dt) { for (auto &c : components) { c->Update(dt); } } /** * Marks the entity for deferred destruction at the end of a systems tick. * Inspired by Godot! */ void QueueFree() { queuedForFree = true; } /** * Propagates cleanup call to all owned components so they can release any * resources or references before the entity is destroyed. */ void Cleanup() { for (auto &c : components) { c->Cleanup(); } } };