diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a70341..6c5943f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,7 @@ if(ECOSIM_BUILD_APP) src/scene/Scene.cpp src/scene/Scene_Menu.cpp src/scene/Scene_Simulation.cpp + src/simulation/SimulationWorld.cpp ) set(IMGUI_SOURCES diff --git a/include/EcoSimEngine/SimulationEngine.hpp b/include/EcoSimEngine/SimulationEngine.hpp index 617fe6d..dd37969 100644 --- a/include/EcoSimEngine/SimulationEngine.hpp +++ b/include/EcoSimEngine/SimulationEngine.hpp @@ -1,13 +1,11 @@ #pragma once -#include #include #include "SFML/Graphics/RenderWindow.hpp" #include "EcoSimEngine/scene/Scene.hpp" #include "EcoSimEngine/scene/SceneManager.hpp" #include "EcoSimEngine/ecs/Assets.hpp" -#include "EcoSimEngine/system/SystemManager.hpp" #include "EcoSimEngine/gui/GUIManager.hpp" #include "EcoSimEngine/event/EventBus.hpp" @@ -26,9 +24,6 @@ class SimulationEngine { Assets m_assets; SceneManager m_sceneManager; - SystemManager m_systemManager; - ComponentManager m_componentManager; - EntityManager m_entityManager; std::unique_ptr m_guiManager; EventBus m_eventBus; @@ -59,8 +54,5 @@ class SimulationEngine { bool isRunning() const; SceneManager& sceneManager() noexcept { return m_sceneManager; } - SystemManager& systemManager() noexcept { return m_systemManager; } - EntityManager& entityManager() noexcept { return m_entityManager; } - ComponentManager& componentManager() noexcept { return m_componentManager; } EventBus& eventBus() noexcept { return m_eventBus; } -}; \ No newline at end of file +}; diff --git a/include/EcoSimEngine/ecs/EntityManager.hpp b/include/EcoSimEngine/ecs/EntityManager.hpp index 73a8eae..7715d45 100644 --- a/include/EcoSimEngine/ecs/EntityManager.hpp +++ b/include/EcoSimEngine/ecs/EntityManager.hpp @@ -3,17 +3,17 @@ #include #include #include +#include +#include +#include #include "EcoSimEngine/ecs/Entity.hpp" #include "EcoSimEngine/system/SystemManager.hpp" #include "EcoSimEngine/component/ComponentManager.hpp" - using EntityVec = std::vector>; using EntityMap = std::map; -class SystemManager; // forward declaration - /** * @brief EntityManager class for managing game entities. * @@ -25,116 +25,129 @@ class SystemManager; // forward declaration * Entities are managed via std::shared_ptr to allow multiple references * without ownership issues. Updates should be called once per simulation tick. */ -class EntityManager { - EntityVec m_entities; // all entities - EntityVec m_entitiesToAdd; // entities to add next update - EntityMap m_entityMap; // map from entity tag to vectors - size_t m_totalEntities{ 0 }; // total entities created - - // Pointer to the engine's SystemManger so we can notify on signature change / destruction - SystemManager* m_systemManager{ nullptr }; - ComponentManager* m_componentManager{ nullptr }; +class EntityManager +{ + EntityVec m_entities; // all entities + EntityVec m_entitiesToAdd; // entities to add next update + EntityMap m_entityMap; // map from entity tag to vectors + size_t m_totalEntities{0}; // total entities created + // Reference to the SystemManager and ComponentManager is required for proper ECS operation. + SystemManager &m_systemManager; + ComponentManager &m_componentManager; /** * @brief Removes all inactive entities from the given vector. * * This helper function ensures that only active entities remain in the container. * Uses std::erase_if (C++20) to remove elements where the entity's isActive() returns false. - * + * * @param vec Reference to a vector of shared pointers to Entity objects. * The vector is modified directly; inactive entities are removed. */ - inline void removeDeadEntities(EntityVec& vec) noexcept + inline void removeDeadEntities(EntityVec &vec) noexcept { // Erase elements from the vector where the lambda predicate returns true. // Lambda returns true if the entity is inactive, causing its removal. std::erase_if(vec, - [](const std::shared_ptr& entity) { - return !entity->isActive(); - }); + [](const std::shared_ptr &entity) + { + return !entity->isActive(); + }); } public: // Require dependencies in the constructor - EntityManager(SystemManager* sm, ComponentManager* cm) - : m_systemManager(sm), m_componentManager(cm) { + EntityManager( + SystemManager &systemManager, + ComponentManager &componentManager) + : m_systemManager(systemManager), + m_componentManager(componentManager) + { } - EntityManager() = default; - - void setSystemManager(SystemManager* sm) { m_systemManager = sm; } // Give the EntityManager a reference to the SystemManager so it can notify about changes. - void setComponentManager(ComponentManager* cm) { m_componentManager = cm; } // Give the EntityManager a reference to the ComponentManager so it can manage components. - // Find entity by numeric id. Linear search � fine for small projects / prototypes. - std::shared_ptr getEntityById(size_t id) { - for (auto& e : m_entities) { - if (e && e->id() == id) return e; + std::shared_ptr getEntityById(size_t id) + { + for (auto &e : m_entities) + { + if (e && e->id() == id) + return e; } - for (auto& e : m_entitiesToAdd) { - if (e && e->id() == id) return e; + for (auto &e : m_entitiesToAdd) + { + if (e && e->id() == id) + return e; } return nullptr; } // Add a component via the manager so systems are notified automatically. - template - T& addComponent(const std::shared_ptr& entity, Args&&... args) { - auto & comp = m_componentManager->add(entity->id(), std::forward(args)...); - entity->signature().set(ComponentType::index, true); // mark component as present in signature (set bit ON) - if (m_systemManager) m_systemManager->EntitySignatureChanged(entity->id(), entity->signature()); // notify systemManager of signature change + template + T &addComponent(const std::shared_ptr &entity, Args &&...args) + { + auto &comp = m_componentManager.add(entity->id(), std::forward(args)...); + entity->signature().set(ComponentType::index, true); // mark component as present in signature (set bit ON) + m_systemManager.EntitySignatureChanged(entity->id(), entity->signature()); // notify systemManager of signature change return comp; } - template - void removeComponent(const std::shared_ptr& entity) { - m_componentManager->remove(entity->id()); - entity->signature().set(ComponentType::index, false); // mark component as absent in signature (set bit OFF) - if (m_systemManager) m_systemManager->EntitySignatureChanged(entity->id(), entity->signature()); + template + void removeComponent(const std::shared_ptr &entity) + { + m_componentManager.remove(entity->id()); + entity->signature().set(ComponentType::index, false); // mark component as absent in signature (set bit OFF) + m_systemManager.EntitySignatureChanged(entity->id(), entity->signature()); } // Destroy an entity and clean up all ECS state associated with it. - void destroyEntity(const std::shared_ptr& entity) { - if (!entity) return; + void destroyEntity(const std::shared_ptr &entity) + { + if (!entity) + return; const auto id = entity->id(); entity->destroy(); - if (m_componentManager) m_componentManager->entityDestroyed(id); + m_componentManager.entityDestroyed(id); entity->signature().reset(); // clear the signature to indicate no components are present - - if (m_systemManager) m_systemManager->EntityDestroyed(entity->id()); + + m_systemManager.EntityDestroyed(entity->id()); } - template - bool hasComponent(const std::shared_ptr& entity) const { - return m_componentManager->has(entity->id()); + template + bool hasComponent(const std::shared_ptr &entity) const + { + return m_componentManager.has(entity->id()); } - template - T& getComponent(const std::shared_ptr& entity) { - return m_componentManager->get(entity->id()); + template + T &getComponent(const std::shared_ptr &entity) + { + return m_componentManager.get(entity->id()); } - template - const T& getComponent(const std::shared_ptr& entity) const { - return m_componentManager->get(entity->id()); + template + const T &getComponent(const std::shared_ptr &entity) const + { + return m_componentManager.get(entity->id()); } - void update() { + void update() + { // Add entities from m_entitiesToAdd to: // 1. The main entity vector (m_entities) // 2. The tag-indexed map (m_entityMap) - for (const auto& entity : m_entitiesToAdd) { + for (const auto &entity : m_entitiesToAdd) + { m_entities.push_back(entity); m_entityMap[entity->tag()].push_back(entity); - // notify systems about this entity's current signature - if (m_systemManager) { - m_systemManager->EntitySignatureChanged(entity->id(), entity->signature()); - } + // notify systems about this entity's current signature + m_systemManager.EntitySignatureChanged(entity->id(), entity->signature()); + } m_entitiesToAdd.clear(); @@ -142,12 +155,14 @@ class EntityManager { removeDeadEntities(m_entities); // remove dead entities from each vector in the entity map - for (auto& [tag, entityVec] : m_entityMap) { + for (auto &[tag, entityVec] : m_entityMap) + { removeDeadEntities(entityVec); } } - std::shared_ptr addEntity(const std::string& tag) { + std::shared_ptr addEntity(const std::string &tag) + { // Must use 'new' here instead of std::make_shared because Entity's constructor is private. // std::make_shared constructs outside EntityManager, so it cannot access private constructors despite friendship. std::shared_ptr entity(new Entity(m_totalEntities++, tag)); @@ -155,37 +170,44 @@ class EntityManager { return entity; } - EntityVec& getEntities() { - return m_entities; + EntityVec &getEntities() + { + return m_entities; } - EntityVec& getEntities(const std::string& tag) { - return m_entityMap[tag]; - } + EntityVec &getEntities(const std::string &tag) + { + return m_entityMap[tag]; + } - const EntityMap& getEntityMap() const noexcept + const EntityMap &getEntityMap() const noexcept { - return m_entityMap; + return m_entityMap; } - void clearAll() noexcept { + void clearAll() noexcept + { // 1) Mark all entities destroyed and notify systems to remove them - for (const auto& entity : m_entities) { - if (!entity) continue; - if (entity->isActive()) entity->destroy(); - if (m_systemManager) m_systemManager->EntityDestroyed(entity->id()); + for (const auto &entity : m_entities) + { + if (!entity) + continue; + if (entity->isActive()) + entity->destroy(); + m_systemManager.EntityDestroyed(entity->id()); } - for (const auto& entity : m_entitiesToAdd) { - if (!entity) continue; - if (entity->isActive()) entity->destroy(); - if (m_systemManager) m_systemManager->EntityDestroyed(entity->id()); + for (const auto &entity : m_entitiesToAdd) + { + if (!entity) + continue; + if (entity->isActive()) + entity->destroy(); + m_systemManager.EntityDestroyed(entity->id()); } // 2) Clear all component storage to avoid stale components - if (m_componentManager) { - m_componentManager->clear(); - } + m_componentManager.clear(); // 3) Remove all entities from our containers m_entities.clear(); @@ -198,6 +220,4 @@ class EntityManager { // m_freeIds.clear(); // m_entitiesById.clear(); } - - }; \ No newline at end of file diff --git a/include/EcoSimEngine/scene/Scene_Simulation.hpp b/include/EcoSimEngine/scene/Scene_Simulation.hpp index 7832933..7a05717 100644 --- a/include/EcoSimEngine/scene/Scene_Simulation.hpp +++ b/include/EcoSimEngine/scene/Scene_Simulation.hpp @@ -9,15 +9,15 @@ #include "EcoSimEngine/component/Components.hpp" #include "EcoSimEngine/scene/Scene.hpp" -#include "EcoSimEngine/utils/SpatialHash.hpp" +#include "EcoSimEngine/simulation/SimulationWorld.hpp" class Scene_Simulation : public Scene { private: std::string m_simKey; + SimulationWorld m_world; const std::string m_defaultSimulationPath{ "resources/defaults/default_simulation.json" }; std::unordered_map m_speciesColors; - SpatialHash m_spatialHash{ 120.0f }; sf::Clock m_clock; protected: diff --git a/include/EcoSimEngine/simulation/SimulationWorld.hpp b/include/EcoSimEngine/simulation/SimulationWorld.hpp new file mode 100644 index 0000000..4421bf7 --- /dev/null +++ b/include/EcoSimEngine/simulation/SimulationWorld.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "EcoSimEngine/component/ComponentManager.hpp" +#include "EcoSimEngine/ecs/EntityManager.hpp" +#include "EcoSimEngine/system/SystemManager.hpp" + +class SimulationWorld +{ +private: + SystemManager m_systemManager; + ComponentManager m_componentManager; + EntityManager m_entityManager; + +public: + SimulationWorld(); + + void update(float dt); + + EntityManager& entityManager() noexcept; + ComponentManager& componentManager() noexcept; + SystemManager& systemManager() noexcept; +}; diff --git a/src/SimulationEngine.cpp b/src/SimulationEngine.cpp index e0e4ddd..b1c6361 100644 --- a/src/SimulationEngine.cpp +++ b/src/SimulationEngine.cpp @@ -11,14 +11,8 @@ #include "EcoSimEngine/ecs/Assets.hpp" #include "EcoSimEngine/SimulationEngine.hpp" #include "EcoSimEngine/scene/Scene_Menu.hpp" -#include "EcoSimEngine/system/MovementSystem.hpp" -#include "EcoSimEngine/system/AISystem.hpp" - SimulationEngine::SimulationEngine(const std::string& path) - : m_systemManager() - , m_componentManager() - , m_entityManager(&m_systemManager, &m_componentManager) { // Subscribe to GUICommand events early m_eventBus.subscribe([this](const Event::GUICommand& cmd) { @@ -75,25 +69,6 @@ void SimulationEngine::init(const std::string& path) { m_guiManager = std::make_unique(this); m_guiManager->init(m_window); - // Movement system - auto movement = m_systemManager.RegisterSystem(); - Signature moveSig; - moveSig.set(COMP_INDEX_CTransform); - moveSig.set(COMP_INDEX_CBehavior); // optional depending on your logic - m_systemManager.SetSignature(moveSig); - - // AI system - auto ai = m_systemManager.RegisterSystem(); - Signature aiSig; - aiSig.set(COMP_INDEX_CBehavior); - aiSig.set(COMP_INDEX_CTransform); - m_systemManager.SetSignature(aiSig); - - - - - - // --- Set initial scene --- m_sceneManager.changeScene(SceneID::Menu, std::make_shared(this)); } diff --git a/src/scene/Scene_Simulation.cpp b/src/scene/Scene_Simulation.cpp index 8cfb076..234e32a 100644 --- a/src/scene/Scene_Simulation.cpp +++ b/src/scene/Scene_Simulation.cpp @@ -19,24 +19,22 @@ #include "EcoSimEngine/scene/Scene_Simulation.hpp" #include "EcoSimEngine/math/Vec2.hpp" #include "EcoSimEngine/utils/Utils.hpp" -#include "EcoSimEngine/utils/SpatialHash.hpp" -#include "EcoSimEngine/system/MovementSystem.hpp" -#include "EcoSimEngine/system/AISystem.hpp" - -Scene_Simulation::Scene_Simulation(SimulationEngine* engine, const std::string& simKey) - : Scene(engine) - , m_simKey(simKey) +Scene_Simulation::Scene_Simulation(SimulationEngine *engine, const std::string &simKey) + : Scene(engine), m_simKey(simKey) { init(simKey); } -void Scene_Simulation::init(const std::string& simulationKey) { +void Scene_Simulation::init(const std::string &simulationKey) +{ // Decide whether to load a named simulation (if provided) or default - if (!simulationKey.empty()) { + if (!simulationKey.empty()) + { loadSimulation(simulationKey); } - else { + else + { loadDefaultSimulation(m_defaultSimulationPath); } @@ -58,57 +56,66 @@ void Scene_Simulation::init(const std::string& simulationKey) { registerAction(sf::Keyboard::Key::D, ActionName::RIGHT); } -void Scene_Simulation::loadSimulation(const std::string& simulationKey) { +void Scene_Simulation::loadSimulation(const std::string &simulationKey) +{ // TODO: implement full named-save loading; for now attempt to open a file, fallback to default. const auto path = buildSavePathFromKey(simulationKey); std::ifstream ifs(path); - if (!ifs.is_open()) { + if (!ifs.is_open()) + { std::cerr << "No save found for key \"" << simulationKey - << "\" at " << path << " � loading default.\n"; + << "\" at " << path << " � loading default.\n"; loadDefaultSimulation(m_defaultSimulationPath); return; } nlohmann::json simJson; - try { + try + { ifs >> simJson; } - catch (const nlohmann::json::parse_error& e) { + catch (const nlohmann::json::parse_error &e) + { std::cerr << "Failed to parse save file " << path << ": " << e.what() - << " � loading default.\n"; + << " � loading default.\n"; loadDefaultSimulation(m_defaultSimulationPath); return; } // Clear any existing entities - m_simulation->entityManager().clearAll(); + m_world.entityManager().clearAll(); spawnFromJson(simJson); } -void Scene_Simulation::loadDefaultSimulation(const std::string& defaultSimulationPath) { +void Scene_Simulation::loadDefaultSimulation(const std::string &defaultSimulationPath) +{ std::ifstream ifs(defaultSimulationPath); - if (!ifs.is_open()) { + if (!ifs.is_open()) + { std::cerr << "Error: Could not open default simulation file: " << defaultSimulationPath << std::endl; return; } nlohmann::json simJson; - try { + try + { ifs >> simJson; } - catch (const nlohmann::json::parse_error& e) { + catch (const nlohmann::json::parse_error &e) + { std::cerr << "Failed to parse default simulation file " << defaultSimulationPath << ": " << e.what() << "\n"; return; } // Clear any existing entities - m_simulation->entityManager().clearAll(); + m_world.entityManager().clearAll(); spawnFromJson(simJson); } -void Scene_Simulation::spawnFromJson(const nlohmann::json& simJson) { - auto& em = m_simulation->entityManager(); - auto& cm = m_simulation->componentManager(); +void Scene_Simulation::spawnFromJson(const nlohmann::json &simJson) +{ + auto &em = m_world.entityManager(); + auto &cm = m_world.componentManager(); // read population counts auto populations = simJson["simulation"]["initialPopulation"]; @@ -125,13 +132,15 @@ void Scene_Simulation::spawnFromJson(const nlohmann::json& simJson) { // Precompute species colours (single pass) int idx = 0; - for (auto& [speciesName, popData] : populations.items()) { - float hue = (idx * 360.0f) / std::max(1, speciesCount); // evenly spaced hues + for (auto &[speciesName, popData] : populations.items()) + { + float hue = (idx * 360.0f) / std::max(1, speciesCount); // evenly spaced hues m_speciesColors[speciesName] = hslToRgb(hue, 0.7f, 0.5f); // 70% sat, 50% lightness ++idx; } - for (auto& [speciesName, popData] : populations.items()) { + for (auto &[speciesName, popData] : populations.items()) + { int total = popData["total"]; int males = popData["male"]; int females = popData["female"]; @@ -139,7 +148,8 @@ void Scene_Simulation::spawnFromJson(const nlohmann::json& simJson) { // load species data JSON (per-species data) std::string speciesFile = "resources/definitions/species/" + speciesName + ".json"; std::ifstream sf(speciesFile); - if (!sf.is_open()) { + if (!sf.is_open()) + { std::cerr << "Could not open species file: " << speciesFile << "\n"; continue; } @@ -147,7 +157,8 @@ void Scene_Simulation::spawnFromJson(const nlohmann::json& simJson) { sf >> speciesJson; // create entities - for (int i = 0; i < total; ++i) { + for (int i = 0; i < total; ++i) + { auto entity = em.addEntity(speciesName); // --- add Components --- @@ -161,7 +172,7 @@ void Scene_Simulation::spawnFromJson(const nlohmann::json& simJson) { em.addComponent(entity, Vec2f(x, y)); // reproductive component - auto& repro = em.addComponent(entity); + auto &repro = em.addComponent(entity); repro.sex = (i < males ? Sex::Male : Sex::Female); repro.canReproduce = true; @@ -175,53 +186,36 @@ void Scene_Simulation::spawnFromJson(const nlohmann::json& simJson) { em.update(); } -void Scene_Simulation::sDoAction(const Action& action) { - if (action.type() != ActionType::START) return; +void Scene_Simulation::sDoAction(const Action &action) +{ + if (action.type() != ActionType::START) + return; if (action.name() == ActionName::QUIT_AND_SAVE) { onEnd(); } - } -void Scene_Simulation::update() { - auto& em = m_simulation->entityManager(); - auto& cm = m_simulation->componentManager(); - - em.update(); - +void Scene_Simulation::update() +{ float dt = m_clock.restart().asSeconds(); - if (dt <= 0.0f) dt = 1.0f / 60.0f; - - // --- rebuild spatial hash every tick (fast) --- - m_spatialHash.clear(); - for (const auto& ent : em.getEntities()) { - if (!ent || !ent->isActive()) continue; - if (!cm.has(ent->id())) continue; - const auto& t = cm.get(ent->id()); - m_spatialHash.insert(ent, t.pos.x, t.pos.y); + + if (dt <= 0.0f) + { + dt = 1.0f / 60.0f; } - // Implement pause functionality - if (!m_paused) { - //sDrag(); // MAYDELETE - // call AI first, then Movement - if (auto ais = m_simulation->systemManager().GetSystem()) { - ais->update(em, cm, dt); - } - if (auto ms = m_simulation->systemManager().GetSystem()) { - ms->update(em, cm, dt); - } - //sStatus(); - //sCollision(); - //sAnimation(); - //sCamera(); + // update when not paused + if (!m_paused) + { + m_world.update(dt); m_currentFrame++; } } -void Scene_Simulation::onEnd() { +void Scene_Simulation::onEnd() +{ // When the scene ends, change back to the MENU scene // Important: pass m_simulation (the SimulationEngine context) to Scene_Menu, @@ -232,26 +226,29 @@ void Scene_Simulation::onEnd() { .changeScene(SceneID::Menu, std::make_shared(m_simulation)); } +void Scene_Simulation::sRender() +{ + auto &em = m_world.entityManager(); + auto &cm = m_world.componentManager(); -void Scene_Simulation::sRender() { - auto& em = m_simulation->entityManager(); - auto& cm = m_simulation->componentManager(); - - sf::RenderWindow& win = m_simulation->window(); + sf::RenderWindow &win = m_simulation->window(); win.clear(sf::Color(15, 15, 20)); - for (const auto& entity : em.getEntities()) { - if (!entity->isActive()) continue; + for (const auto &entity : em.getEntities()) + { + if (!entity->isActive()) + continue; const auto id = entity->id(); - if (!cm.has(id)) continue; - const auto& transform = cm.get(id); + if (!cm.has(id)) + continue; + const auto &transform = cm.get(id); sf::CircleShape circle(10.0f); - circle.setOrigin({ circle.getRadius(), circle.getRadius() }); - circle.setPosition({ transform.pos.x, transform.pos.y }); + circle.setOrigin({circle.getRadius(), circle.getRadius()}); + circle.setPosition({transform.pos.x, transform.pos.y}); // lookup species color - const auto& species = cm.get(id); + const auto &species = cm.get(id); auto it = m_speciesColors.find(species.speciesName); circle.setFillColor(it != m_speciesColors.end() ? it->second : sf::Color::White); @@ -259,7 +256,8 @@ void Scene_Simulation::sRender() { } } -void Scene_Simulation::onGui() { +void Scene_Simulation::onGui() +{ // Example overlay window showing simulation info ImGui::Begin("Simulation Info", nullptr, ImGuiWindowFlags_AlwaysAutoResize); @@ -283,11 +281,11 @@ void Scene_Simulation::onGui() { ImGui::End(); } - // helpers // simple mapping from a simulation key/name to a file path. // Right now we just look in a "saves/" folder; you can change this. -std::string Scene_Simulation::buildSavePathFromKey(const std::string& key) { +std::string Scene_Simulation::buildSavePathFromKey(const std::string &key) +{ return "saves/" + key + ".json"; } diff --git a/src/simulation/SimulationWorld.cpp b/src/simulation/SimulationWorld.cpp new file mode 100644 index 0000000..72f8cad --- /dev/null +++ b/src/simulation/SimulationWorld.cpp @@ -0,0 +1,60 @@ +#include "EcoSimEngine/simulation/SimulationWorld.hpp" + +#include "EcoSimEngine/component/ComponentIndices.hpp" +#include "EcoSimEngine/system/AISystem.hpp" +#include "EcoSimEngine/system/MovementSystem.hpp" + +SimulationWorld::SimulationWorld() + : m_entityManager(m_systemManager, m_componentManager) +{ + // Movement system + m_systemManager.RegisterSystem(); + + Signature movementSignature; + movementSignature.set(COMP_INDEX_CTransform); + + m_systemManager.SetSignature(movementSignature); + + // AI system + m_systemManager.RegisterSystem(); + + Signature aiSignature; + aiSignature.set(COMP_INDEX_CBehavior); + aiSignature.set(COMP_INDEX_CTransform); + + m_systemManager.SetSignature(aiSignature); +} + +void SimulationWorld::update(float dt) +{ + m_entityManager.update(); + + if (auto ai = m_systemManager.GetSystem()) + { + ai->update(m_entityManager, m_componentManager, dt); + } + + if (auto movement = m_systemManager.GetSystem()) + { + movement->update( + m_entityManager, + m_componentManager, + dt); + } +} + +// getters for the managers +EntityManager& SimulationWorld::entityManager() noexcept +{ + return m_entityManager; +} + +ComponentManager& SimulationWorld::componentManager() noexcept +{ + return m_componentManager; +} + +SystemManager& SimulationWorld::systemManager() noexcept +{ + return m_systemManager; +} diff --git a/tests/foundation_tests.cpp b/tests/foundation_tests.cpp index 5a6ef72..0eccf9d 100644 --- a/tests/foundation_tests.cpp +++ b/tests/foundation_tests.cpp @@ -98,7 +98,7 @@ void testSystemManager() { void testEntityDestruction() { SystemManager systems; ComponentManager components; - EntityManager entities(&systems, &components); + EntityManager entities(systems, components); auto transformSystem = systems.RegisterSystem();