统一 2D/3D Renderable 继承链与实时数据策略

This commit is contained in:
2026-08-14 18:47:36 +08:00
parent bb64801679
commit cb32f72bc9
43 changed files with 1010 additions and 528 deletions
+33 -13
View File
@@ -12,15 +12,30 @@
namespace renderive::render_3d {
namespace {
static_assert(std::derived_from<Point_Visual, Renderable>);
static_assert(std::derived_from<Point_Visual, ::Renderable_Base>);
TEST(PointState, UsesKernelDoubleStateAtFrameBoundary) {
Point_Visual visual({{{1.0F, 2.0F, 3.0F}, {1, 2, 3, 255}, 7.0F}});
auto visual = Point_Visual::Builder{}.build(
std::vector<Point>{{{1.0F, 2.0F, 3.0F}, {1, 2, 3, 255}, 7.0F}});
ASSERT_TRUE(visual);
const auto initial_observation = visual->observation();
EXPECT_EQ(initial_observation.event,
Renderable_Observer_Event::Data_Updated);
EXPECT_EQ(initial_observation.data_revision, 1U);
EXPECT_EQ(initial_observation.item_count, 1U);
Point_State configured;
configured.visible = false;
configured.style.stroke_width_px = 3.0F;
visual.configure(configured);
visual->set<&Point_State::visible>(configured.visible);
visual->set<&Point_State::style>(configured.style);
EXPECT_EQ(visual->observation().event,
Renderable_Observer_Event::Cache_Updated);
const auto published = detail::Point_State_Access::publish(visual);
const auto published = detail::publish_point(*visual);
EXPECT_EQ(visual->observation().event,
Renderable_Observer_Event::Published);
EXPECT_EQ(published.state, configured);
ASSERT_EQ(published.data->size(), 1U);
EXPECT_EQ(published.data->front().position, (Vec3{1.0F, 2.0F, 3.0F}));
@@ -29,7 +44,8 @@ TEST(PointState, UsesKernelDoubleStateAtFrameBoundary) {
}
TEST(PointState, PublishesImmutableBulkPayloadsThroughDoubleBuffer) {
Point_Visual visual;
auto visual = Point_Visual::Builder{}.build();
ASSERT_TRUE(visual);
constexpr int update_count = 500;
constexpr std::uint64_t initial_data_revision = 1;
std::atomic<bool> done{};
@@ -41,13 +57,13 @@ TEST(PointState, PublishesImmutableBulkPayloadsThroughDoubleBuffer) {
point.position.x = static_cast<float>(value);
point.diameter_px = static_cast<float>(value % 12 + 1);
}
visual.update_points(std::move(points));
visual->update_points(std::move(points));
}
done.store(true, std::memory_order_release);
});
do {
const auto published = detail::Point_State_Access::publish(visual);
const auto published = detail::publish_point(*visual);
if (!published.data->empty()) {
const float expected = published.data->front().position.x;
for (const auto& point : *published.data)
@@ -56,7 +72,7 @@ TEST(PointState, PublishesImmutableBulkPayloadsThroughDoubleBuffer) {
} while (!done.load(std::memory_order_acquire));
writer.join();
const auto published = detail::Point_State_Access::publish(visual);
const auto published = detail::publish_point(*visual);
EXPECT_GT(published.data_revision, 0U);
EXPECT_LE(published.data_revision,
initial_data_revision + update_count);
@@ -65,17 +81,21 @@ TEST(PointState, PublishesImmutableBulkPayloadsThroughDoubleBuffer) {
}
TEST(PointState, RejectsInvalidStateAndPayloadAtTheOwningBoundary) {
Point_Visual visual;
auto visual = Point_Visual::Builder{}.build();
ASSERT_TRUE(visual);
Point_State invalid;
invalid.style.stroke_width_px = -1.0F;
EXPECT_THROW(visual.configure(invalid), std::invalid_argument);
EXPECT_THROW(visual->set<&Point_State::style>(invalid.style),
std::invalid_argument);
EXPECT_THROW(visual.update_points(std::vector<Point>{{{}, {}, 0.0F}}),
EXPECT_THROW(visual->update_points(std::vector<Point>{{{}, {}, 0.0F}}),
std::invalid_argument);
}
TEST(PointFrameControl, UsesDedicatedThreeDimensionalFrameStrategy) {
Point_Visual visual(std::vector<Point>{{{}, {}, 8.0F}});
auto visual = Point_Visual::Builder{}.build(
std::vector<Point>{{{}, {}, 8.0F}});
ASSERT_TRUE(visual);
detail::Scene_State_Buffer scene({{320, 180}, {}});
detail::Input_Collector input;
const auto prepare = [&](detail::Point_Frame_Strategy& strategy) {
@@ -85,7 +105,7 @@ TEST(PointFrameControl, UsesDedicatedThreeDimensionalFrameStrategy) {
auto published_scene = scene.publish_state();
lease->scene = std::move(published_scene.state);
lease->scene_revision = published_scene.revision;
lease->point = detail::Point_State_Access::publish(visual);
lease->point = detail::publish_point(*visual);
lease->input = input.drain();
return true;
};
@@ -109,7 +129,7 @@ TEST(PointFrameControl, UsesDedicatedThreeDimensionalFrameStrategy) {
detail::Point_Frame_Strategy playback(Frame_Mode::Playback, 60.0);
EXPECT_TRUE(prepare(playback));
visual.update_points(std::vector<Point>(2, Point{{}, {}, 8.0F}));
visual->update_points(std::vector<Point>(2, Point{{}, {}, 8.0F}));
EXPECT_TRUE(prepare(playback));
auto playback_status = playback.status();
EXPECT_EQ(playback_status.produced_frame_count, 2U);