Skip to content

Commit 4bfc9b4

Browse files
committed
Finalized code comments.
1 parent 76766b2 commit 4bfc9b4

1 file changed

Lines changed: 51 additions & 15 deletions

File tree

core/peer_networked_controller.cpp

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,11 +1539,21 @@ void DollController::notify_frame_checked(FrameIndex p_doll_frame_index) {
15391539
}
15401540

15411541
// Remove all the server snapshots which doll frame was already executed.
1542+
// NOTE: This logic is removing all the snapshots older than the specified
1543+
// frame index while is not removing the specified frame index.
1544+
// It's quite important to keep that snapshot to ensure the function
1545+
// `apply_snapshot_instant_input_reconciliation` can work properly.
1546+
// It needs the snapshot the doll is at, to safely apply the reconciliation.
15421547
while (!server_snapshots.empty() && server_snapshots.front().doll_executed_input < p_doll_frame_index) {
15431548
VecFunc::remove_at(server_snapshots, 0);
15441549
}
15451550

15461551
// Removed all the checked doll frame snapshots.
1552+
// NOTE: This logic is removing all the snapshots older than the specified
1553+
// frame index while is not removing the specified frame index.
1554+
// It's quite important to keep that snapshot to ensure the function
1555+
// `apply_snapshot_instant_input_reconciliation` can work properly.
1556+
// It needs the snapshot the doll is at, to safely apply the reconciliation.
15471557
while (!client_snapshots.empty() && client_snapshots.front().doll_executed_input < p_doll_frame_index) {
15481558
VecFunc::remove_at(client_snapshots, 0);
15491559
}
@@ -1727,7 +1737,6 @@ bool DollController::__pcr__fetch_recovery_info(
17271737
DollSnapshot *client_snapshot;
17281738
DollSnapshot *server_snapshot;
17291739

1730-
// This is valid until we reset it again.
17311740
const FrameIndex checkable_input = fetch_checkable_snapshot(client_snapshot, server_snapshot);
17321741
if (checkable_input == FrameIndex::NONE) {
17331742
// Nothing to check.
@@ -1763,7 +1772,17 @@ void DollController::on_snapshot_applied(
17631772
ASSERT_COND(p_frame_count_to_rewind >= 0);
17641773
#endif
17651774

1775+
// This function is executed when the SceneSynchronizer apply the server
1776+
// snapshot to reconcile the PlayerController.
1777+
// The doll, which timeline is detached from the main SceneSync (which follows the PlayerController) timeline,
1778+
// is still processed together with the SceneSync so it uses this event to
1779+
// Apply the doll server snapshots and compensate the doll input.
1780+
// NOTE: The input compensation is the act of:
1781+
// - Delaying the input processing when the input buffer is small (with the goal of growing the buffer)
1782+
// - Discarding part of the input buffer, if the buffer grown too much, to remain up-to-dated with the server.
1783+
17661784
if make_unlikely (!server_snapshots.empty() && server_snapshots.back().doll_executed_input == FrameIndex::NONE) {
1785+
// This controller is not simulating on the server. This function handles this case.
17671786
apply_snapshot_no_input_reconciliation(p_global_server_snapshot);
17681787
}
17691788

@@ -1809,13 +1828,21 @@ void DollController::apply_snapshot_instant_input_reconciliation(const Snapshot
18091828
// on the current connection).
18101829
const int optimal_queued_inputs = fetch_optimal_queued_inputs();
18111830

1831+
// 2. Then, find the ideal input to restore. Notice that this logic is used
1832+
// mainly to alter the input buffering size:
1833+
// If the input buffer `frames_input` is too big it discards the superflous inputs.
1834+
// If the input buffer is too small adds some fake inputs to delay the execution.
18121835
if make_likely (frames_input.back().id.id >= std::uint32_t(optimal_queued_inputs)) {
18131836
last_doll_compared_input = frames_input.back().id - optimal_queued_inputs;
18141837
} else {
18151838
last_doll_compared_input = FrameIndex{ 0 };
18161839
}
18171840

1818-
// Search the snapshot to apply.
1841+
// 3. Once the ideal input to restore is found, it's necessary to find the
1842+
// nearest server snapshot to apply.
1843+
// Notice that this logic is build so to prefer building a bigger input buffer
1844+
// than needed, while keeping the scene consistent, rather than breaking
1845+
// the synchronization.
18191846
const DollSnapshot *snapshot_to_apply = nullptr;
18201847
for (const DollSnapshot &snapshot : server_snapshots) {
18211848
if (snapshot.doll_executed_input <= last_doll_compared_input) {
@@ -1825,6 +1852,7 @@ void DollController::apply_snapshot_instant_input_reconciliation(const Snapshot
18251852
}
18261853
}
18271854

1855+
// 4. Just apply the snapshot.
18281856
if (snapshot_to_apply) {
18291857
static_cast<ClientSynchronizer *>(peer_controller->scene_synchronizer->get_synchronizer_internal())->apply_snapshot(snapshot_to_apply->data, 0, 0, nullptr, true, true, true, true, true);
18301858
// Bring everything back to this point.
@@ -1834,10 +1862,10 @@ void DollController::apply_snapshot_instant_input_reconciliation(const Snapshot
18341862
}
18351863

18361864
void DollController::apply_snapshot_rewinding_input_reconciliation(const Snapshot &p_global_server_snapshot, const int p_frame_count_to_rewind) {
1837-
// This function apply the snapshot and handles the reconciliation mechanism.
1838-
// over the rewinding.
1865+
// This function applies the snapshot and handles the reconciliation mechanism
1866+
// during the rewinding process.
18391867
// The input reconciliation performed during the rewinding is the best because
1840-
// allows to manipulate the timeline without causing too many rubberbanding.
1868+
// the timeline manipulations are much less visible.
18411869

18421870
// This function assume the "frame count to rewind" is never 0.
18431871
ASSERT_COND(p_frame_count_to_rewind > 0);
@@ -1848,7 +1876,7 @@ void DollController::apply_snapshot_rewinding_input_reconciliation(const Snapsho
18481876

18491877
const int input_count = frames_input.size();
18501878
const DollSnapshot *server_snapshot = nullptr;
1851-
FrameIndex new_last_doll_compared_input;
1879+
FrameIndex new_last_doll_compared_input = FrameIndex::NONE;
18521880
if make_likely (input_count > 0) {
18531881
// 2. Fetch the best input to start processing.
18541882
const int optimal_input_count = p_frame_count_to_rewind + optimal_queued_inputs;
@@ -1857,9 +1885,7 @@ void DollController::apply_snapshot_rewinding_input_reconciliation(const Snapsho
18571885
// inputs so that the `input_count` equals to `optimal_queued_inputs`
18581886
// at the end of the reconcilation (rewinding) operation.
18591887

1860-
// 3. Fetch the best FrameInput to reset.
1861-
// Doesn't matter if we have or not the frame input. If not, the doll will
1862-
// just wait idle.
1888+
// 3. Fetch the ideal frame to reset.
18631889
if make_likely (frames_input.back().id.id >= std::uint32_t(optimal_input_count)) {
18641890
new_last_doll_compared_input = frames_input.back().id - optimal_input_count;
18651891
} else {
@@ -1900,9 +1926,13 @@ void DollController::apply_snapshot_rewinding_input_reconciliation(const Snapsho
19001926
}
19011927

19021928
if make_unlikely (input_count == 0 || new_last_doll_compared_input == FrameIndex::NONE) {
1903-
// There are no inputs and in this case this function has to avoidhawk:
1904-
// - Advance on the timeline while rewinding (so it needs to set the timeline back).
1905-
// - Try to compensate so to give the inputs enough time to arrive.
1929+
// There are no inputs or there were no server snapshots to apply during
1930+
// the rewinding phase, so it's preferable to wait more inputs and snapshots
1931+
// so to safely apply the reconciliation without introducing any desynchronizations.
1932+
//
1933+
// The follow logic make sure that the rewinding is about to happen
1934+
// doesn't alter this doll timeline: At the end of the rewinding this
1935+
// doll will be exactly as is right now.
19061936
const FrameIndex frames_to_travel = { std::uint32_t(p_frame_count_to_rewind + optimal_queued_inputs) };
19071937
if make_likely (current_input_buffer_id > frames_to_travel) {
19081938
last_doll_compared_input = current_input_buffer_id - frames_to_travel;
@@ -1913,12 +1943,18 @@ void DollController::apply_snapshot_rewinding_input_reconciliation(const Snapsho
19131943
last_doll_compared_input = new_last_doll_compared_input;
19141944
}
19151945

1916-
// 5. Fetch frame index to start processing.
1917-
queued_frame_index_to_process = last_doll_compared_input + 1;
1946+
// 5. Now it's time to prepare the doll for the next rewinding that is about to:
1947+
// - Reconcile the client
1948+
// - Resize the input buffer.
19181949
current_input_buffer_id = last_doll_compared_input;
1950+
queued_frame_index_to_process = last_doll_compared_input + 1;
19191951

19201952
if make_unlikely (server_snapshot) {
1921-
// 6. Apply the server snapshot.
1953+
// 6. Apply the server snapshot found during the point `4`.
1954+
// That logic detected that this controller has the server snapshot
1955+
// for the input we have to reset.
1956+
// In this case, it's mandatory to apply that, to ensure the scene
1957+
// reconciliation.
19221958
static_cast<ClientSynchronizer *>(peer_controller->scene_synchronizer->get_synchronizer_internal())->apply_snapshot(server_snapshots.back().data, 0, 0, nullptr, true, true, true, true, true);
19231959
} else if make_likely (!client_snapshots.empty()) {
19241960
// 7. Get the closest available snapshot, and apply it, no need to be

0 commit comments

Comments
 (0)