aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/manager
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe/manager')
-rw-r--r--src/crepe/manager/ComponentManager.cpp26
-rw-r--r--src/crepe/manager/ComponentManager.h9
-rw-r--r--src/crepe/manager/Mediator.h2
-rw-r--r--src/crepe/manager/ReplayManager.cpp25
-rw-r--r--src/crepe/manager/ReplayManager.h24
5 files changed, 66 insertions, 20 deletions
diff --git a/src/crepe/manager/ComponentManager.cpp b/src/crepe/manager/ComponentManager.cpp
index 24ba0d7..5f5c050 100644
--- a/src/crepe/manager/ComponentManager.cpp
+++ b/src/crepe/manager/ComponentManager.cpp
@@ -72,3 +72,29 @@ set<game_object_id_t> ComponentManager::get_objects_by_tag(const string & tag) c
return this->get_objects_by_predicate<Metadata>(
[tag](const Metadata & data) { return data.tag == tag; });
}
+
+ComponentManager::Snapshot ComponentManager::save() {
+ Snapshot snapshot{};
+ for (const auto & [type, by_id_index] : this->components) {
+ for (game_object_id_t id = 0; id < by_id_index.size(); id++) {
+ const auto & components = by_id_index[id];
+ for (size_t index = 0; index < components.size(); index++) {
+ const Component & component = *components[index];
+ snapshot.components.push_back(SnapshotComponent{
+ .type = type,
+ .id = id,
+ .index = index,
+ .component = component.save(),
+ });
+ }
+ }
+ }
+ return snapshot;
+}
+
+void ComponentManager::restore(const Snapshot & snapshot) {
+ for (const SnapshotComponent & info : snapshot.components) {
+ this->components[info.type][info.id][info.index]->restore(*info.component);
+ }
+}
+
diff --git a/src/crepe/manager/ComponentManager.h b/src/crepe/manager/ComponentManager.h
index dd7c154..457a196 100644
--- a/src/crepe/manager/ComponentManager.h
+++ b/src/crepe/manager/ComponentManager.h
@@ -143,10 +143,15 @@ public:
RefVector<T> get_components_by_tag(const std::string & tag) const;
struct SnapshotComponent {
- Component component;
+ std::type_index type;
+ game_object_id_t id;
+ size_t index;
+ std::unique_ptr<Component> component;
};
struct Snapshot {
-
+ // TODO: some kind of hash code that ensures components exist in all the same places as
+ // this snapshot
+ std::vector<SnapshotComponent> components;
};
Snapshot save();
void restore(const Snapshot &);
diff --git a/src/crepe/manager/Mediator.h b/src/crepe/manager/Mediator.h
index eef4432..f5864e7 100644
--- a/src/crepe/manager/Mediator.h
+++ b/src/crepe/manager/Mediator.h
@@ -14,6 +14,7 @@ class ResourceManager;
class SDLContext;
class LoopTimer;
class ReplayManager;
+class LoopManager;
/**
* Struct to pass references to classes that would otherwise need to be singletons down to
@@ -36,6 +37,7 @@ struct Mediator {
OptionalRef<ResourceManager> resource_manager;
OptionalRef<LoopTimer> timer;
OptionalRef<ReplayManager> replay_manager;
+ OptionalRef<LoopManager> loop_manager;
};
} // namespace crepe
diff --git a/src/crepe/manager/ReplayManager.cpp b/src/crepe/manager/ReplayManager.cpp
index 82c2275..81ff114 100644
--- a/src/crepe/manager/ReplayManager.cpp
+++ b/src/crepe/manager/ReplayManager.cpp
@@ -1,4 +1,4 @@
-#include "../util/Log.h"
+#include <format>
#include "ReplayManager.h"
#include "Manager.h"
@@ -11,26 +11,29 @@ ReplayManager::ReplayManager(Mediator & mediator) : Manager(mediator) {
}
void ReplayManager::record_start() {
- if (this->recording) this->release(this->current_recording);
- this->current_recording++;
- this->recording = true;
+ if (this->state == RECORDING) this->release(this->id);
+ this->id++;
+ this->memory[this->id] = make_unique<Recording>();
+ this->recording = *this->memory.at(this->id);
+ this->state = RECORDING;
}
recording_t ReplayManager::record_end() {
- this->recording = false;
- return this->current_recording;
+ this->state = IDLE;
+ return this->id;
}
void ReplayManager::play(recording_t handle) {
if (!this->memory.contains(handle))
throw out_of_range(format("ReplayManager: no recording for handle {}", handle));
- Recording & recording = *this->memory.at(handle);
-
- dbg_log("TODO: magic");
+ this->recording = *this->memory.at(handle);
+ this->recording->frame = 0;
+ this->state = PLAYING;
}
void ReplayManager::release(recording_t handle) {
- dbg_log("release");
-
+ if (!this->memory.contains(handle))
+ return;
+ this->memory.erase(handle);
}
diff --git a/src/crepe/manager/ReplayManager.h b/src/crepe/manager/ReplayManager.h
index c50196c..672d093 100644
--- a/src/crepe/manager/ReplayManager.h
+++ b/src/crepe/manager/ReplayManager.h
@@ -1,13 +1,14 @@
#pragma once
+#include <unordered_map>
+
#include "Manager.h"
#include "ComponentManager.h"
-#include <unordered_map>
+#include "util/OptionalRef.h"
namespace crepe {
class ReplaySystem;
-class Memento;
typedef size_t recording_t;
@@ -20,11 +21,20 @@ protected:
void record_frame();
private:
- typedef std::vector<ComponentManager::Snapshot> Recording;
-
- bool recording = false;
- recording_t current_recording = -1;
-
+ struct Recording {
+ size_t frame = 0;
+ std::vector<ComponentManager::Snapshot> frames;
+ };
+
+ enum State {
+ IDLE,
+ RECORDING,
+ PLAYING,
+ };
+
+ State state = IDLE;
+ OptionalRef<Recording> recording;
+ recording_t id = -1;
std::unordered_map<recording_t, std::unique_ptr<Recording>> memory;
public: