work on paused replays

This commit is contained in:
Roman Trapeznikov 2024-01-08 17:51:52 +03:00
parent 13ad00029c
commit e3ef47dfc0
No known key found for this signature in database
GPG Key ID: 7F4F4115DE048582
4 changed files with 24 additions and 15 deletions

View File

@ -1579,7 +1579,7 @@ static auto PyRewindReplay(PyObject* self, PyObject* args) -> PyObject* {
throw Exception(
"Attempting to rewind a replay not in replay session context.");
}
session->RestoreState();
session->RestoreState(session->base_time() - 2'000);
Py_RETURN_NONE;
BA_PYTHON_CATCH;
}

View File

@ -96,6 +96,12 @@ class ClientSession : public Session {
target_base_time_millisecs_ = base_time_millisecs_;
}
protected:
void SetBaseTime(millisecs_t time) {
base_time_millisecs_ = time;
ResetTargetBaseTime();
}
private:
void ClearSessionObjs();
void AddCommand(const std::vector<uint8_t>& command);

View File

@ -18,7 +18,7 @@ auto ClientSessionReplay::GetActualTimeAdvanceMillisecs(
double base_advance_millisecs) -> double {
auto* appmode = SceneV1AppMode::GetActiveOrFatal();
if (appmode->is_replay_paused()) {
return 0.0;
return 0.001;
}
return base_advance_millisecs * pow(2.0f, appmode->replay_speed_exponent());
}
@ -139,6 +139,7 @@ void ClientSessionReplay::FetchMessages() {
SessionStream out(nullptr, false);
DumpFullState(&out);
current_state_.base_time_ = base_time();
current_state_.correction_messages_.clear();
GetCorrectionMessages(false, &current_state_.correction_messages_);
@ -281,28 +282,28 @@ void ClientSessionReplay::OnReset(bool rewind) {
void ClientSessionReplay::SaveState() { states_.push_back(current_state_); }
void ClientSessionReplay::RestoreState() {
ScreenMessage("restoring state " + std::to_string(states_.size()));
const int N = 500;
void ClientSessionReplay::RestoreState(millisecs_t to_base_time) {
ScreenMessage("was: " + std::to_string(base_time()) + "ms");
ScreenMessage("want: " + std::to_string(to_base_time) + "ms");
if (states_.size() <= N) {
states_.clear();
Reset(true);
return;
}
for (int i = 0; i < N; ++i) {
while (!states_.empty() && states_.back().base_time_ > to_base_time) {
states_.pop_back();
}
current_state_ = states_.back();
RestoreFromCurrentState();
if (states_.empty()) {
Reset(true);
} else {
current_state_ = states_.back();
RestoreFromCurrentState();
}
}
void ClientSessionReplay::RestoreFromCurrentState() {
// what to do with messages_fetch_num_? is it used somewhere at all?
Reset(true);
fseek(file_, current_state_.file_position_, SEEK_SET);
SetBaseTime(current_state_.base_time_);
HandleSessionMessage(current_state_.message_);
for (const auto& msg : current_state_.correction_messages_) {
HandleSessionMessage(msg);

View File

@ -29,7 +29,7 @@ class ClientSessionReplay : public ClientSession,
void Error(const std::string& description) override;
void FetchMessages() override;
void SaveState();
void RestoreState();
void RestoreState(millisecs_t to_base_time);
private:
struct IntermediateState {
@ -39,6 +39,8 @@ class ClientSessionReplay : public ClientSession,
// A position in replay file where we should continue from.
long file_position_;
millisecs_t base_time_;
};
void RestoreFromCurrentState();