#pragma once #include "Scene_Base.hpp" #include #include class Scene_Base::Impl : public renderive::scene_inheritance::Impl_Root { public: using Observer = Scene_Base::Observer; struct Frame_Control_Capability { virtual ~Frame_Control_Capability() = default; virtual std::shared_ptr frame_control_strategy() = 0; virtual std::shared_ptr frame_control_strategy() const = 0; virtual void replace_frame_control_strategy( std::shared_ptr strategy) = 0; }; struct Scene_State_Capability { virtual ~Scene_State_Capability() = default; virtual void before_scene_state_swap() = 0; virtual void swap_scene_state() = 0; virtual void after_scene_state_swap() {} virtual std::uint64_t acquire_scene_state() = 0; virtual void capture_scene_state( Frame_Render_Snapshot& snapshot) const = 0; }; struct Composition_Relationships { virtual ~Composition_Relationships() = default; virtual void attach(Renderable_Id id) = 0; [[nodiscard]] virtual Scene_Edit_Error add_parent( Renderable_Id child, Renderable_Id parent) = 0; [[nodiscard]] virtual bool cleanup() = 0; [[nodiscard]] virtual bool valid() const = 0; virtual renderive::scene::dependency::Resolution resolve() const = 0; virtual void restore( const renderive::scene::dependency::Resolution& resolution) = 0; }; struct Raster_Capabilities { virtual ~Raster_Capabilities() = default; virtual std::shared_ptr make_renderable_color_cache() = 0; virtual Frame_Viewport frame_viewport() const = 0; }; struct Compositor { virtual ~Compositor() = default; virtual void begin_composite( const Composite_Render_Context& context) = 0; virtual void composite(const Composite_Render_Context& context) = 0; }; struct Renderer { virtual ~Renderer() = default; virtual Node_Execution_Result render_scene( const Scene_Render_Context& context) = 0; }; using Composite_Render_Node_Function = std::function; using Scene_Render_Node_Function = std::function; using Execution_Function = std::variant; struct Execution_Binding { std::optional renderable_index; Execution_Function function; }; struct Compiled_Render_Plan; struct Render_Completion { Scene_Render_Result error{}; std::exception_ptr exception; bool completed{}; bool observed{}; }; struct Render_Task { std::shared_ptr snapshot; std::shared_ptr compiled_plan; std::shared_ptr topology; std::shared_ptr frame; std::shared_ptr completion; }; class Execution_Context; class Render_Execution_Scope; class Renderable_Edit_Transaction; explicit Impl(std::pmr::memory_resource& upstream_memory_resource); virtual ~Impl(); void initialize(Scene_Base& scene); [[nodiscard]] Scene_Base& scene() noexcept; [[nodiscard]] const Scene_Base& scene() const noexcept; [[nodiscard]] virtual std::uint64_t now_ns() const noexcept; [[nodiscard]] std::pmr::memory_resource& memory_resource() const noexcept; [[nodiscard]] std::pmr::memory_resource& upstream_memory_resource() const noexcept; [[nodiscard]] Frame_Control_Capability& frame_control(); [[nodiscard]] const Frame_Control_Capability& frame_control() const; [[nodiscard]] Scene_State_Capability& scene_state(); [[nodiscard]] const Scene_State_Capability& scene_state() const; [[nodiscard]] Composition_Relationships* composition() noexcept; [[nodiscard]] const Composition_Relationships* composition() const noexcept; [[nodiscard]] Raster_Capabilities* raster() noexcept; [[nodiscard]] const Raster_Capabilities* raster() const noexcept; [[nodiscard]] Scene_Render_Result submit_render(Abstract_Frame* frame); void complete_pending_operation(); void record_pending_exception(std::exception_ptr exception); void capture_edit_renderable(const Renderable& renderable); void request_render_graph_rebuild(Renderable_Base& renderable); [[nodiscard]] std::shared_ptr snapshot_live_model(); [[nodiscard]] std::shared_ptr capture_live_frame(); void publish_frame_state_locked(); void bind_observation_source( std::unique_ptr source); void unbind_observation_source() noexcept; void publish_observation(); std::shared_ptr compile_render_plan( const Frame_Render_Snapshot& snapshot); void execute_render_task(std::shared_ptr task); [[nodiscard]] Scene_Edit_Error execute_renderable_edit( std::function edit); [[nodiscard]] Scene_Render_Result execute_render_graph(Render_Task& task); [[nodiscard]] Scene_Edit_Error renderable_scene_error( const Renderable_Base& renderable) const noexcept; [[nodiscard]] bool is_renderable_attached_locked( const Renderable& renderable) const; [[nodiscard]] Scene_Edit_Error validate_structure_locked() const; [[nodiscard]] Scene_Edit_Error cleanup_detached_topology_locked(); [[nodiscard]] std::unique_lock lock_render_idle(); [[nodiscard]] bool is_render_execution_context() const noexcept; void invalidate_renderables(); void shutdown(); [[nodiscard]] Scene_Base::Edit_Operation enqueue_renderable_edit( std::function edit); inline static thread_local Scene_Base* active_execution_scene_{}; inline static thread_local Scene_Base* active_renderable_edit_scene_{}; inline static thread_local Scene_Base* active_submitted_observer_scene_{}; Scene_Base* owner_{}; std::shared_ptr scene_lifetime_; std::shared_ptr memory_domain_; std::unique_ptr execution_context_; std::pmr::unordered_map renderables_; renderive::scene::dependency::Dependency_Resolver dependency_resolver_; std::pmr::unordered_map> color_caches_; mutable std::mutex model_mutex_; mutable std::recursive_mutex task_mutex_; std::condition_variable_any render_completed_; std::shared_ptr current_completion_; std::exception_ptr pending_exception_; std::size_t deferred_render_count_{}; bool refresh_interval_reset_pending_{}; std::uint64_t render_sequence_{}; std::size_t pending_operations_{}; bool runtime_started_{}; bool shutting_down_{}; Renderable_Edit_Transaction* active_edit_transaction_{}; const Render_Node_Id composite_begin_node_id_; const Render_Node_Id scene_render_node_id_; Render_Plan_History render_plan_history_; std::shared_ptr compiled_render_plan_; Capture_Controller capture_controller_; Capture_Repository capture_repository_; mutable std::mutex observation_mutex_; std::shared_ptr observation_source_; }; struct Scene_2D_Base::Impl : Scene_Base::next_Impl, Scene_Base::Impl::Composition_Relationships { using Observer = Scene_2D_Base::Observer; static_assert(renderive::inheritance::Defines_Chain_Layer< Impl, Scene_Base::next_Impl, Scene_2D_Base::next_Impl, renderive::scene_inheritance::Impl_Node< renderive::inheritance::Chain_Probe, Impl>>); explicit Impl(std::pmr::memory_resource& memory_resource); void with_initial_display_edit(std::function edit); [[nodiscard]] Scene_Edit_Error set_display_parent_locked( const Renderable& child, const Renderable& parent); [[nodiscard]] Scene_Edit_Error add_display_parent_locked( const Renderable& child, const Renderable& parent); [[nodiscard]] Scene_Edit_Error clear_display_parent_locked( const Renderable& child); void attach(Renderable_Id id) override; [[nodiscard]] Scene_Edit_Error add_parent( Renderable_Id child, Renderable_Id parent) override; [[nodiscard]] bool cleanup() override; [[nodiscard]] bool valid() const override; [[nodiscard]] renderive::scene::dependency::Resolution resolve() const override; void restore( const renderive::scene::dependency::Resolution& resolution) override; renderive::scene::dependency::Dependency_Resolver display_resolver_; }; struct Scene_3D_Base::Impl : Scene_Base::next_Impl { using Observer = Scene_3D_Base::Observer; static_assert(renderive::inheritance::Defines_Chain_Layer< Impl, Scene_Base::next_Impl, Scene_3D_Base::next_Impl, renderive::scene_inheritance::Impl_Node< renderive::inheritance::Chain_Probe, Impl>>); explicit Impl(std::pmr::memory_resource& memory_resource) : Scene_Base::next_Impl(memory_resource) {} };