Skip to content

Commit 150ecab

Browse files
committed
Adding integration test for the new doll processing.
1 parent 5052c39 commit 150ecab

3 files changed

Lines changed: 125 additions & 45 deletions

File tree

core/var_data.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ VarData::VarData() {
1010
memset(&data, 0, sizeof(data));
1111
}
1212

13-
VarData::VarData(double x, double y, double z, double w) {
13+
VarData::VarData(double x, double y, double z, double w) :
14+
VarData() {
1415
data.vec.x = x;
1516
data.vec.y = y;
1617
data.vec.z = z;

tests/test_doll_simulation.cpp

Lines changed: 117 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,13 @@ namespace NS_Test {
2020

2121
const double delta = 1.0 / 60.0;
2222

23-
class TDSLocalNetworkedController : public NS::LocalSceneObject {
23+
class TDSControlledObject : public NS::LocalSceneObject {
2424
public:
2525
NS::ObjectLocalId local_id = NS::ObjectLocalId::NONE;
2626

27-
TDSLocalNetworkedController() = default;
27+
TDSControlledObject() = default;
2828

2929
virtual void on_scene_entry() override {
30-
// Setup the NetworkInterface.
31-
set_xi(0);
32-
3330
get_scene()->scene_sync->register_app_object(get_scene()->scene_sync->to_handle(this));
3431
}
3532

@@ -43,40 +40,49 @@ class TDSLocalNetworkedController : public NS::LocalSceneObject {
4340
p_scene_sync.setup_controller(
4441
p_id,
4542
authoritative_peer_id,
46-
[this](double p_delta, DataBuffer &r_buffer) -> void { collect_inputs(p_delta, r_buffer); },
47-
[this](DataBuffer &p_buffer) -> int { return count_input_size(p_buffer); },
48-
[this](DataBuffer &p_buffer_A, DataBuffer &p_buffer_b) -> bool { return are_inputs_different(p_buffer_A, p_buffer_b); },
49-
[this](double p_delta, DataBuffer &p_buffer) -> void { controller_process(p_delta, p_buffer); });
43+
std::bind(&TDSControlledObject::collect_inputs, this, std::placeholders::_1, std::placeholders::_2),
44+
std::bind(&TDSControlledObject::count_input_size, this, std::placeholders::_1),
45+
std::bind(&TDSControlledObject::are_inputs_different, this, std::placeholders::_1, std::placeholders::_2),
46+
std::bind(&TDSControlledObject::controller_process, this, std::placeholders::_1, std::placeholders::_2));
5047

51-
p_scene_sync.register_variable(p_id, "xi");
48+
p_scene_sync.register_variable(p_id, "xy");
5249
}
5350

54-
void set_xi(int p_xi) {
51+
void set_xy(float x, float y) {
5552
NS::VarData vd;
56-
vd.data.i32 = 1;
53+
vd.data.vec.x = x;
54+
vd.data.vec.y = y;
5755
vd.type = 0;
5856
NS::MapFunc::assign(variables, std::string("xi"), std::move(vd));
5957
}
6058

61-
int get_xi() const {
59+
NS::VarData get_xy() const {
6260
const NS::VarData *vd = NS::MapFunc::get_or_null(variables, std::string("xi"));
6361
if (vd) {
64-
return vd->data.i32;
62+
return NS::VarData::make_copy(*vd);
6563
} else {
66-
return 0;
64+
return NS::VarData(0, 0);
6765
}
6866
}
6967

7068
// ------------------------------------------------- NetController interface
69+
bool previous_input = true;
7170
void collect_inputs(double p_delta, DataBuffer &r_buffer) {
72-
r_buffer.add(true);
71+
// Write true or false alternating each other.
72+
r_buffer.add(!previous_input);
73+
previous_input = !previous_input;
7374
}
7475

7576
void controller_process(double p_delta, DataBuffer &p_buffer) {
76-
bool advance_xi;
77-
p_buffer.read(advance_xi);
78-
if (advance_xi) {
79-
set_xi(get_xi() + 1);
77+
bool advance_or_turn;
78+
p_buffer.read(advance_or_turn);
79+
NS::VarData current = get_xy();
80+
if (advance_or_turn) {
81+
// Advance
82+
set_xy(current.data.vec.x + 1, current.data.vec.y);
83+
} else {
84+
// Turn
85+
set_xy(current.data.vec.x, current.data.vec.y + 1);
8086
}
8187
}
8288

@@ -95,18 +101,20 @@ class TDSLocalNetworkedController : public NS::LocalSceneObject {
95101
/// This class is made in a way which allows to be overriden to test the sync
96102
/// still works under bad network conditions.
97103
struct TestDollSimulationBase {
104+
bool assert_if_desync = false;
105+
98106
NS::LocalNetworkProps network_properties;
99107

100108
NS::LocalScene server_scene;
101109
NS::LocalScene peer_1_scene;
102110
NS::LocalScene peer_2_scene;
103-
TDSLocalNetworkedController *controller_1_serv = nullptr;
104-
TDSLocalNetworkedController *controller_1_peer1 = nullptr;
105-
TDSLocalNetworkedController *controller_1_peer2 = nullptr;
111+
TDSControlledObject *controlled_1_serv = nullptr;
112+
TDSControlledObject *controlled_1_peer1 = nullptr;
113+
TDSControlledObject *controlled_1_peer2 = nullptr;
106114

107-
TDSLocalNetworkedController *controller_2_serv = nullptr;
108-
TDSLocalNetworkedController *controller_2_peer1 = nullptr;
109-
TDSLocalNetworkedController *controller_2_peer2 = nullptr;
115+
TDSControlledObject *controlled_2_serv = nullptr;
116+
TDSControlledObject *controlled_2_peer1 = nullptr;
117+
TDSControlledObject *controlled_2_peer2 = nullptr;
110118

111119
private:
112120
virtual void on_scenes_initialized() {}
@@ -142,13 +150,13 @@ struct TestDollSimulationBase {
142150
peer_2_scene.add_object<NS::LocalSceneSynchronizer>("sync", server_scene.get_peer());
143151

144152
// Then compose the scene: 2 controllers.
145-
controller_1_serv = server_scene.add_object<TDSLocalNetworkedController>("controller_1", peer_1_scene.get_peer());
146-
controller_1_peer1 = peer_1_scene.add_object<TDSLocalNetworkedController>("controller_1", peer_1_scene.get_peer());
147-
controller_1_peer2 = peer_2_scene.add_object<TDSLocalNetworkedController>("controller_1", peer_1_scene.get_peer());
153+
controlled_1_serv = server_scene.add_object<TDSControlledObject>("controller_1", peer_1_scene.get_peer());
154+
controlled_1_peer1 = peer_1_scene.add_object<TDSControlledObject>("controller_1", peer_1_scene.get_peer());
155+
controlled_1_peer2 = peer_2_scene.add_object<TDSControlledObject>("controller_1", peer_1_scene.get_peer());
148156

149-
controller_2_serv = server_scene.add_object<TDSLocalNetworkedController>("controller_2", peer_2_scene.get_peer());
150-
controller_2_peer1 = peer_1_scene.add_object<TDSLocalNetworkedController>("controller_2", peer_2_scene.get_peer());
151-
controller_2_peer2 = peer_2_scene.add_object<TDSLocalNetworkedController>("controller_2", peer_2_scene.get_peer());
157+
controlled_2_serv = server_scene.add_object<TDSControlledObject>("controller_2", peer_2_scene.get_peer());
158+
controlled_2_peer1 = peer_1_scene.add_object<TDSControlledObject>("controller_2", peer_2_scene.get_peer());
159+
controlled_2_peer2 = peer_2_scene.add_object<TDSControlledObject>("controller_2", peer_2_scene.get_peer());
152160

153161
server_scene.scene_sync->register_process(server_scene.scene_sync->find_local_id(), PROCESS_PHASE_LATE, [=](double p_delta) -> void {
154162
on_server_process(p_delta);
@@ -160,16 +168,25 @@ struct TestDollSimulationBase {
160168
on_client_2_process(p_delta);
161169
});
162170

163-
on_scenes_initialized();
171+
if (assert_if_desync) {
172+
peer_1_scene.scene_sync->event_state_validated.bind([](NS::FrameIndex fi, bool p_desync_detected) -> void {
173+
ASSERT_COND(!p_desync_detected);
174+
});
175+
peer_2_scene.scene_sync->event_state_validated.bind([](NS::FrameIndex fi, bool p_desync_detected) -> void {
176+
ASSERT_COND(!p_desync_detected);
177+
});
178+
}
164179

165180
// Set the position of each object:
166-
controller_1_serv->set_xi(100);
167-
controller_1_peer1->set_xi(100);
168-
controller_1_peer2->set_xi(100);
181+
controlled_1_serv->set_xy(100, 0);
182+
controlled_1_peer1->set_xy(100, 0);
183+
controlled_1_peer2->set_xy(100, 0);
184+
185+
controlled_2_serv->set_xy(0, 0);
186+
controlled_2_peer1->set_xy(0, 0);
187+
controlled_2_peer2->set_xy(0, 0);
169188

170-
controller_2_serv->set_xi(0);
171-
controller_2_peer1->set_xi(0);
172-
controller_2_peer2->set_xi(0);
189+
on_scenes_initialized();
173190
}
174191

175192
double rand_range(double M, double N) {
@@ -197,6 +214,62 @@ struct TestDollSimulationBase {
197214
}
198215
};
199216

217+
struct TestDollSimulationWithoutReconciliation : public TestDollSimulationBase {
218+
virtual void on_scenes_initialized() override {
219+
// Notify instantly
220+
server_scene.scene_sync->set_frame_confirmation_timespan(0.0);
221+
222+
// Ensure the controllers are at their initial location as defined by the doll simulation class.
223+
ASSERT_COND(NS::LocalSceneSynchronizer::var_data_compare(controlled_1_serv->get_xy(), NS::VarData(100, 0)));
224+
ASSERT_COND(NS::LocalSceneSynchronizer::var_data_compare(controlled_1_peer1->get_xy(), NS::VarData(100, 0)));
225+
ASSERT_COND(NS::LocalSceneSynchronizer::var_data_compare(controlled_1_peer2->get_xy(), NS::VarData(100, 0)));
226+
227+
ASSERT_COND(NS::LocalSceneSynchronizer::var_data_compare(controlled_2_serv->get_xy(), NS::VarData(0, 0)));
228+
ASSERT_COND(NS::LocalSceneSynchronizer::var_data_compare(controlled_2_peer2->get_xy(), NS::VarData(0, 0)));
229+
ASSERT_COND(NS::LocalSceneSynchronizer::var_data_compare(controlled_2_peer1->get_xy(), NS::VarData(0, 0)));
230+
}
231+
232+
std::vector<NS::VarData> controlled_1_player_position;
233+
std::vector<NS::VarData> controlled_2_player_position;
234+
235+
virtual void on_scenes_processed(double p_delta) override {
236+
controlled_1_player_position.push_back(controlled_1_peer1->get_xy());
237+
controlled_2_player_position.push_back(controlled_2_peer2->get_xy());
238+
239+
const NS::FrameIndex controller_1_player_frame_index = peer_1_scene.scene_sync->get_controller_for_peer(peer_1_scene.get_peer())->get_current_frame_index();
240+
const NS::FrameIndex controller_2_player_frame_index = peer_2_scene.scene_sync->get_controller_for_peer(peer_2_scene.get_peer())->get_current_frame_index();
241+
242+
const NS::FrameIndex controller_2_doll_frame_index = peer_1_scene.scene_sync->get_controller_for_peer(peer_2_scene.get_peer())->get_current_frame_index();
243+
const NS::FrameIndex controller_1_doll_frame_index = peer_2_scene.scene_sync->get_controller_for_peer(peer_1_scene.get_peer())->get_current_frame_index();
244+
245+
if (controller_1_doll_frame_index != NS::FrameIndex::NONE) {
246+
// Make sure the players are always ahead the dolls.
247+
ASSERT_COND(controller_1_player_frame_index > controller_2_doll_frame_index);
248+
ASSERT_COND(controller_2_player_frame_index > controller_1_doll_frame_index);
249+
250+
// Verify the doll are at the exact location they were on the player.
251+
const NS::VarData doll_1_position = controlled_1_peer2->get_xy();
252+
const NS::VarData doll_2_position = controlled_2_peer1->get_xy();
253+
ASSERT_COND(NS::LocalSceneSynchronizer::var_data_compare(controlled_1_player_position[controller_1_doll_frame_index.id], doll_1_position));
254+
ASSERT_COND(NS::LocalSceneSynchronizer::var_data_compare(controlled_2_player_position[controller_2_doll_frame_index.id], doll_2_position));
255+
}
256+
257+
int a = 0;
258+
}
259+
};
260+
261+
void test_simulation_without_reconciliation() {
262+
TestDollSimulationWithoutReconciliation test;
263+
// This test is not triggering any desynchronization.
264+
test.assert_if_desync = true;
265+
test.init_test();
266+
267+
test.do_test(100);
268+
269+
// Asserted.
270+
ASSERT_COND(false);
271+
}
272+
200273
void test_latency() {
201274
TestDollSimulationBase test;
202275
test.init_test();
@@ -239,6 +312,11 @@ void test_latency() {
239312
}
240313

241314
void test_doll_simulation() {
315+
test_simulation_without_reconciliation();
316+
// TODO test with latency.
317+
// TODO test with long confirmation time.
318+
// TODO test with reconciliation.
319+
// TODO test lag compensation.
242320
test_latency();
243321
}
244322

tests/tests.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ void NS_Test::test_all() {
1111
NS::LocalSceneSynchronizer::install_local_scene_sync();
1212

1313
// TODO test DataBuffer.
14-
test_data_buffer();
15-
test_processor();
16-
test_local_network();
17-
test_scene_synchronizer();
18-
test_simulation();
14+
// TODO enable these again.
15+
//test_data_buffer();
16+
//test_processor();
17+
//test_local_network();
18+
//test_scene_synchronizer();
19+
//test_simulation();
1920
test_doll_simulation();
2021

2122
NS::LocalSceneSynchronizer::uninstall_local_scene_sync();

0 commit comments

Comments
 (0)