#pragma once #include #include #include #include #include "renderive/base/observer/Observer.hpp" #include "renderive/frame_control/Frame_Control.hpp" #include "renderive/state/Triple_State_Storage.hpp" #include "base/Scene_Base.hpp" struct Scene3D_Frame_Data : Abstract_Frame {}; struct Scene3D_State { std::uint64_t revision{}; }; template concept Scene3D_Frame_Control_Constructible = std::constructible_from || std::constructible_from; template , class State = Scene3D_State, class State_Observer = Observer_State<>, class Scene_Observer = Observer_State<>> requires Frame_Control_Strategy_For && State_Value class Scene3D_Context : public Scene_3D_Base, public Triple_State_Storage< State, Atomic_Spin_Mutex, State_Observer> { public: using Scene_State_Strategy = Triple_State_Storage; using Frame_Control = Strategy; using Frame = typename Frame_Control::Frame; using Painter_Lease = typename Frame_Control::Painter_Lease; using Render_Lease = typename Frame_Control::Render_Lease; template requires Scene3D_Frame_Control_Constructible explicit Scene3D_Context(Args&&... args) : Scene3D_Context(*std::pmr::get_default_resource(), std::forward(args)...) {} template requires Scene3D_Frame_Control_Constructible explicit Scene3D_Context(std::pmr::memory_resource& memory_resource, Args&&... args) : Scene_3D_Base(memory_resource, std::make_unique()), Scene_State_Strategy(State{}), frame_control(make_frame_control(this->memory_resource(), std::forward(args)...)) {} template requires Scene3D_Frame_Control_Constructible Scene3D_Context(With_Observer state_observer, With_Observer scene_observer, Args&&... args) : Scene3D_Context(*std::pmr::get_default_resource(), std::move(state_observer), std::move(scene_observer), std::forward(args)...) {} template requires Scene3D_Frame_Control_Constructible Scene3D_Context(std::pmr::memory_resource& memory_resource, With_Observer state_observer, With_Observer scene_observer, Args&&... args) : Scene_3D_Base( memory_resource, std::make_unique(std::move(scene_observer.observer))), Scene_State_Strategy(State{}, std::move(state_observer)), frame_control(make_frame_control(this->memory_resource(), std::forward(args)...)) {} ~Scene3D_Context() override { this->shutdown(); } Frame_Control frame_control; protected: Frame_Control_Strategy_Base& frame_control_strategy_impl() noexcept override { return frame_control; } const Frame_Control_Strategy_Base& frame_control_strategy_impl() const noexcept override { return frame_control; } std::uint64_t acquire_scene_state() override { return this->Scene_State_Strategy::acquire_render_state(); } void capture_scene_state(Frame_Render_Snapshot& snapshot) const override { snapshot.set_scene_state( this->Scene_State_Strategy::render_state_value()); } private: struct Context_State_Layer : renderive::scene_inheritance::State_Node< Context_State_Layer, Scene_3D_Base::State_Layer> {}; struct Impl : renderive::scene_inheritance::Impl_Node { struct Observer : renderive::scene_inheritance::Observer_Node< Impl, Scene_3D_Base::Impl::Observer> { static void handle(Impl& layer, const Scene_Base::Observation& observation) { layer.scene_observer.observe(observation); } }; Impl() = default; explicit Impl(Scene_Observer observer) : scene_observer(std::move(observer)) {} std::uint64_t now_ns() const noexcept override { return scene_observer.now_ns(); } Scene_Observer scene_observer; }; template static Frame_Control make_frame_control(std::pmr::memory_resource& memory_resource, Args&&... args) { if constexpr (std::constructible_from) { return Frame_Control(memory_resource, std::forward(args)...); } else { return Frame_Control(std::forward(args)...); } } };