Files
Renderive/render_2D/render_2D/scene/Plot_Scene.cpp
T
2026-08-16 03:34:17 +08:00

198 lines
6.7 KiB
C++

#include "Plot_Scene.h"
#include "detail/Plot_Scene_Model.hpp"
#include "../plottable/Performance_Overlay.h"
#include "../renderable/Renderable.h"
#include <renderive/scene/base/Scene_Base.hpp>
#include <stdexcept>
#include <variant>
namespace renderive::detail {
void record_performance_frame(Performance_Overlay& overlay, double duration_ms, const Low_Latency_Diagnostics& diagnostics, std::size_t renderable_count, Size viewport) {
overlay.record_frame(duration_ms, diagnostics, renderable_count, viewport);
}
}
namespace renderive {
namespace {
using Manual_Plot_Scene = Plot_Scene_Model<detail::Manual_Frame_Control>;
using Low_Latency_Plot_Scene = Plot_Scene_Model<detail::Low_Latency_Frame_Control>;
using Playback_Plot_Scene = Plot_Scene_Model<detail::Playback_Frame_Control>;
}
struct Plot_Scene::Impl {
using Model = std::variant<std::unique_ptr<Manual_Plot_Scene>,
std::unique_ptr<Low_Latency_Plot_Scene>,
std::unique_ptr<Playback_Plot_Scene>>;
explicit Impl(Plot_Frame_Mode mode) : mode(mode), model(create(mode)) {}
template <class Operation>
decltype(auto) apply(Operation&& operation) {
return std::visit(
[&operation](auto& scene) -> decltype(auto) {
return operation(*scene);
},
model);
}
template <class Operation>
decltype(auto) apply(Operation&& operation) const {
return std::visit(
[&operation](const auto& scene) -> decltype(auto) {
return operation(*scene);
},
model);
}
static Model create(Plot_Frame_Mode mode) {
switch (mode) {
case Plot_Frame_Mode::Manual:
return std::make_unique<Manual_Plot_Scene>();
case Plot_Frame_Mode::Low_Latency:
return std::make_unique<Low_Latency_Plot_Scene>();
case Plot_Frame_Mode::Playback:
return std::make_unique<Playback_Plot_Scene>();
}
throw std::invalid_argument("unknown Plot_Scene frame mode");
}
Plot_Frame_Mode mode;
Model model;
};
Plot_Scene::Plot_Scene(Plot_Scene_Options options)
: impl_(std::make_unique<Impl>(options.frame_mode)) {}
Plot_Scene::~Plot_Scene() = default;
void Plot_Scene::init() { impl_->apply([](auto& scene) { scene.init(); }); }
renderive_Owner<Renderable> Plot_Scene::root_renderable() const {
return impl_->apply([](const auto& scene) { return scene.root_renderable(); });
}
Scene_2D_Base::Attach_Builder Plot_Scene::attach_builder() {
return static_cast<Scene_2D_Base&>(render_scene()).attach_builder();
}
Scene_Base::Edit_Operation Plot_Scene::edit_renderables(Scene_2D_Base::Renderable_Edit edit) {
return static_cast<Scene_2D_Base&>(render_scene()).edit_renderables(std::move(edit));
}
Scene_Base& Plot_Scene::render_scene() noexcept {
return impl_->apply([](auto& scene) -> Scene_Base& { return scene; });
}
const Scene_Base& Plot_Scene::render_scene() const noexcept {
return impl_->apply([](const auto& scene) -> const Scene_Base& { return scene; });
}
void Plot_Scene::set_background_color(Color color) {
impl_->apply([color](auto& scene) { scene.set_background_color(color); });
}
Color Plot_Scene::background_color() const noexcept {
return impl_->apply([](const auto& scene) { return scene.background_color(); });
}
void Plot_Scene::set_viewport_size(Size size) {
impl_->apply([size](auto& scene) { scene.set_viewport_size(size); });
}
Size Plot_Scene::viewport_size() const noexcept {
return impl_->apply([](const auto& scene) { return scene.viewport_size(); });
}
void Plot_Scene::dispatch_event(const Event& event) {
impl_->apply([&event](auto& scene) { scene.dispatch_event(event); });
}
bool Plot_Scene::prepare_frame() {
return impl_->apply([](auto& scene) { return scene.prepare_frame(); });
}
bool Plot_Scene::refresh_manual_frame() {
return impl_->apply([](auto& scene) { return scene.refresh_manual_frame(); });
}
bool Plot_Scene::render_prepared_frame() {
return impl_->apply([](auto& scene) { return scene.render_prepared_frame(); });
}
bool Plot_Scene::discard_pending_frame() {
return impl_->apply([](auto& scene) { return scene.discard_pending_frame(); });
}
bool Plot_Scene::render_frame(bool force) {
return impl_->apply([force](auto& scene) { return scene.render_frame(force); });
}
void Plot_Scene::with_frame(const std::function<void(Image_View)>& consumer) {
impl_->apply([&consumer](auto& scene) { scene.with_frame(consumer); });
}
void Plot_Scene::activate_view() noexcept {
impl_->apply([](auto& scene) { scene.activate_view(); });
}
void Plot_Scene::deactivate_view() noexcept {
impl_->apply([](auto& scene) { scene.deactivate_view(); });
}
bool Plot_Scene::view_active() const noexcept {
return impl_->apply([](const auto& scene) { return scene.view_active(); });
}
void Plot_Scene::request_redraw() noexcept { render_scene().notify_model_dirty(); }
Plot_Control_Error Plot_Scene::set_max_render_fps(double fps) {
return impl_->apply([fps](auto& scene) { return scene.set_max_render_fps(fps); });
}
Plot_Control_Error Plot_Scene::clear_max_render_fps() {
return impl_->apply([](auto& scene) { return scene.clear_max_render_fps(); });
}
double Plot_Scene::max_render_fps() const noexcept {
return impl_->apply([](const auto& scene) { return scene.max_render_fps(); });
}
Plot_Control_Error Plot_Scene::set_consumer_feedback(Frame_Consumer_Feedback feedback) {
return impl_->apply([feedback](auto& scene) { return scene.set_consumer_feedback(feedback); });
}
Plot_Control_Error Plot_Scene::clear_consumer_feedback() {
return impl_->apply([](auto& scene) { return scene.clear_consumer_feedback(); });
}
Plot_Frame_Mode Plot_Scene::frame_mode() const noexcept { return impl_->mode; }
Plot_Frame_Status Plot_Scene::frame_status() const {
return impl_->apply([](const auto& scene) { return scene.frame_status(); });
}
Low_Latency_Diagnostics Plot_Scene::diagnostics() const {
return impl_->apply([](const auto& scene) { return scene.diagnostics(); });
}
Refresh_Control_Snapshot Plot_Scene::refresh_feedback_snapshot() const {
return impl_->apply(
[](const auto& scene) { return scene.refresh_feedback_snapshot(); });
}
void Plot_Scene::set_presentation_sink(std::weak_ptr<Presentation_Sink> sink) {
impl_->apply([&sink](auto& scene) { scene.set_presentation_sink(std::move(sink)); });
}
std::shared_ptr<Performance_Overlay> Plot_Scene::performance_overlay() const {
return impl_->apply([](const auto& scene) { return scene.performance_overlay(); });
}
void Plot_Scene::set_performance_overlay(
std::shared_ptr<Performance_Overlay> overlay) {
impl_->apply([&overlay](auto& scene) {
scene.set_performance_overlay(std::move(overlay));
});
}
} // namespace renderive