// SPDX-License-Identifier: MPL-2.0 #include "sequa/3d/scene.hpp" #include using namespace sequa::three_d; namespace { Transform at(float x) { Transform t; t.position = {x, 0, 0}; return t; } } // namespace TEST_CASE("SceneState : creation, deplacement, destruction") { SceneState scene; REQUIRE_FALSE(scene.apply({1, {CreateObject{1, at(0), {}}, CreateObject{2, at(5), {}}}})); REQUIRE_FALSE(scene.apply({2, {SetTransform{1, at(3)}, DestroyObject{2}}})); CHECK(scene.world_version() == 2); REQUIRE(scene.objects().size() == 1); CHECK(scene.objects().at(1).transform == at(3)); } TEST_CASE("SceneState : version non croissante refusee") { SceneState scene; REQUIRE_FALSE(scene.apply({5, {}})); const auto error = scene.apply({5, {}}); REQUIRE(error.has_value()); CHECK(error->code == Error::Code::invalid_argument); CHECK(scene.apply({4, {}}).has_value()); } TEST_CASE("SceneState : un delta invalide ne modifie rien (tout ou rien)") { SceneState scene; REQUIRE_FALSE(scene.apply({1, {CreateObject{1, at(0), {}}}})); // Le déplacement de 1 est valide, mais 99 est inconnu : rien ne doit être appliqué. CHECK(scene.apply({2, {SetTransform{1, at(7)}, SetTransform{99, at(1)}}}).has_value()); CHECK(scene.world_version() == 1); CHECK(scene.objects().at(1).transform == at(0)); CHECK(scene.apply({2, {CreateObject{1, at(0), {}}}}).has_value()); // doublon CHECK(scene.apply({2, {CreateObject{invalid_object, at(0), {}}}}).has_value()); CHECK(scene.world_version() == 1); } TEST_CASE("SceneState : le snapshot reconstruit une scene identique") { SceneState scene; Visual sphere; sphere.primitive = Primitive::sphere; sphere.semantic_class = 3; REQUIRE_FALSE(scene.apply({1, {CreateObject{7, at(1), {}}, CreateObject{3, at(2), sphere}}})); REQUIRE_FALSE(scene.apply({4, {SetCamera{Camera{at(-10), 60, 0.1f, 500}}}})); const SceneDelta snapshot = scene.snapshot(); CHECK(snapshot.world_version == 4); REQUIRE(snapshot.commands.size() == 3); CHECK(std::get(snapshot.commands[0]).id == 3); // ordre par id croissant CHECK(std::holds_alternative(snapshot.commands[2])); SceneState copy; REQUIRE_FALSE(copy.apply(snapshot)); CHECK(copy.objects() == scene.objects()); CHECK(copy.camera() == scene.camera()); }