后台服务协程化
This commit is contained in:
@@ -25,20 +25,21 @@ struct Web_Plot_Session::Impl {
|
||||
scene = std::move(*built_scene);
|
||||
scene->activate_view();
|
||||
}
|
||||
std::optional<Web_Response> encode_frame() {
|
||||
std::string pixels;
|
||||
scene->with_frame([&](Image_View image) {
|
||||
pixels = encode_pixel_frame(image, ++sequence);
|
||||
});
|
||||
if (pixels.empty()) return std::nullopt;
|
||||
return Web_Response{Web_Response_Type::Pixels, std::move(pixels)};
|
||||
}
|
||||
std::optional<Web_Response> handle(const Web_Event& event) {
|
||||
return std::visit([this](const auto& value) -> std::optional<Web_Response> {
|
||||
using T = std::decay_t<decltype(value)>;
|
||||
if constexpr (std::same_as<T, Frame_Request>) {
|
||||
const auto result = scene->render_frame();
|
||||
if (!result || scene->wait_for_render() != Scene_Render_Result::none)
|
||||
return std::nullopt;
|
||||
std::string pixels;
|
||||
scene->with_frame([&](Image_View image) {
|
||||
pixels = encode_pixel_frame(image, ++sequence);
|
||||
});
|
||||
if (pixels.empty()) return std::nullopt;
|
||||
return Web_Response{Web_Response_Type::Pixels,
|
||||
std::move(pixels)};
|
||||
if (!result || scene->wait_for_render() != Scene_Render_Result::none) return std::nullopt;
|
||||
return encode_frame();
|
||||
} else if constexpr (std::same_as<T, Viewport_Resize>) {
|
||||
viewport = value.size;
|
||||
rebuild();
|
||||
@@ -48,10 +49,37 @@ struct Web_Plot_Session::Impl {
|
||||
return std::nullopt;
|
||||
}, event);
|
||||
}
|
||||
void async_handle(const Web_Event& event, Web_Response_Completion completion) {
|
||||
if (!std::holds_alternative<Frame_Request>(event)) {
|
||||
completion({handle(event), {}});
|
||||
return;
|
||||
}
|
||||
const auto result = scene->render_frame(
|
||||
[this, completion](Scene_Render_Result render_result, std::exception_ptr exception) mutable {
|
||||
if (exception) {
|
||||
completion({{}, std::move(exception)});
|
||||
return;
|
||||
}
|
||||
if (render_result != Scene_Render_Result::none) {
|
||||
completion({});
|
||||
return;
|
||||
}
|
||||
try {
|
||||
completion({encode_frame(), {}});
|
||||
}
|
||||
catch (...) {
|
||||
completion({{}, std::current_exception()});
|
||||
}
|
||||
});
|
||||
if (!result || *result != Plot_Render_Status::rendered) completion({});
|
||||
}
|
||||
};
|
||||
Web_Plot_Session::Web_Plot_Session() : impl_(std::make_unique<Impl>()) {}
|
||||
Web_Plot_Session::~Web_Plot_Session() = default;
|
||||
std::optional<Web_Response> Web_Plot_Session::handle(const Web_Event& event) {
|
||||
return impl_->handle(event);
|
||||
}
|
||||
void Web_Plot_Session::async_handle(const Web_Event& event, Web_Response_Completion completion) {
|
||||
impl_->async_handle(event, std::move(completion));
|
||||
}
|
||||
} // namespace renderive::web
|
||||
|
||||
Reference in New Issue
Block a user