diff options
Diffstat (limited to 'src/crepe/api')
-rw-r--r-- | src/crepe/api/LoopManager.cpp | 35 | ||||
-rw-r--r-- | src/crepe/api/LoopManager.h | 21 | ||||
-rw-r--r-- | src/crepe/api/LoopManager.hpp | 34 |
3 files changed, 70 insertions, 20 deletions
diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index 637fbe1..ff428fd 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -13,18 +13,17 @@ using namespace crepe; using namespace std; -LoopManager::LoopManager() - : systems({ - ScriptSystem{this->mediator}, - PhysicsSystem{this->mediator}, - CollisionSystem{this->mediator}, - AnimatorSystem{this->mediator}, - ParticleSystem{this->mediator}, - RenderSystem{this->mediator}, - InputSystem{this->mediator}, - EventSystem{this->mediator}, - AudioSystem{this->mediator}, - }) { } +LoopManager::LoopManager() { + this->load_system<ScriptSystem>(); + this->load_system<PhysicsSystem>(); + this->load_system<CollisionSystem>(); + this->load_system<AnimatorSystem>(); + this->load_system<ParticleSystem>(); + this->load_system<RenderSystem>(); + this->load_system<InputSystem>(); + this->load_system<EventSystem>(); + this->load_system<AudioSystem>(); +} void LoopManager::start() { this->setup(); @@ -32,16 +31,16 @@ void LoopManager::start() { } void LoopManager::fixed_update() { - for (System & system : this->systems) { - if (!system.active) continue; - system.fixed_update(); + for (auto & [type, system] : this->systems) { + if (!system->active) continue; + system->fixed_update(); } } void LoopManager::frame_update() { - for (System & system : this->systems) { - if (!system.active) continue; - system.frame_update(); + for (auto & [type, system] : this->systems) { + if (!system->active) continue; + system->frame_update(); } } diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index 1183a4d..4b1fc1e 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -73,15 +73,32 @@ private: SaveManager save_manager{mediator}; //! SDL context \todo no more singletons! - SDLContext & sdl_context = SDLContext::get_instance(); + SDLContext & sdl_context = mediator.sdl_context; //! Loop timer \todo no more singletons! LoopTimer & loop_timer = LoopTimer::get_instance(); private: /** * \brief Collection of System instances + * + * This map holds System instances indexed by the system's class typeid. It is filled in the + * constructor of \c LoopManager using LoopManager::load_system. + */ + std::unordered_map<std::type_index, std::unique_ptr<System>> systems; + /** + * \brief Initialize a system + * \tparam T System type (must be derivative of \c System) + */ + template <class T> + void load_system(); + /** + * \brief Retrieve a reference to ECS system + * \tparam T System type + * \returns Reference to system instance + * \throws std::runtime_error if the System is not initialized */ - std::vector<System> systems; + template <class T> + T & get_system(); }; } // namespace crepe diff --git a/src/crepe/api/LoopManager.hpp b/src/crepe/api/LoopManager.hpp index 51afa70..627b281 100644 --- a/src/crepe/api/LoopManager.hpp +++ b/src/crepe/api/LoopManager.hpp @@ -1,5 +1,10 @@ #pragma once +#include <memory> +#include <cassert> +#include <format> + +#include "../system/System.h" #include "LoopManager.h" namespace crepe { @@ -9,4 +14,33 @@ void LoopManager::add_scene() { this->scene_manager.add_scene<T>(); } +template <class T> +T & LoopManager::get_system() { + using namespace std; + static_assert(is_base_of<System, T>::value, "get_system must recieve a derivative class of System"); + + const type_info & type = typeid(T); + if (!this->systems.contains(type)) + throw runtime_error(format("LoopManager: {} is not initialized", type.name())); + + System * system = this->systems.at(type).get(); + T * concrete_system = dynamic_cast<T *>(system); + assert(concrete_system != nullptr); + + return *concrete_system; +} + +template <class T> +void LoopManager::load_system() { + using namespace std; + static_assert(is_base_of<System, T>::value, + "load_system must recieve a derivative class of System"); + + const type_info & type = typeid(T); + if (this->systems.contains(type)) + throw runtime_error(format("LoopManager: {} is already initialized", type.name())); + System * system = new T(this->mediator); + this->systems[type] = unique_ptr<System>(system); +} + } // namespace crepe |