From 359ad8db97305856f4cfdade1cd1dada78a7a635 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Wed, 11 Dec 2024 21:04:30 +0100 Subject: more replay system WIP --- src/crepe/manager/ComponentManager.cpp | 26 ++++++++++++++++++++++++++ src/crepe/manager/ComponentManager.h | 9 +++++++-- src/crepe/manager/Mediator.h | 2 ++ src/crepe/manager/ReplayManager.cpp | 25 ++++++++++++++----------- src/crepe/manager/ReplayManager.h | 24 +++++++++++++++++------- 5 files changed, 66 insertions(+), 20 deletions(-) (limited to 'src/crepe/manager') 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 ComponentManager::get_objects_by_tag(const string & tag) c return this->get_objects_by_predicate( [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 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; }; struct Snapshot { - + // TODO: some kind of hash code that ensures components exist in all the same places as + // this snapshot + std::vector 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 resource_manager; OptionalRef timer; OptionalRef replay_manager; + OptionalRef 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 #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(); + 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 + #include "Manager.h" #include "ComponentManager.h" -#include +#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 Recording; - - bool recording = false; - recording_t current_recording = -1; - + struct Recording { + size_t frame = 0; + std::vector frames; + }; + + enum State { + IDLE, + RECORDING, + PLAYING, + }; + + State state = IDLE; + OptionalRef recording; + recording_t id = -1; std::unordered_map> memory; public: -- cgit v1.2.3