Skip to content

Commit 4bf1171

Browse files
committed
Fully fixed all the bugs.
1 parent d9a25eb commit 4bf1171

4 files changed

Lines changed: 42 additions & 23 deletions

File tree

core/net_utilities.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ void remove_unordered(std::vector<V> &r_vec, const T &p_val) {
198198
}
199199
}
200200

201-
// Swap the element at position with the last one, then removes it.
201+
// Removes the element without changing order.
202202
template <class V>
203203
void remove_at(std::vector<V> &r_vec, std::size_t p_index) {
204204
if (r_vec.size() <= p_index) {

core/peer_networked_controller.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,7 @@ bool DollController::fetch_next_input(double p_delta) {
14791479
FrameInput guessed_fi = frames_input[closest_frame_index];
14801480
guessed_fi.id = next_input_id;
14811481
set_frame_input(guessed_fi, false);
1482+
SceneSynchronizerDebugger::singleton()->print(INFO, "The input " + next_input_id + " is missing. Copying it from " + std::string(frames_input[closest_frame_index].id));
14821483
return true;
14831484
} else {
14841485
// The input is not set and there is no suitable one.
@@ -1520,7 +1521,7 @@ void DollController::process(double p_delta) {
15201521

15211522
void DollController::on_state_validated(FrameIndex p_frame_index, bool p_detected_desync) {
15221523
notify_frame_checked(last_doll_compared_input);
1523-
notify_frame_processing(current_input_buffer_id);
1524+
clear_previously_generated_client_snapshots();
15241525
}
15251526

15261527
void DollController::notify_frame_checked(FrameIndex p_doll_frame_index) {
@@ -1540,12 +1541,12 @@ void DollController::notify_frame_checked(FrameIndex p_doll_frame_index) {
15401541
}
15411542

15421543
// Remove all the server snapshots which doll frame was already executed.
1543-
while (!server_snapshots.empty() && server_snapshots.front().doll_executed_input <= p_doll_frame_index) {
1544+
while (!server_snapshots.empty() && server_snapshots.front().doll_executed_input < p_doll_frame_index) {
15441545
VecFunc::remove_at(server_snapshots, 0);
15451546
}
15461547

15471548
// Removed all the checked doll frame snapshots.
1548-
while (!client_snapshots.empty() && client_snapshots.front().doll_executed_input <= p_doll_frame_index) {
1549+
while (!client_snapshots.empty() && client_snapshots.front().doll_executed_input < p_doll_frame_index) {
15491550
VecFunc::remove_at(client_snapshots, 0);
15501551
}
15511552
} else {
@@ -1556,14 +1557,13 @@ void DollController::notify_frame_checked(FrameIndex p_doll_frame_index) {
15561557
last_doll_validated_input = p_doll_frame_index;
15571558
}
15581559

1559-
void DollController::notify_frame_processing(FrameIndex p_input_id) {
1560-
if make_likely (p_input_id != FrameIndex::NONE) {
1560+
void DollController::clear_previously_generated_client_snapshots() {
1561+
if make_likely (current_input_buffer_id != FrameIndex::NONE) {
15611562
// Removed all the client snapshots which input is more than the specified one
15621563
// to ensure the function `__pcr__fetch_recovery_info` works properly.
15631564
for (int i = int(client_snapshots.size()) - 1; i >= 0; i--) {
1564-
if (client_snapshots[i].doll_executed_input > p_input_id) {
1565+
if (client_snapshots[i].doll_executed_input > current_input_buffer_id) {
15651566
VecFunc::remove_at(client_snapshots, i);
1566-
i--;
15671567
} else {
15681568
break;
15691569
}
@@ -1594,6 +1594,11 @@ void DollController::on_received_server_snapshot(const Snapshot &p_snapshot) {
15941594
}
15951595

15961596
void DollController::on_snapshot_update_finished(const Snapshot &p_snapshot) {
1597+
#ifdef DEBUG_ENABLED
1598+
// The SceneSync set the correct input, and here it checks it.
1599+
const FrameIndex doll_executed_input = MapFunc::at(p_snapshot.peers_frames_index, peer_controller->get_authority_peer(), FrameIndex::NONE);
1600+
ASSERT_COND(doll_executed_input == current_input_buffer_id);
1601+
#endif
15971602
copy_controlled_objects_snapshot(p_snapshot, client_snapshots, false);
15981603
}
15991604

@@ -1680,7 +1685,9 @@ void DollController::copy_controlled_objects_snapshot(
16801685
FrameIndex DollController::fetch_checkable_snapshot(DollSnapshot *&r_client_snapshot, DollSnapshot *&r_server_snapshot) {
16811686
for (auto client_snap_it = client_snapshots.rbegin(); client_snap_it != client_snapshots.rend(); client_snap_it++) {
16821687
if (client_snap_it->doll_executed_input != FrameIndex::NONE) {
1683-
ASSERT_COND_MSG(client_snap_it->doll_executed_input <= current_input_buffer_id, "All the client snapshots are properly cleared when the `current_input_id` is manipulated. So this function is impossible to trigger. If it does, there is a bug on the `notify_frame_processing`.");
1688+
#ifdef DEBUG_ENABLED
1689+
ASSERT_COND_MSG(client_snap_it->doll_executed_input <= current_input_buffer_id, "All the client snapshots are properly cleared when the `current_input_id` is manipulated. So this function is impossible to trigger. If it does, there is a bug on the `clear_previously_generated_client_snapshots`.");
1690+
#endif
16841691
auto server_snap_it = VecFunc::find(server_snapshots, client_snap_it->doll_executed_input);
16851692
if (server_snap_it != server_snapshots.end()) {
16861693
r_client_snapshot = &(*client_snap_it);
@@ -1732,7 +1739,7 @@ bool DollController::__pcr__fetch_recovery_info(
17321739
last_doll_compared_input = checkable_input;
17331740

17341741
// Now just compare the two snapshots.
1735-
return Snapshot::compare(
1742+
const bool compare = Snapshot::compare(
17361743
*peer_controller->scene_synchronizer,
17371744
server_snapshot->data,
17381745
client_snapshot->data,
@@ -1744,6 +1751,14 @@ bool DollController::__pcr__fetch_recovery_info(
17441751
r_different_node_data
17451752
#endif
17461753
);
1754+
1755+
// TODO remove this.
1756+
if (r_differences_info) {
1757+
for (auto d : *r_differences_info) {
1758+
SceneSynchronizerBase::__print_line(d);
1759+
}
1760+
}
1761+
return compare;
17471762
}
17481763

17491764
void DollController::on_snapshot_applied(
@@ -1813,6 +1828,8 @@ void DollController::apply_snapshot_instant_input_reconciliation(const Snapshot
18131828
for (const DollSnapshot &snapshot : server_snapshots) {
18141829
if (snapshot.doll_executed_input <= last_doll_compared_input) {
18151830
snapshot_to_apply = &snapshot;
1831+
} else {
1832+
break;
18161833
}
18171834
}
18181835

core/peer_networked_controller.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,9 +405,10 @@ struct DollController final : public RemotelyControlledController {
405405
int fetch_optimal_queued_inputs() const;
406406
virtual bool fetch_next_input(double p_delta) override;
407407
virtual void process(double p_delta) override;
408+
408409
void on_state_validated(FrameIndex p_frame_index, bool p_detected_desync);
409410
void notify_frame_checked(FrameIndex p_input_id);
410-
void notify_frame_processing(FrameIndex p_input_id);
411+
void clear_previously_generated_client_snapshots();
411412

412413
void on_received_server_snapshot(const Snapshot &p_snapshot);
413414
void on_snapshot_update_finished(const Snapshot &p_snapshot);

tests/test_doll_simulation.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,10 @@ void test_simulation_reconciliation(float p_frame_confirmation_timespan) {
426426
// Run another 30 frames.
427427
test.do_test(30);
428428

429+
// Ensure it was able to reconcily in exactly 1 frame.
430+
ASSERT_COND(test.peer1_desync_detected.size() == 1);
431+
ASSERT_COND(test.peer2_desync_detected.size() == 1);
432+
429433
// Make sure the reconciliation was successful.
430434
// NOTE: 45 is a margin established basing on the `p_frame_confirmation_timespan`.
431435
const NS::FrameIndex ensure_no_desync_after{ 45 };
@@ -462,7 +466,7 @@ void test_simulation_with_hiccups(TestDollSimulationStorePositions &test) {
462466
}
463467
}
464468

465-
test.do_test(30);
469+
test.do_test(100);
466470

467471
const NS::FrameIndex controller_1_last_player_frame_index = test.peer_1_scene.scene_sync->get_controller_for_peer(test.peer_1_scene.get_peer())->get_current_frame_index();
468472
const NS::FrameIndex controller_2_last_player_frame_index = test.peer_2_scene.scene_sync->get_controller_for_peer(test.peer_2_scene.get_peer())->get_current_frame_index();
@@ -477,8 +481,8 @@ void test_simulation_with_hiccups(TestDollSimulationStorePositions &test) {
477481

478482
// Make sure the last frames are identical.
479483
test.assert_positions(
480-
test.peer1_desync_detected.back(),
481-
test.peer2_desync_detected.back());
484+
test.peer1_desync_detected.back() + 10,
485+
test.peer2_desync_detected.back() + 10);
482486
}
483487

484488
void test_simulation_with_latency() {
@@ -628,17 +632,14 @@ void test_latency() {
628632
}
629633

630634
void test_doll_simulation() {
631-
// TODO enable these tests.
632-
//test_simulation_without_reconciliation(0.0);
633-
//test_simulation_without_reconciliation(1. / 30.);
634-
//test_simulation_reconciliation(0.0);
635-
//test_simulation_reconciliation(1.0 / 10.0);
636-
//test_simulation_with_latency();
635+
test_simulation_without_reconciliation(0.0);
636+
test_simulation_without_reconciliation(1. / 30.);
637+
test_simulation_reconciliation(0.0);
638+
test_simulation_reconciliation(1.0 / 10.0);
639+
test_simulation_with_latency();
637640
test_simulation_with_hiccups();
638641
// TODO test with great latency and lag compensation.
639-
//test_latency();
640-
641-
ASSERT_COND(false);
642+
test_latency();
642643
}
643644

644645
}; //namespace NS_Test

0 commit comments

Comments
 (0)