Skip to content
This repository was archived by the owner on Mar 29, 2025. It is now read-only.

Commit 839f72e

Browse files
committed
Adds test to verify that a process can be registered and unregistered outside the SycRegistration phase.
1 parent ae0e7e9 commit 839f72e

File tree

1 file changed

+169
-0
lines changed

1 file changed

+169
-0
lines changed

tests/test_scene_synchronizer.cpp

+169
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,174 @@ void test_sync_mode_reset() {
12041204
NS_ASSERT_COND(NS::MathFunc::is_equal_approx(controlled_obj_1_peer_1->position.data.f32, frame_count * delta * one_meter * 2.0f, delta * 2.0f));
12051205
}
12061206

1207+
class TestProcessingSceneObject : public NS::LocalSceneObject {
1208+
public:
1209+
// NOTE, this property isn't sync.
1210+
TestProcessingSceneObject *deactivate_processing_on_object = nullptr;
1211+
ProcessPhase deactivate_processing_phase;
1212+
1213+
NS::ObjectLocalId local_id = NS::ObjectLocalId::NONE;
1214+
NS::VarData var_1;
1215+
NS::VarData var_2;
1216+
1217+
NS::PHandler processing_handler = NS::NullPHandler;
1218+
1219+
virtual void on_scene_entry() override {
1220+
get_scene()->scene_sync->register_app_object(get_scene()->scene_sync->to_handle(this));
1221+
}
1222+
1223+
virtual void setup_synchronizer(NS::LocalSceneSynchronizer &p_scene_sync, NS::ObjectLocalId p_id) override {
1224+
local_id = p_id;
1225+
1226+
p_scene_sync.register_variable(
1227+
p_id,
1228+
"var_1",
1229+
[](NS::SynchronizerManager &p_synchronizer_manager, NS::ObjectHandle p_handle, const std::string &p_var_name, const NS::VarData &p_value) {
1230+
static_cast<TestProcessingSceneObject *>(NS::LocalSceneSynchronizer::from_handle(p_handle))->var_1.copy(p_value);
1231+
},
1232+
[](const NS::SynchronizerManager &p_synchronizer_manager, NS::ObjectHandle p_handle, const std::string &p_var_name, NS::VarData &r_value) {
1233+
r_value.copy(static_cast<TestProcessingSceneObject *>(NS::LocalSceneSynchronizer::from_handle(p_handle))->var_1);
1234+
});
1235+
1236+
p_scene_sync.register_variable(
1237+
p_id,
1238+
"var_2",
1239+
[](NS::SynchronizerManager &p_synchronizer_manager, NS::ObjectHandle p_handle, const std::string &p_var_name, const NS::VarData &p_value) {
1240+
static_cast<TestProcessingSceneObject *>(NS::LocalSceneSynchronizer::from_handle(p_handle))->var_2.copy(p_value);
1241+
},
1242+
[](const NS::SynchronizerManager &p_synchronizer_manager, NS::ObjectHandle p_handle, const std::string &p_var_name, NS::VarData &r_value) {
1243+
r_value.copy(static_cast<TestProcessingSceneObject *>(NS::LocalSceneSynchronizer::from_handle(p_handle))->var_2);
1244+
});
1245+
}
1246+
1247+
void activate_processing(ProcessPhase Phase) {
1248+
if (processing_handler == NS::NullPHandler) {
1249+
processing_handler = get_scene()->scene_sync->register_process(local_id, Phase, [this](float p_delta) {
1250+
this->sync_process(p_delta);
1251+
});
1252+
}
1253+
}
1254+
1255+
void deactivate_processing(ProcessPhase Phase) {
1256+
if (processing_handler != NS::NullPHandler) {
1257+
get_scene()->scene_sync->unregister_process(local_id, Phase, processing_handler);
1258+
processing_handler = NS::NullPHandler;
1259+
}
1260+
}
1261+
1262+
virtual void on_scene_exit() override {
1263+
get_scene()->scene_sync->on_app_object_removed(get_scene()->scene_sync->to_handle(this));
1264+
}
1265+
1266+
void sync_process(float p_delta) {
1267+
if (deactivate_processing_on_object) {
1268+
deactivate_processing_on_object->deactivate_processing(deactivate_processing_phase);
1269+
deactivate_processing_on_object = nullptr;
1270+
}
1271+
var_1.data.f32 += var_2.data.f32 * p_delta;
1272+
}
1273+
};
1274+
1275+
void test_registering_and_deregistering_process() {
1276+
NS::LocalScene server_scene;
1277+
server_scene.start_as_no_net();
1278+
1279+
NS::LocalScene peer_1_scene;
1280+
peer_1_scene.start_as_no_net();
1281+
1282+
// Add the scene sync
1283+
server_scene.scene_sync =
1284+
server_scene.add_object<NS::LocalSceneSynchronizer>("sync", server_scene.get_peer());
1285+
1286+
peer_1_scene.scene_sync =
1287+
peer_1_scene.add_object<NS::LocalSceneSynchronizer>("sync", server_scene.get_peer());
1288+
1289+
server_scene.scene_sync->set_frame_confirmation_timespan(0.0);
1290+
1291+
TestProcessingSceneObject *processing_object_1_server = server_scene.add_object<TestProcessingSceneObject>("obj_1", server_scene.get_peer());
1292+
TestProcessingSceneObject *processing_object_1_peer = peer_1_scene.add_object<TestProcessingSceneObject>("obj_1", server_scene.get_peer());
1293+
1294+
TestProcessingSceneObject *processing_object_2_server = server_scene.add_object<TestProcessingSceneObject>("obj_2", server_scene.get_peer());
1295+
TestProcessingSceneObject *processing_object_2_peer = peer_1_scene.add_object<TestProcessingSceneObject>("obj_2", server_scene.get_peer());
1296+
1297+
processing_object_1_server->var_1.data.f32 = 0.0;
1298+
processing_object_1_server->var_2.data.f32 = 2.0;
1299+
processing_object_1_peer->var_1.data.f32 = 0.0;
1300+
processing_object_1_peer->var_2.data.f32 = 2.0;
1301+
1302+
processing_object_2_server->var_1.data.f32 = -10.0;
1303+
processing_object_2_server->var_2.data.f32 = 4.0;
1304+
processing_object_2_peer->var_1.data.f32 = -10.0;
1305+
processing_object_2_peer->var_2.data.f32 = 4.0;
1306+
1307+
// Process the scene 10 times and ensure the processing was never executed.
1308+
for (int i = 0; i < 10; i++) {
1309+
server_scene.process(delta);
1310+
peer_1_scene.process(delta);
1311+
1312+
NS_ASSERT_COND(processing_object_1_server->var_1.data.f32 == 0.0f);
1313+
NS_ASSERT_COND(processing_object_1_peer->var_1.data.f32 == 0.0f);
1314+
NS_ASSERT_COND(processing_object_2_server->var_1.data.f32 == -10.0f);
1315+
NS_ASSERT_COND(processing_object_2_peer->var_1.data.f32 == -10.0f);
1316+
}
1317+
1318+
processing_object_1_server->activate_processing(PROCESS_PHASE_PROCESS);
1319+
processing_object_1_peer->activate_processing(PROCESS_PHASE_PROCESS);
1320+
processing_object_2_server->activate_processing(PROCESS_PHASE_LATE); // EXECUTES AFTER OBJECT 1
1321+
processing_object_2_peer->activate_processing(PROCESS_PHASE_LATE); // EXECUTES AFTER OBJECT 1
1322+
1323+
// Now process another 10 times and ensure the processing was correctly executed
1324+
float expected_object_1 = 0.0;
1325+
float expected_object_2 = -10.0;
1326+
for (int i = 0; i < 10; i++) {
1327+
server_scene.process(delta);
1328+
peer_1_scene.process(delta);
1329+
1330+
expected_object_1 += delta * 2.0;
1331+
expected_object_2 += delta * 4.0;
1332+
1333+
NS_ASSERT_COND(processing_object_1_server->var_1.data.f32 == expected_object_1);
1334+
NS_ASSERT_COND(processing_object_1_peer->var_1.data.f32 == expected_object_1);
1335+
NS_ASSERT_COND(processing_object_2_server->var_1.data.f32 == expected_object_2);
1336+
NS_ASSERT_COND(processing_object_2_peer->var_1.data.f32 == expected_object_2);
1337+
}
1338+
1339+
// Now, deactivate the execution for the object 2 from object 1 (that
1340+
// executes sooner thanks to the different processing phase), to ensure
1341+
// it doesn't cause any crash and the deactivation is executed only the following frame.
1342+
processing_object_1_server->deactivate_processing_on_object = processing_object_2_server;
1343+
processing_object_1_peer->deactivate_processing_on_object = processing_object_2_peer;
1344+
processing_object_1_server->deactivate_processing_phase = PROCESS_PHASE_LATE;
1345+
processing_object_1_peer->deactivate_processing_phase = PROCESS_PHASE_LATE;
1346+
1347+
// Process one time. NOTE Here the object 2 processing is deactivated.
1348+
server_scene.process(delta);
1349+
peer_1_scene.process(delta);
1350+
1351+
expected_object_1 += delta * 2.0;
1352+
expected_object_2 += delta * 4.0;
1353+
1354+
// However ensure that in the above frame the processing happened anyway.
1355+
NS_ASSERT_COND(processing_object_1_server->var_1.data.f32 == expected_object_1);
1356+
NS_ASSERT_COND(processing_object_1_peer->var_1.data.f32 == expected_object_1);
1357+
NS_ASSERT_COND(processing_object_2_server->var_1.data.f32 == expected_object_2);
1358+
NS_ASSERT_COND(processing_object_2_peer->var_1.data.f32 == expected_object_2);
1359+
1360+
// Now process another 10 times and ensure the processing keep going only on the object 1.
1361+
for (int i = 0; i < 10; i++) {
1362+
server_scene.process(delta);
1363+
peer_1_scene.process(delta);
1364+
1365+
expected_object_1 += delta * 2.0;
1366+
//expected_object_2 += delta * 4.0;
1367+
1368+
NS_ASSERT_COND(processing_object_1_server->var_1.data.f32 == expected_object_1);
1369+
NS_ASSERT_COND(processing_object_1_peer->var_1.data.f32 == expected_object_1);
1370+
NS_ASSERT_COND(processing_object_2_server->var_1.data.f32 == expected_object_2);
1371+
NS_ASSERT_COND(processing_object_2_peer->var_1.data.f32 == expected_object_2);
1372+
}
1373+
}
1374+
12071375
void test_scene_synchronizer() {
12081376
test_ids();
12091377
test_client_and_server_initialization();
@@ -1218,5 +1386,6 @@ void test_scene_synchronizer() {
12181386
test_streaming();
12191387
test_no_network();
12201388
test_sync_mode_reset();
1389+
test_registering_and_deregistering_process();
12211390
}
12221391
}; //namespace NS_Test

0 commit comments

Comments
 (0)