#pragma once #include #include #include #include #include #include #include "renderive/base/observer/Observer.hpp" #include "renderive/frame_control/Frame_Control.hpp" #include "renderive/renderable/color/Concepts.hpp" #include "renderive/state/Published_State_Storage.hpp" #include "renderive/scene/base/Scene_Base.hpp" #include "renderive/scene/base/Frame_Viewport.hpp" struct Scene2D_Frame_Data : Abstract_Frame {}; struct Scene2D_State { Frame_Viewport viewport; }; template concept Scene2D_State_Value = State_Value && requires(State& state) { requires std::same_as, Frame_Viewport>; }; template concept Scene2D_Frame_Control_Constructible = std::constructible_from || std::constructible_from; template , Color_Cache_Type Cache = Recording_Color_Cache, class State = Scene2D_State, class State_Observer = Observer_State<>, class Scene_Observer = Observer_State<>> requires Frame_Control_Strategy_For && Scene2D_State_Value class Scene2D_Context : public Scene_2D_Base, public Published_State_Storage, public Scene_Compositor { public: using Scene_State_Strategy = Published_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 Scene2D_Frame_Control_Constructible explicit Scene2D_Context(Args&&... args) : Scene2D_Context(*std::pmr::get_default_resource(), std::forward(args)...) {} template requires Scene2D_Frame_Control_Constructible explicit Scene2D_Context(std::pmr::memory_resource& memory_resource, Args&&... args) : Scene_2D_Base(memory_resource, std::make_unique()), Scene_State_Strategy(State{}), frame_control(make_frame_control(this->memory_resource(), std::forward(args)...)), final_color_cache_(make_cache(this->memory_resource())) {} template requires Scene2D_Frame_Control_Constructible Scene2D_Context(With_Observer state_observer, With_Observer scene_observer, Args&&... args) : Scene2D_Context(*std::pmr::get_default_resource(), std::move(state_observer), std::move(scene_observer), std::forward(args)...) {} template requires Scene2D_Frame_Control_Constructible Scene2D_Context(std::pmr::memory_resource& memory_resource, With_Observer state_observer, With_Observer scene_observer, Args&&... args) : Scene_2D_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)...)), final_color_cache_(make_cache(this->memory_resource())) {} ~Scene2D_Context() override { this->shutdown(); } Frame_Control frame_control; template void with_final_color_cache(Function&& function) { if (this->is_render_execution_context()) { function(static_cast(final_color_cache_)); return; } auto lock = this->lock_render_idle(); function(static_cast(final_color_cache_)); } 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::shared_ptr make_renderable_color_cache() override { return make_cache_pointer(this->memory_resource()); } Frame_Viewport frame_viewport() const override { return this->Scene_State_Strategy::render_state_value().viewport; } void begin_composite(const Composite_Render_Context&) override { final_color_cache_.clear(); } void composite(const Composite_Render_Context& context) override { if (context.renderable && context.renderable->visible && context.color_cache) final_color_cache_.composite(*context.color_cache); } void publish_scene_state() override { this->Scene_State_Strategy::publish(); } std::uint64_t acquire_scene_state() override { return this->Scene_State_Strategy::state_revision(); } 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_2D_Base::State_Layer> {}; struct Impl : renderive::scene_inheritance::Impl_Node { struct Observer : renderive::scene_inheritance::Observer_Node< Impl, Scene_2D_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)...); } } static Cache make_cache(std::pmr::memory_resource& memory_resource) { if constexpr (std::constructible_from) { return Cache(memory_resource); } else { return Cache(); } } static std::shared_ptr make_cache_pointer(std::pmr::memory_resource& memory_resource) { std::pmr::polymorphic_allocator allocator(&memory_resource); if constexpr (std::constructible_from) { return std::allocate_shared(allocator, memory_resource); } else { return std::allocate_shared(allocator); } } Cache final_color_cache_; };