Files
Renderive/render_2D/tests/render_2D_Frame_Pipeline_Tests.cpp
T
2026-08-18 11:09:48 +08:00

103 lines
3.8 KiB
C++

#include "render_2D/scene/Render_Scene_2D.h"
#include <renderive/renderable/Renderable_Build.hpp>
#include <gtest/gtest.h>
#include <memory>
namespace renderive {
namespace {
std::unique_ptr<Render_Scene_2D> make_scene(
Render_Scene_2D::State state = {}) {
auto strategy =
std::make_shared<Low_Latency_Render_Scene_2D_Strategy>();
return Render_Scene_2D::Builder(std::move(strategy))
.configure([&](Render_Scene_2D::Properties& properties) {
properties = state;
})
.build().value();
}
TEST(RenderScene2DFramePipeline, BuilderOwnsConstructionAndState) {
Render_Scene_2D::State state;
state.viewport = {96, 54};
state.background = Color{8, 16, 24, 255};
auto scene = make_scene(state);
ASSERT_TRUE(scene);
EXPECT_EQ(scene->root_renderable()->object_name(), "root");
}
TEST(RenderScene2DFramePipeline, SceneBuilderOwnsRenderableGroupAndObjectNames) {
auto builder = Render_Scene_2D::Builder(
std::make_shared<Manual_Render_Scene_2D_Strategy>());
auto child = detail::make_renderable_group(false, "child");
builder.add_renderable(child);
auto built_scene = builder.build();
ASSERT_TRUE(built_scene);
ASSERT_TRUE(*built_scene);
EXPECT_EQ(child->object_name(), "child");
EXPECT_EQ((*built_scene)->observer().renderable_count, 2U);
}
TEST(RenderScene2DFramePipeline, SceneBuilderRejectsMissingDependencyEndpoint) {
auto builder = Render_Scene_2D::Builder(
std::make_shared<Manual_Render_Scene_2D_Strategy>());
auto external = detail::make_renderable_group(false, "external");
auto child = detail::make_renderable_group(false, "child");
detail::Renderable_Build_Access::add_dependency_parent(
*child, external);
builder.add_renderable(child);
auto built_scene = builder.build();
ASSERT_FALSE(built_scene);
EXPECT_EQ(built_scene.error(),
Scene_Build_Result::dependency_endpoint_missing);
}
TEST(RenderScene2DFramePipeline, SceneBuilderRejectsDependencyCycle) {
auto builder = Render_Scene_2D::Builder(
std::make_shared<Manual_Render_Scene_2D_Strategy>());
auto first = detail::make_renderable_group(false, "first");
auto second = detail::make_renderable_group(false, "second");
detail::Renderable_Build_Access::add_dependency_parent(*first, second);
detail::Renderable_Build_Access::add_dependency_parent(*second, first);
builder.add_renderable(first);
builder.add_renderable(second);
auto built_scene = builder.build();
ASSERT_FALSE(built_scene);
EXPECT_EQ(built_scene.error(), Scene_Build_Result::dependency_cycle);
}
TEST(RenderScene2DFramePipeline, SceneValidityDoesNotGateStrategyProgress) {
Render_Scene_2D::State state;
state.viewport = {80, 45};
auto scene = make_scene(state);
scene->publish_frame_state();
EXPECT_EQ(scene->observer().state, state);
EXPECT_EQ(scene->render_frame().value(), Plot_Render_Status::view_inactive);
scene->activate_view();
EXPECT_EQ(scene->render_frame().value(), Plot_Render_Status::rendered);
EXPECT_EQ(scene->render_frame().value(), Plot_Render_Status::rendered);
EXPECT_EQ(scene->wait_for_render(), Scene_Render_Result::none);
}
TEST(RenderScene2DFramePipeline, ObserverReadsPublishedDoubleBufferedState) {
Render_Scene_2D::State state;
state.viewport = {32, 24};
auto scene = make_scene(state);
scene->activate_view();
ASSERT_EQ(scene->render_frame().value(), Plot_Render_Status::rendered);
ASSERT_EQ(scene->wait_for_render(), Scene_Render_Result::none);
const auto observation = scene->observer();
EXPECT_EQ(observation.state, state);
EXPECT_EQ(observation.renderable_count, 1U);
EXPECT_TRUE(observation.view_active);
EXPECT_GT(observation.frequency_hz, 0.0);
}
} // namespace
} // namespace renderive