#include #include "task_flow/src/Task_Runtime.hpp" #include #include #include namespace { using namespace aethera; using namespace aethera::render_3d; struct Publish_Context final { aethera::render_3d::detail::Prepared_Visual prepared{}; /* Taskflow Visual 节点发布、本次 completion 读取。 */ std::size_t slot{}; }; void publish(void* raw_context, std::size_t slot, const aethera::render_3d::detail::Prepared_Visual& prepared) { if (!raw_context) return; auto& context = *static_cast(raw_context); context.prepared = prepared; context.slot = slot; } } // namespace int main() { if (initialize_task_runtime(2) != Initialize_Task_Runtime_Result::initialized) return 2; Point_Visual::Builder builder; builder .set([](Point_Visual::Frame& frame) { frame.items = {Point{.diameter_px = 12.0F}}; }); auto visual = std::shared_ptr{builder.build()}; auto renderable = model_proxy_shared(visual); auto context = std::make_shared(); renderable->advance(); renderable->render(context, 0, &publish); auto component = renderable->taskflow(); auto graph = task_flow::make_task_graph("render_3d.async_visual_contract"); if (!graph->compose("point", component)) return 2; const auto submitted = graph->run([visual = std::move(visual), context = std::move(context)](std::exception_ptr failure) { bool state_valid{}; visual->get([&](const Point_Visual::State& state) { state_valid = state.item_count == 1 && state.prepared_item_count == 1 && state.prepared_revision != 0; }); const bool prepared_valid = context->slot == 0 && context->prepared.has_payload() && context->prepared.item_count() == 1; std::_Exit(!failure && state_valid && prepared_valid ? 0 : 1); }); if (submitted != Run_Taskflow_Result::submitted) return 2; _endthreadex(3); return 3; }