@@ -1295,7 +1295,7 @@ DollController::DollController(PeerNetworkedController *p_peer_controller) :
12951295 peer_controller->scene_synchronizer ->event_state_validated .bind (std::bind (&DollController::on_state_validated, this , std::placeholders::_1, std::placeholders::_2));
12961296
12971297 event_handler_snapshot_applied =
1298- peer_controller->scene_synchronizer ->event_snapshot_applied .bind (std::bind (&DollController::on_snapshot_applied, this , std::placeholders::_1));
1298+ peer_controller->scene_synchronizer ->event_snapshot_applied .bind (std::bind (&DollController::on_snapshot_applied, this , std::placeholders::_1, std::placeholders::_2 ));
12991299}
13001300
13011301DollController::~DollController () {
@@ -1395,16 +1395,6 @@ void DollController::on_rewind_frame_begin(FrameIndex p_frame_index, int p_index
13951395 return ;
13961396}
13971397
1398- int DollController::count_queued_inputs () const {
1399- int queued_inputs_count = 0 ;
1400- for (const FrameInput &frame : frames_input) {
1401- if (frame.id > current_input_buffer_id) {
1402- queued_inputs_count += 1 ;
1403- }
1404- }
1405- return queued_inputs_count;
1406- }
1407-
14081398int DollController::fetch_optimal_queued_inputs () const {
14091399 // The optimal virtual delay is a number that refers to the amount of queued
14101400 // frames the DollController should try to have on each frame to avoid
@@ -1485,7 +1475,7 @@ void DollController::process(double p_delta) {
14851475 auto server_snap_it = VecFunc::find (server_snapshots, DollSnapshot (frame_index - 1 ));
14861476 if (server_snap_it != server_snapshots.end ()) {
14871477 // The snapshot was found, so apply it.
1488- static_cast <ClientSynchronizer *>(peer_controller->scene_synchronizer ->get_synchronizer_internal ())->apply_snapshot (server_snap_it->data , 0 , nullptr , true , true , true , true , true );
1478+ static_cast <ClientSynchronizer *>(peer_controller->scene_synchronizer ->get_synchronizer_internal ())->apply_snapshot (server_snap_it->data , 0 , 0 , nullptr , true , true , true , true , true );
14891479 }
14901480 }
14911481 }
@@ -1650,8 +1640,6 @@ void DollController::copy_controlled_objects_snapshot(
16501640bool DollController::__pcr__fetch_recovery_info (
16511641 FrameIndex p_checking_frame_index,
16521642 Snapshot *r_no_rewind_recover,
1653- // The frames to process afterward.
1654- int p_predicted_frames,
16551643 std::vector<std::string> *r_differences_info
16561644#ifdef DEBUG_ENABLED
16571645 ,
@@ -1692,17 +1680,65 @@ bool DollController::__pcr__fetch_recovery_info(
16921680 );
16931681}
16941682
1695- void DollController::on_snapshot_applied (const Snapshot &p_global_server_snapshot) {
1696- // This function can't run on the server.
1697- ENSURE (peer_controller->scene_synchronizer ->is_client ());
1683+ void DollController::on_snapshot_applied (
1684+ const Snapshot &p_global_server_snapshot,
1685+ const int p_frame_count_to_rewind) {
1686+ // The `DollController` is never created on the server, and the below
1687+ // assertion is always satisfied.
1688+ ASSERT_COND (peer_controller->scene_synchronizer ->is_client ());
1689+
1690+ // This function handles the reconciliation mechanism.
1691+ // The reconciliation is implemented in this function because this is the
1692+ // best moment to manipulate the processing (to consume or build the input
1693+ // queue) and avoid to make it noticeable.
1694+
1695+ // 1. Fetch the optimal queued inputs (how many inputs should be queued based
1696+ // on the current connection).
1697+ const int optimal_queued_inputs = fetch_optimal_queued_inputs ();
1698+
1699+ // 2. Get the input count.
1700+ const int input_count = frames_input.size ();
1701+
1702+ // 3. Fetch the best input to start processing.
1703+ // TODO consider to scale this dynamically to slowly catchup with the server, as too drastic change may result in a less stable simulation.
1704+ const int optimal_input_count = p_frame_count_to_rewind + optimal_queued_inputs;
1705+
1706+ // The lag compensation algorithm offsets the available
1707+ // inputs so that the `input_count` equals to `optimal_queued_inputs`
1708+ // at the end of the reconcilation (rewinding) operation.
1709+
1710+ if (input_count < optimal_input_count) {
1711+ // It has less inputs than the optimal input count defined.
1712+ // In this case the offset, mention above, is going to be positive.
1713+ // It will offset the reconciliation, by the delta difference
1714+ // `optimal_input_count - input_count`, with frames where the object are
1715+ // not procesed.
1716+ const int missing_inputs = optimal_input_count - input_count;
1717+ } else {
1718+ // It has more inputs than the optimal input count defined.
1719+ // In this case the offset is negative, meaning it throws away all the
1720+ // extra inputs to recatch the server.
1721+ const int extra_inputs = input_count - optimal_input_count;
1722+
1723+ current_input_buffer_id += extra_inputs;
1724+
1725+ I need to find a way to define the `current_input_buffer_id` based on the extra inputs and the available frames_input;
1726+ }
16981727
1699- const FrameIndex doll_frame_index = MapFunc::at (p_global_server_snapshot.peers_frames_index , peer_controller->get_authority_peer (), FrameIndex::NONE);
1728+ const FrameIndex doll_frame_index =
1729+ MapFunc::at (
1730+ p_global_server_snapshot.peers_frames_index ,
1731+ peer_controller->get_authority_peer (),
1732+ FrameIndex::NONE);
17001733
17011734 if (doll_frame_index == FrameIndex::NONE) {
17021735 // On the server, the doll was not executed so just apply the server snapshot.
1703- const auto server_snap_it = VecFunc::find (server_snapshots, DollSnapshot (FrameIndex::NONE));
1736+ const auto server_snap_it =
1737+ VecFunc::find (
1738+ server_snapshots,
1739+ DollSnapshot (FrameIndex::NONE));
17041740 ENSURE_MSG (server_snap_it != server_snapshots.end (), " The doll was unable to set the NO-CONTROLLER snapshot because it was unable to find it in the server_snapshots array." );
1705- static_cast <ClientSynchronizer *>(peer_controller->scene_synchronizer ->get_synchronizer_internal ())->apply_snapshot (server_snap_it->data , 0 , nullptr , true , true , true , true , true );
1741+ static_cast <ClientSynchronizer *>(peer_controller->scene_synchronizer ->get_synchronizer_internal ())->apply_snapshot (server_snap_it->data , 0 , 0 , nullptr , true , true , true , true , true );
17061742
17071743 } else {
17081744 // At this point it's necessary to mention that due to the fact the doll is
@@ -1714,7 +1750,7 @@ void DollController::on_snapshot_applied(const Snapshot &p_global_server_snapsho
17141750 const auto client_snap_it = VecFunc::find (client_snapshots, DollSnapshot (doll_frame_index));
17151751 ENSURE_MSG (client_snap_it != client_snapshots.end (), " The doll was unable to set the snapshot because it was unable to find the client snapshot with ID: " + doll_frame_index);
17161752
1717- static_cast <ClientSynchronizer *>(peer_controller->scene_synchronizer ->get_synchronizer_internal ())->apply_snapshot (client_snap_it->data , 0 , nullptr , true , true , true , true , true );
1753+ static_cast <ClientSynchronizer *>(peer_controller->scene_synchronizer ->get_synchronizer_internal ())->apply_snapshot (client_snap_it->data , 0 , 0 , nullptr , true , true , true , true , true );
17181754 }
17191755}
17201756
0 commit comments