aboutsummaryrefslogtreecommitdiff
path: root/src/crepe
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe')
-rw-r--r--src/crepe/Component.cpp5
-rw-r--r--src/crepe/Component.h8
-rw-r--r--src/crepe/api/LoopManager.cpp35
-rw-r--r--src/crepe/api/LoopManager.h21
-rw-r--r--src/crepe/api/LoopManager.hpp34
-rw-r--r--src/crepe/manager/ComponentManager.h24
-rw-r--r--src/crepe/manager/ReplayManager.h17
7 files changed, 103 insertions, 41 deletions
diff --git a/src/crepe/Component.cpp b/src/crepe/Component.cpp
index acfd35c..141e1a8 100644
--- a/src/crepe/Component.cpp
+++ b/src/crepe/Component.cpp
@@ -3,3 +3,8 @@
using namespace crepe;
Component::Component(game_object_id_t id) : game_object_id(id) {}
+
+Component & Component::operator=(const Component &) {
+ return *this;
+}
+
diff --git a/src/crepe/Component.h b/src/crepe/Component.h
index eff5a58..47c5c34 100644
--- a/src/crepe/Component.h
+++ b/src/crepe/Component.h
@@ -32,9 +32,13 @@ protected:
//! Only ComponentManager can create components
friend class ComponentManager;
- Component(const Component &) = delete;
+ // create snapshot
+ Component(const Component &) = default;
+ // restore snapshot
+ virtual Component & operator=(const Component &);
+
+ // components are never moved
Component(Component &&) = delete;
- virtual Component & operator=(const Component &) = delete;
virtual Component & operator=(Component &&) = delete;
public:
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
diff --git a/src/crepe/manager/ComponentManager.h b/src/crepe/manager/ComponentManager.h
index 19a8e81..94fd94f 100644
--- a/src/crepe/manager/ComponentManager.h
+++ b/src/crepe/manager/ComponentManager.h
@@ -21,13 +21,6 @@ class GameObject;
* This class manages all components. It provides methods to add, delete and get components.
*/
class ComponentManager : public Manager {
- // TODO: This relation should be removed! I (loek) believe that the scene manager should
- // create/destroy components because the GameObject's are stored in concrete Scene classes,
- // which will in turn call GameObject's destructor, which will in turn call
- // ComponentManager::delete_components_by_id or something. This is a pretty major change, so
- // here is a comment and temporary fix instead :tada:
- friend class SceneManager;
-
public:
ComponentManager(Mediator & mediator);
~ComponentManager(); // dbg_trace
@@ -49,12 +42,7 @@ public:
const vec2 & position = {0, 0}, double rotation = 0,
double scale = 1);
-protected:
- /**
- * GameObject is used as an interface to add/remove components, and the game programmer is
- * supposed to use it instead of interfacing with the component manager directly.
- */
- friend class GameObject;
+public:
/**
* \brief Add a component to the ComponentManager
*
@@ -154,6 +142,16 @@ public:
template <typename T>
RefVector<T> get_components_by_tag(const std::string & tag) const;
+ struct SnapshotComponent {
+ by_type<by_id_index<std::vector<std::unique_ptr<Component>>>> components;
+ Component component;
+ };
+ struct Snapshot {
+
+ };
+ Snapshot save();
+ void restore(const Snapshot &);
+
private:
/**
* \brief Get object IDs by predicate function
diff --git a/src/crepe/manager/ReplayManager.h b/src/crepe/manager/ReplayManager.h
index 242eae4..c50196c 100644
--- a/src/crepe/manager/ReplayManager.h
+++ b/src/crepe/manager/ReplayManager.h
@@ -1,6 +1,8 @@
#pragma once
#include "Manager.h"
+#include "ComponentManager.h"
+#include <unordered_map>
namespace crepe {
@@ -18,15 +20,18 @@ protected:
void record_frame();
private:
- bool recording;
- struct Recording {
- recording_t id;
- std::vector<Memento> frames;
- };
+ typedef std::vector<ComponentManager::Snapshot> Recording;
+
+ bool recording = false;
+ recording_t current_recording = -1;
+
+
+ std::unordered_map<recording_t, std::unique_ptr<Recording>> memory;
public:
void record_start();
recording_t record_end();
-
+ void play(recording_t handle);
+ void release(recording_t handle);
};
} // namespace crepe