aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe/api')
-rw-r--r--src/crepe/api/LoopManager.cpp35
-rw-r--r--src/crepe/api/LoopManager.h21
-rw-r--r--src/crepe/api/LoopManager.hpp34
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