#include "editor/EditorSimulationPreview.h" #include "zeroerr/assert.h" #include "zeroerr/unittest.h" using namespace eve::editor; namespace { class FakeSimulation final : public IEditorSimulationBackend { public: std::unique_ptr cloneForPreview() const override { return std::make_unique(*this); } EditorResult step(std::uint64_t tick, double fixedDelta) override { if (tick <= tick_) return eve::editing::failed(EditorStatus::Rejected, RuleId("fake.tick"), "Ticks must increase"); tick_ = tick; position_ += fixedDelta * 3.0; return eve::editing::applied(); } EditorResult> capture() const override { SimulationObjectSample sample; sample.object = "body-1"; sample.positionX = position_; return eve::editing::applied>({sample}); } double position() const { return position_; } private: std::uint64_t tick_ = 0; double position_ = 0.0; }; } // namespace TEST_CASE("editor.simulation.preview_pauses_steps_and_bakes_without_mutating_source") { FakeSimulation source; SimulationPreviewController controller; CHECK_EQ(static_cast(controller.update(source).code()), static_cast(EditorStatus::NoOp)); REQUIRE(controller.setFixedDelta(0.5).ok()); auto frame = controller.singleStep(source); REQUIRE(frame.ok()); CHECK_EQ(frame.value().objects[0].positionX, 1.5); frame = controller.singleStep(source); REQUIRE(frame.ok()); CHECK_EQ(frame.value().objects[0].positionX, 3.0); CHECK_EQ(source.position(), 0.0); auto baked = controller.bake(source, 42, 3, 10); CHECK_EQ(static_cast(baked.status), static_cast(EditorStatus::Applied)); CHECK_EQ(baked.sourceRevision, 42U); CHECK_EQ(baked.frames.size(), 4U); CHECK_EQ(baked.frames.back().objects[0].positionX, 4.5); CHECK_EQ(source.position(), 0.0); CHECK_EQ(static_cast(controller.bake(source, 42, 11, 10).status), static_cast(EditorStatus::Rejected)); }