Skip to content

Commit 5052c39

Browse files
committed
Implemented the Doll's rewind apply-snapshot.
1 parent f59fa77 commit 5052c39

2 files changed

Lines changed: 36 additions & 9 deletions

File tree

core/net_utilities.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,23 +199,24 @@ void remove_unordered(std::vector<V> &r_vec, const T &p_val) {
199199
}
200200

201201
// Swap the element at position with the last one, then removes it.
202-
template <class V, typename T>
202+
template <class V>
203203
void remove_at(std::vector<V> &r_vec, std::size_t p_index) {
204-
if (r_vec.size() >= p_index) {
204+
if (r_vec.size() <= p_index) {
205205
return;
206206
}
207207

208-
remove(r_vec, r_vec.begin() + p_index);
208+
r_vec.erase(r_vec.begin() + p_index);
209209
}
210210

211211
// Swap the element at position with the last one, then removes it.
212-
template <class V, typename T>
212+
template <class V>
213213
void remove_at_unordered(std::vector<V> &r_vec, std::size_t p_index) {
214-
if (r_vec.size() >= p_index) {
214+
if (r_vec.size() <= p_index) {
215215
return;
216216
}
217217

218-
remove_unordered(r_vec, r_vec.begin() + p_index);
218+
std::iter_swap(r_vec.begin() + p_index, r_vec.rbegin());
219+
r_vec.pop_back();
219220
}
220221
} //namespace VecFunc
221222

core/peer_networked_controller.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ void RemotelyControlledController::process(double p_delta) {
686686

687687
if (unlikely(current_input_buffer_id == FrameIndex::NONE)) {
688688
// Skip this until the first input arrive.
689-
SceneSynchronizerDebugger::singleton()->print(INFO, "Server skips this frame as the current_input_buffer_id == UINT32_MAX", "CONTROLLER-" + std::to_string(peer_controller->authority_peer));
689+
SceneSynchronizerDebugger::singleton()->print(INFO, "Server skips this frame as the current_input_buffer_id == FrameIndex::NONE", "CONTROLLER-" + std::to_string(peer_controller->authority_peer));
690690
return;
691691
}
692692

@@ -1356,7 +1356,7 @@ DollController::DollController(PeerNetworkedController *p_peer_controller) :
13561356
event_handler_state_validated =
13571357
peer_controller->scene_synchronizer->event_state_validated.bind(std::bind(&DollController::on_state_validated, this, std::placeholders::_1, std::placeholders::_2));
13581358

1359-
event_handler_state_validated =
1359+
event_handler_snapshot_applied =
13601360
peer_controller->scene_synchronizer->event_snapshot_applied.bind(std::bind(&DollController::on_snapshot_applied, this, std::placeholders::_1));
13611361
}
13621362

@@ -1562,6 +1562,24 @@ bool DollController::fetch_next_input(double p_delta) {
15621562
}
15631563

15641564
void DollController::process(double p_delta) {
1565+
if (queued_instant_to_process >= 0 && queued_instant_to_process < int(frames_input.size())) {
1566+
// Rewinding in progress.
1567+
// On the doll the rewind's processing takes care to apply the server
1568+
// snapshot if it's found.
1569+
// This operation is done here, because the doll process on a different
1570+
// timeline than the one processed by the client.
1571+
const FrameIndex frame_index = frames_input[queued_instant_to_process].id;
1572+
// 1. Skil the first frame as there is nomthing before it.
1573+
if (frame_index > FrameIndex{ 0 }) {
1574+
// 2. Try fetching the previous server snapshot.
1575+
auto server_snap_it = VecFunc::find(server_snapshots, DollSnapshot(frame_index - 1));
1576+
if (server_snap_it != server_snapshots.end()) {
1577+
// The snapshot was found, so apply it.
1578+
static_cast<ClientSynchronizer *>(peer_controller->scene_synchronizer->get_synchronizer_internal())->apply_snapshot(server_snap_it->data, 0, nullptr, true, true, true, true, true);
1579+
}
1580+
}
1581+
}
1582+
15651583
notify_frame_checked(peer_controller->scene_synchronizer->client_get_last_checked_frame_index());
15661584

15671585
const bool is_new_input = fetch_next_input(p_delta);
@@ -1592,14 +1610,22 @@ void DollController::notify_frame_checked(FrameIndex p_frame_index) {
15921610
}
15931611

15941612
// Removes all the inputs older than the known one (included).
1595-
while (frames_input.empty() == false && frames_input.front().id <= p_frame_index) {
1613+
while (!frames_input.empty() && frames_input.front().id <= p_frame_index) {
15961614
if (frames_input.front().id == p_frame_index) {
15971615
// Pause the streaming if the last frame is empty.
15981616
streaming_paused = (frames_input.front().buffer_size_bit - METADATA_SIZE) <= 0;
15991617
}
16001618
frames_input.pop_front();
16011619
}
16021620

1621+
while (!server_snapshots.empty() && server_snapshots.front().data.input_id <= p_frame_index) {
1622+
VecFunc::remove_at(server_snapshots, 0);
1623+
}
1624+
1625+
while (!client_snapshots.empty() && client_snapshots.front().doll_executed_input <= p_frame_index) {
1626+
VecFunc::remove_at(client_snapshots, 0);
1627+
}
1628+
16031629
last_checked_input = p_frame_index;
16041630
}
16051631

0 commit comments

Comments
 (0)