修改成异步的接口

This commit is contained in:
2026-08-13 08:45:18 +08:00
parent 6d2cf825ae
commit b964dcdcd9
23 changed files with 553 additions and 227 deletions
@@ -95,57 +95,50 @@ private:
};
TEST(dynamic_renderable_lifecycle_test,
attach_during_render_is_non_blocking_and_visible_on_the_next_frame) {
attach_during_render_is_queued_until_the_current_frame_finishes) {
Scene2D_Context<> scene;
auto gate = std::make_shared<Gate>();
auto current = std::make_shared<Blocking_Renderable>(scene, gate);
auto attached = std::make_shared<Counting_Renderable>(scene);
scene.attach_renderable(current);
scene.attach_renderable(current).wait();
scene.render();
gate->wait_until_arrived();
std::atomic<bool> attach_finished{};
std::thread controller([&] {
scene.attach_renderable(attached);
attach_finished.store(true, std::memory_order_release);
std::atomic<bool> callback_called{};
auto mutation = scene.attach_renderable(attached, {}, [&](std::exception_ptr exception) {
EXPECT_FALSE(exception);
callback_called.store(true, std::memory_order_release);
});
EXPECT_TRUE(wait_until([&] { return attach_finished.load(std::memory_order_acquire); }));
EXPECT_FALSE(mutation.ready());
EXPECT_FALSE(callback_called.load(std::memory_order_acquire));
EXPECT_EQ(attached->prepare_count.load(std::memory_order_acquire), 0);
gate->open();
controller.join();
scene.wait_for_render();
mutation.wait();
EXPECT_TRUE(wait_until([&] { return callback_called.load(std::memory_order_acquire); }));
EXPECT_EQ(attached->prepare_count.load(std::memory_order_acquire), 0);
scene.render();
scene.wait_for_render();
EXPECT_EQ(attached->prepare_count.load(std::memory_order_acquire), 1);
}
TEST(dynamic_renderable_lifecycle_test,
detach_during_render_keeps_the_frame_owner_alive_until_execution_finishes) {
detach_during_render_waits_for_the_frame_before_releasing_scene_ownership) {
Scene2D_Context<> scene;
auto gate = std::make_shared<Gate>();
std::atomic<bool> destroyed{};
auto renderable = std::make_shared<Blocking_Renderable>(scene, gate, 1, &destroyed);
std::weak_ptr<Blocking_Renderable> weak = renderable;
scene.attach_renderable(renderable);
scene.attach_renderable(renderable).wait();
scene.render();
gate->wait_until_arrived();
std::atomic<bool> detach_finished{};
std::thread controller([&] {
scene.detach_renderable(renderable);
detach_finished.store(true, std::memory_order_release);
});
EXPECT_TRUE(wait_until([&] { return detach_finished.load(std::memory_order_acquire); }));
controller.join();
auto mutation = scene.detach_renderable(renderable);
EXPECT_FALSE(mutation.ready());
renderable.reset();
EXPECT_FALSE(destroyed.load(std::memory_order_acquire));
EXPECT_FALSE(weak.expired());
gate->open();
scene.wait_for_render();
mutation.wait();
EXPECT_TRUE(wait_until([&] { return destroyed.load(std::memory_order_acquire); }));
EXPECT_TRUE(weak.expired());
EXPECT_EQ(scene.renderable_count(), 0u);
@@ -164,15 +157,16 @@ TEST(dynamic_renderable_lifecycle_test,
scene.attach_renderable(child, {
.dependency_parents = {first_parent}
});
scene.wait_for_mutations();
scene.render();
first_gate->wait_until_arrived();
scene.set_dependency_parent(child, second_parent);
auto reparent = scene.set_dependency_parent(child, second_parent);
EXPECT_FALSE(reparent.ready());
EXPECT_EQ(child->prepare_count.load(std::memory_order_acquire), 0);
first_gate->open();
scene.wait_for_render();
reparent.wait();
EXPECT_EQ(child->prepare_count.load(std::memory_order_acquire), 1);
scene.render();
second_gate->wait_until_arrived();
EXPECT_EQ(child->prepare_count.load(std::memory_order_acquire), 1);
@@ -258,9 +252,9 @@ TEST(dynamic_renderable_lifecycle_test,
scene.render();
scene.wait_for_render();
scene.wait_for_mutations();
EXPECT_EQ(renderable->prepare_count.load(std::memory_order_acquire), 1);
EXPECT_EQ(scene.renderable_count(), 0u);
scene.render();
scene.wait_for_render();
EXPECT_EQ(renderable->prepare_count.load(std::memory_order_acquire), 1);
@@ -327,21 +321,25 @@ TEST(dynamic_renderable_lifecycle_test,
Scene2D_Context<Low_Latency_Strategy<Scene2D_Frame_Data>, Tracking_Color_Cache> scene;
auto gate = std::make_shared<Gate>();
auto renderable = std::make_shared<Blocking_Painted_Renderable>(scene, gate);
scene.attach_renderable(renderable);
scene.attach_renderable(renderable).wait();
ASSERT_EQ(Tracking_Color_Cache::next_instance_id.load(), 2);
Tracking_Color_Cache::watched_instance.store(2, std::memory_order_release);
scene.render();
gate->wait_until_arrived();
scene.detach_renderable(renderable);
auto detach = scene.detach_renderable(renderable);
auto attach = scene.attach_renderable(renderable);
EXPECT_FALSE(detach.ready());
EXPECT_FALSE(attach.ready());
EXPECT_FALSE(Tracking_Color_Cache::watched_destroyed.load(std::memory_order_acquire));
scene.attach_renderable(renderable);
ASSERT_EQ(Tracking_Color_Cache::next_instance_id.load(), 3);
EXPECT_EQ(Tracking_Color_Cache::next_instance_id.load(), 2);
gate->open();
scene.wait_for_render();
detach.wait();
attach.wait();
EXPECT_TRUE(wait_until([] {
return Tracking_Color_Cache::watched_destroyed.load(std::memory_order_acquire);
}));
ASSERT_EQ(Tracking_Color_Cache::next_instance_id.load(), 3);
scene.with_final_color_cache([](const Tracking_Color_Cache& cache) {
EXPECT_EQ(cache.samples, std::vector<int>({2}));
});
@@ -446,7 +444,7 @@ TEST(dynamic_renderable_lifecycle_test,
controller.join();
controls_done.store(true, std::memory_order_release);
renderer.join();
scene.wait_for_mutations();
EXPECT_EQ(failures.load(std::memory_order_acquire), 0);
EXPECT_EQ(violations.load(std::memory_order_acquire), 0);
EXPECT_EQ(scene.renderable_count(), 2u);