aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/manager/ReplayManager.cpp
blob: 090a94e1f77236e861ea5601c9b56de3bda5fbb0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <format>

#include "Manager.h"
#include "ReplayManager.h"

using namespace crepe;
using namespace std;

ReplayManager::ReplayManager(Mediator & mediator) : Manager(mediator) {
	mediator.replay_manager = *this;
}

void ReplayManager::record_start() {
	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->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));
	this->recording = *this->memory.at(handle);
	this->recording->frame = 0;
	this->state = PLAYING;
}

void ReplayManager::release(recording_t handle) {
	if (!this->memory.contains(handle)) return;
	this->memory.erase(handle);
}

void ReplayManager::frame_record() {
	if (this->state != RECORDING)
		throw runtime_error("ReplayManager: frame_step called while not playing");

	ComponentManager & components = this->mediator.component_manager;
	Recording & recording = this->recording;

	recording.frames.push_back(components.save());
	recording.frame++;
}

bool ReplayManager::frame_step() {
	if (this->state != PLAYING)
		throw runtime_error("ReplayManager: frame_step called while not playing");

	ComponentManager & components = this->mediator.component_manager;
	Recording & recording = this->recording;

	ComponentManager::Snapshot & frame = recording.frames.at(recording.frame);

	components.restore(frame);
	recording.frame++;

	if (recording.frame < recording.frames.size()) return false;
	// end of recording
	recording.frame = 0;
	this->state = IDLE;
	this->recording.clear();
	return true;
}

ReplayManager::State ReplayManager::get_state() const { return this->state; }