Skip to content

Commit f59fa77

Browse files
committed
Implemented doll's apply snapshot
1 parent f9b0989 commit f59fa77

3 files changed

Lines changed: 74 additions & 35 deletions

File tree

core/peer_networked_controller.cpp

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,17 @@ void DollController::on_received_server_snapshot(const Snapshot &p_snapshot) {
16091609
return;
16101610
}
16111611

1612+
// This check ensure that the server_snapshots contains just a single FrameIndex::NONE
1613+
// snapshot or a bunch of indexed one.
1614+
if (p_snapshot.input_id == FrameIndex::NONE) {
1615+
// The received snapshot doesn't have a FrameIndex set, it means there is no controller
1616+
// so assume this is the most up-to-date snapshot.
1617+
server_snapshots.clear();
1618+
} else {
1619+
// Make sure to remove all the snapshots with FrameIndex::NONE received before this one.
1620+
VecFunc::remove(server_snapshots, DollSnapshot(FrameIndex::NONE));
1621+
}
1622+
16121623
copy_controlled_objects_snapshot(p_snapshot, p_snapshot.input_id, server_snapshots);
16131624
}
16141625

@@ -1622,7 +1633,7 @@ void DollController::copy_controlled_objects_snapshot(
16221633
std::vector<DollSnapshot> &r_snapshots) {
16231634
const std::vector<ObjectData *> *controlled_objects = peer_controller->scene_synchronizer->get_peer_controlled_objects_data(peer_controller->get_authority_peer());
16241635
if (!controlled_objects || controlled_objects->size() <= 0) {
1625-
// Nothing to store.
1636+
// Nothing to store for this doll.
16261637
return;
16271638
}
16281639

@@ -1691,12 +1702,12 @@ bool DollController::__pcr__fetch_recovery_info(
16911702
// 1. Fetch the server snapshot.
16921703
// The server snapshot can be fetched, normally, using the index.
16931704
std::vector<DollSnapshot>::const_iterator server_snap_it = VecFunc::find(server_snapshots, DollSnapshot(p_checking_frame_index));
1694-
// The server snapshot was not found, this is impossible because we store
1695-
// all the snapshots.
1696-
ENSURE_V_MSG(server_snapshots.end() != server_snap_it, false, "Doll fetch recovery info failed because the snapshot was not found, though this should be impossible to trigger. checking_frame_index: " + p_checking_frame_index);
1697-
1698-
const DollSnapshot *server_snapshot = &*server_snap_it;
1699-
ENSURE_V(server_snapshot, false);
1705+
if (server_snapshots.end() == server_snap_it) {
1706+
// The server snapshot was not found on this doll, that can only happen
1707+
// when this doll is not simulating anything on this client.
1708+
// So, just return true.
1709+
return true;
1710+
}
17001711

17011712
// 2. Now fetch the client snapshot.
17021713
// Since the doll is following a a different timeline, we need to fetch the
@@ -1707,12 +1718,16 @@ bool DollController::__pcr__fetch_recovery_info(
17071718
client_snapshot = &snapshot;
17081719
}
17091720
}
1710-
ENSURE_V_MSG(client_snapshot, false, "Doll fetch recovery info failed because the client snapshot was not found. checking_frame: " + p_checking_frame_index)
1721+
if (!client_snapshot) {
1722+
// The client was not found, most likely there was nothing to store,
1723+
// it can be considered as the two snapshots are different.
1724+
return false;
1725+
}
17111726

17121727
// Now just compare the two snapshots.
17131728
return Snapshot::compare(
17141729
*peer_controller->scene_synchronizer,
1715-
server_snapshot->data,
1730+
server_snap_it->data,
17161731
client_snapshot->data,
17171732
-1,
17181733
r_no_rewind_recover,
@@ -1725,21 +1740,19 @@ bool DollController::__pcr__fetch_recovery_info(
17251740
}
17261741

17271742
void DollController::on_snapshot_applied(const Snapshot &p_snapshot) {
1728-
// Since this doll is executing on a different timeline, we can't apply
1729-
// the received snapshot.
1730-
// 1. Search which input was executed by this doll when this snapshot was executed.
1731-
FrameIndex doll_executed_input;
1732-
{
1733-
const auto client_snap_it = VecFunc::find(client_snapshots, DollSnapshot(p_snapshot.input_id));
1734-
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: " + p_snapshot.input_id);
1743+
// This function can't run on the server.
1744+
ENSURE(peer_controller->scene_synchronizer->is_client());
17351745

1736-
doll_executed_input = client_snap_it->doll_executed_input;
1737-
}
1746+
// At this point it's necessary to mention that due to the fact the doll is
1747+
// processing on a different timeline, we may not have the server snapshot
1748+
// to reconcile the doll with the server right away.
1749+
// For this reason, this function apply the client snapshot, and leaves to
1750+
// Rewinding's process function the task to apply the server snapshot.
1751+
1752+
const auto client_snap_it = VecFunc::find(client_snapshots, DollSnapshot(p_snapshot.input_id));
1753+
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: " + p_snapshot.input_id);
17381754

1739-
// Now it has the executed input so, fetch the snapshot to apply.
1740-
// 2. Fetch the server snapshot.
1741-
const auto server_snap_it = VecFunc::find(server_snapshots, DollSnapshot(doll_executed_input));
1742-
if (server_snap_it ==)
1755+
static_cast<ClientSynchronizer *>(peer_controller->scene_synchronizer->get_synchronizer_internal())->apply_snapshot(p_snapshot, 0, nullptr, true, true, true, true, true);
17431756
}
17441757

17451758
NoNetController::NoNetController(PeerNetworkedController *p_peer_controller) :

scene_synchronizer.cpp

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3679,19 +3679,27 @@ void ClientSynchronizer::update_simulated_objects_list(const std::vector<ObjectN
36793679

36803680
void ClientSynchronizer::apply_snapshot(
36813681
const NS::Snapshot &p_snapshot,
3682-
int p_flag,
3682+
const int p_flag,
36833683
std::vector<std::string> *r_applied_data_info,
3684-
bool p_skip_custom_data) {
3684+
const bool p_skip_custom_data,
3685+
const bool p_skip_simulated_objects_update,
3686+
const bool p_disable_apply_non_doll_controlled_only,
3687+
const bool p_skip_snapshot_applied_event_broadcast,
3688+
const bool p_skip_change_event) {
36853689
NS_PROFILE
36863690

36873691
const std::vector<NS::NameAndVar> *snap_objects_vars = p_snapshot.object_vars.data();
36883692

3689-
scene_synchronizer->change_events_begin(p_flag);
3693+
if (!p_skip_change_event) {
3694+
scene_synchronizer->change_events_begin(p_flag);
3695+
}
36903696
const int this_peer = scene_synchronizer->network_interface->fetch_local_peer_id();
36913697

3692-
update_simulated_objects_list(p_snapshot.simulated_objects);
3698+
if (!p_skip_simulated_objects_update) {
3699+
update_simulated_objects_list(p_snapshot.simulated_objects);
3700+
}
36933701

3694-
for (ObjectNetId net_node_id = { 0 }; net_node_id < ObjectNetId{ uint32_t(p_snapshot.object_vars.size()) }; net_node_id += 1) {
3702+
for (ObjectNetId net_node_id : p_snapshot.simulated_objects) {
36953703
NS::ObjectData *object_data = scene_synchronizer->get_object_data(net_node_id);
36963704

36973705
if (object_data == nullptr) {
@@ -3701,12 +3709,17 @@ void ClientSynchronizer::apply_snapshot(
37013709
continue;
37023710
}
37033711

3704-
if (object_data->realtime_sync_enabled_on_client == false) {
3705-
// This is not a simulated object.
3706-
continue;
3712+
#ifdef DEBUG_ENABLED
3713+
if (!p_skip_simulated_objects_update) {
3714+
// This can't trigger because the `update_simulated_objects_list` make sure to set this.
3715+
ASSERT_COND(object_data->realtime_sync_enabled_on_client);
37073716
}
3717+
#endif
37083718

3709-
if (object_data->get_controlled_by_peer() > 0 && object_data->get_controlled_by_peer() != this_peer) {
3719+
if (
3720+
!p_disable_apply_non_doll_controlled_only &&
3721+
object_data->get_controlled_by_peer() > 0 &&
3722+
object_data->get_controlled_by_peer() != this_peer) {
37103723
// This object is controlled by a doll, which simulation / reconcilation
37113724
// is mostly doll-controller driven.
37123725
// The dolls are notified at the end of this loop, when the event
@@ -3775,9 +3788,13 @@ void ClientSynchronizer::apply_snapshot(
37753788
scene_synchronizer->synchronizer_manager->snapshot_set_custom_data(p_snapshot.custom_data);
37763789
}
37773790

3778-
scene_synchronizer->event_snapshot_applied.broadcast(p_snapshot);
3791+
if (!p_skip_snapshot_applied_event_broadcast) {
3792+
scene_synchronizer->event_snapshot_applied.broadcast(p_snapshot);
3793+
}
37793794

3780-
scene_synchronizer->change_events_flush();
3795+
if (!p_skip_change_event) {
3796+
scene_synchronizer->change_events_flush();
3797+
}
37813798
}
37823799

37833800
NS_NAMESPACE_END

scene_synchronizer.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ class SceneSynchronizerBase {
284284
return *synchronizer_manager;
285285
}
286286

287+
const Synchronizer *get_synchronizer_internal() const { return synchronizer; }
288+
Synchronizer *get_synchronizer_internal() { return synchronizer; }
289+
287290
void set_frames_per_seconds(int p_fps);
288291
int get_frames_per_seconds() const;
289292

@@ -838,11 +841,17 @@ class ClientSynchronizer final : public Synchronizer {
838841

839842
void update_client_snapshot(Snapshot &p_snapshot);
840843
void update_simulated_objects_list(const std::vector<ObjectNetId> &p_simulated_objects);
844+
845+
public:
841846
void apply_snapshot(
842847
const Snapshot &p_snapshot,
843-
int p_flag,
848+
const int p_flag,
844849
std::vector<std::string> *r_applied_data_info,
845-
bool p_skip_custom_data = false);
850+
const bool p_skip_custom_data = false,
851+
const bool p_skip_simulated_objects_update = false,
852+
const bool p_disable_apply_non_doll_controlled_only = false,
853+
const bool p_skip_snapshot_applied_event_broadcast = false,
854+
const bool p_skip_change_event = false);
846855
};
847856

848857
/// This is used to make sure we can safely convert any `BaseType` defined by

0 commit comments

Comments
 (0)