#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "renderive/base/memory/Memory_Resource.hpp" #include "renderive/capture/Capture.hpp" #include "renderive/frame_control/base/Frame_Control_Strategy_Base.hpp" #include "renderive/renderable/Renderable_Graph_Builder.hpp" #include "renderive/renderable/base/Renderable_Base.hpp" #include "renderive/renderable/base/Renderive_Owner.hpp" #include "renderive/render_graph/External_Operation.hpp" #include "renderive/render_graph/Render_Plan.hpp" #include "renderive/scene/Inheritance.hpp" #include "renderive/scene/dependency/Dependency_Resolver.hpp" #include "Abstract_Frame.hpp" #include "Frame_Render_Snapshot.hpp" #include "Frame_Viewport.hpp" #include "Render_Contexts.hpp" #include "Scene_Lifetime.hpp" #include "renderive/base/Concepts.hpp" namespace renderive::inheritance { struct Observation_Source; } class Color_Cache; enum class Scene_Render_Result : std::uint8_t { none, cancelled, deadline_exceeded, external_failure, shutting_down }; enum class Scene_Edit_Error : std::uint8_t { none, empty_edit, null_renderable, foreign_renderable, renderable_not_attached, dependency_self_reference, dependency_cycle, display_self_reference, display_cycle, dangling_dependency, dangling_display, shutting_down }; struct Scene_Execution_Statistics { std::size_t capacity{}; std::size_t queued{}; std::size_t peak_queued{}; std::uint64_t backpressure_count{}; std::uint64_t backpressure_wait_ns{}; }; class Scene_Base : public Non_Copyable { public: using Renderable = renderive_Owner; using Const_Renderable = renderive_Owner; class Attach_Builder; class Renderable_Editor : public renderive::scene_inheritance::Editor_Root { public: template using next_Editor = renderive::scene_inheritance::Editor_Node; [[nodiscard]] Scene_Edit_Error attach(Renderable renderable); [[nodiscard]] Scene_Edit_Error detach(const Renderable& renderable); [[nodiscard]] Scene_Edit_Error set_dependency_parent(const Renderable& child, const Renderable& parent); [[nodiscard]] Scene_Edit_Error add_dependency_parent(const Renderable& child, const Renderable& parent); [[nodiscard]] Scene_Edit_Error clear_dependency_parent(const Renderable& child); void replace_frame_control_strategy( std::shared_ptr strategy); [[nodiscard]] Scene_Edit_Error error() const noexcept { return error_; } protected: explicit Renderable_Editor(Scene_Base& scene) : scene_(scene) {} Scene_Base& scene_; Scene_Edit_Error fail(Scene_Edit_Error error) noexcept; private: Scene_Edit_Error error_{}; friend class Scene_Base; friend class Attach_Builder; }; class Attach_Builder : public renderive::scene_inheritance::Builder_Root { public: template using next_Builder = renderive::scene_inheritance::Builder_Node; Attach_Builder(const Attach_Builder&) = delete; Attach_Builder& operator=(const Attach_Builder&) = delete; Attach_Builder(Attach_Builder&&) = delete; Attach_Builder& operator=(Attach_Builder&&) = delete; [[nodiscard]] Scene_Edit_Error attach(Renderable renderable); [[nodiscard]] Scene_Edit_Error set_dependency_parent(const Renderable& child, const Renderable& parent); [[nodiscard]] Scene_Edit_Error add_dependency_parent(const Renderable& child, const Renderable& parent); [[nodiscard]] Scene_Edit_Error clear_dependency_parent(const Renderable& child); protected: explicit Attach_Builder(Scene_Base& scene); Scene_Base& scene_; std::unique_lock task_lock_; private: friend class Scene_Base; }; using Renderable_Edit = std::function; class Edit_Operation { public: Edit_Operation() = default; [[nodiscard]] Scene_Edit_Error wait() const; private: explicit Edit_Operation(std::shared_future result) : result_(std::move(result)) {} std::shared_future result_; friend class Scene_Base; friend class Scene_2D_Base; friend class Scene_3D_Base; }; struct Topology_Relationship { Const_Renderable child; Const_Renderable parent; }; struct Topology_Snapshot { std::vector renderables; std::vector display; std::vector dependency; }; enum class Observation_Event { render_submitted, render_started, render_completed, render_cancelled, render_failed }; struct Observation { Observation_Event event{}; std::uint64_t time_ns{}; std::uint64_t render_sequence{}; std::uint64_t scene_state_revision{}; std::size_t renderable_count{}; std::shared_ptr topology; std::shared_ptr frame_snapshot; std::shared_ptr render_plan; }; Scene_Render_Result render(); Scene_Render_Result render(Abstract_Frame& frame); Scene_Render_Result wait_for_render(); void publish_frame_state(); void publish_frame_state(Abstract_Frame& frame); [[nodiscard]] Edit_Operation edit_renderables(Renderable_Edit edit); [[nodiscard]] std::size_t renderable_count() const; [[nodiscard]] Topology_Snapshot topology_snapshot() const; [[nodiscard]] std::vector paint_order_snapshot() const; [[nodiscard]] std::shared_ptr render_plan_snapshot() const; [[nodiscard]] std::shared_ptr find_render_plan(Render_Plan_Version version) const; [[nodiscard]] Capture_Request_Result capture_next_frame(); [[nodiscard]] Capture_Request_Result capture_frames(std::size_t count); [[nodiscard]] Capture_Controller_State capture_state() const noexcept; [[nodiscard]] std::optional capture_session(Capture_Session_Id session_id) const; [[nodiscard]] std::vector capture_sessions() const; [[nodiscard]] std::vector node_statistics(Capture_Session_Id session_id) const; [[nodiscard]] std::vector plan_version_statistics(Capture_Session_Id session_id) const; [[nodiscard]] Scene_Execution_Statistics execution_statistics() const noexcept; [[nodiscard]] std::pmr::memory_resource& memory_resource() const noexcept; [[nodiscard]] std::pmr::memory_resource& upstream_memory_resource() const noexcept; [[nodiscard]] auto frame_control_strategy() -> std::shared_ptr; [[nodiscard]] auto frame_control_strategy() const -> std::shared_ptr; struct Observer : renderive::scene_inheritance::Observer_Root {}; protected: Scene_Base(); explicit Scene_Base(std::pmr::memory_resource& upstream_memory_resource); virtual ~Scene_Base(); struct Builder : renderive::scene_inheritance::Builder_Root {}; struct State : renderive::scene_inheritance::State_Root {}; class Impl; template using next_Builder = renderive::scene_inheritance::Builder_Node; template using next_State = renderive::scene_inheritance::State_Node; template using next_Impl = renderive::scene_inheritance::Impl_Node; template using next_Observer = renderive::scene_inheritance::Observer_Node; template using next_Editor = renderive::scene_inheritance::Editor_Node; Scene_Base(std::pmr::memory_resource& upstream_memory_resource, std::unique_ptr impl); void bind_observation_source( std::unique_ptr source); void unbind_observation_source() noexcept; [[nodiscard]] bool observation_snapshot( std::type_index type, void* destination) const; template Implementation& d_func() noexcept { return static_cast(*impl_); } template const Implementation& d_func() const noexcept { return static_cast(*impl_); } private: friend class Renderable_Base; friend class Scene_2D_Base; std::unique_ptr impl_; }; class Scene_2D_Base : public Scene_Base { public: class Renderable_Editor : public Scene_Base::Renderable_Editor::next_Editor { public: template using next_Editor = renderive::scene_inheritance::Editor_Node; [[nodiscard]] Scene_Edit_Error set_display_parent(const Renderable& child, const Renderable& parent); [[nodiscard]] Scene_Edit_Error add_display_parent(const Renderable& child, const Renderable& parent); [[nodiscard]] Scene_Edit_Error clear_display_parent(const Renderable& child); private: explicit Renderable_Editor(Scene_2D_Base& scene) : Scene_Base::Renderable_Editor::next_Editor< Renderable_Editor>(scene), scene_2d_(scene) {} Scene_2D_Base& scene_2d_; friend class Scene_2D_Base; friend class Attach_Builder; }; class Attach_Builder : public Scene_Base::Attach_Builder::next_Builder { public: template using next_Builder = renderive::scene_inheritance::Builder_Node; [[nodiscard]] Scene_Edit_Error set_display_parent(const Renderable& child, const Renderable& parent); [[nodiscard]] Scene_Edit_Error add_display_parent(const Renderable& child, const Renderable& parent); [[nodiscard]] Scene_Edit_Error clear_display_parent(const Renderable& child); private: explicit Attach_Builder(Scene_2D_Base& scene) : Scene_Base::Attach_Builder::next_Builder< Attach_Builder>(scene), scene_2d_(scene) {} Scene_2D_Base& scene_2d_; friend class Scene_2D_Base; }; using Renderable_Edit = std::function; Scene_2D_Base(); explicit Scene_2D_Base(std::pmr::memory_resource& memory_resource); Attach_Builder attach_builder(); [[nodiscard]] static Attach_Builder attach_builder(const Renderable& anchor); [[nodiscard]] Edit_Operation edit_renderables(Renderable_Edit edit); struct Observer : Scene_Base::next_Observer {}; protected: struct Builder : Scene_Base::next_Builder {}; struct State : Scene_Base::next_State {}; struct Impl; template using next_Builder = renderive::scene_inheritance::Builder_Node; template using next_State = renderive::scene_inheritance::State_Node; template using next_Impl = renderive::scene_inheritance::Impl_Node; template using next_Observer = renderive::scene_inheritance::Observer_Node; template using next_Editor = renderive::scene_inheritance::Editor_Node; static_assert(renderive::inheritance::Defines_Chain_Layer< Builder, Scene_Base::next_Builder, next_Builder, renderive::scene_inheritance::Builder_Node< renderive::inheritance::Chain_Probe, Builder>>); static_assert(renderive::inheritance::Defines_Chain_Layer< State, Scene_Base::next_State, next_State, renderive::scene_inheritance::State_Node< renderive::inheritance::Chain_Probe, State>>); static_assert(renderive::inheritance::Defines_Chain_Layer< Observer, Scene_Base::next_Observer, next_Observer, renderive::scene_inheritance::Observer_Node< renderive::inheritance::Chain_Probe, Observer>>); static_assert(renderive::inheritance::Defines_Chain_Layer< Renderable_Editor, Scene_Base::Renderable_Editor::next_Editor, next_Editor, renderive::scene_inheritance::Editor_Node< renderive::inheritance::Chain_Probe, Renderable_Editor>>); static_assert(renderive::inheritance::Defines_Chain_Layer< Attach_Builder, Scene_Base::Attach_Builder::next_Builder, Attach_Builder::next_Builder, renderive::scene_inheritance::Builder_Node< renderive::inheritance::Chain_Probe, Attach_Builder>>); Scene_2D_Base(std::pmr::memory_resource& memory_resource, std::unique_ptr impl); private: friend class Scene_Base; }; class Scene_3D_Base : public Scene_Base { public: class Renderable_Editor : public Scene_Base::Renderable_Editor::next_Editor { public: template using next_Editor = renderive::scene_inheritance::Editor_Node; private: explicit Renderable_Editor(Scene_3D_Base& scene) : Scene_Base::Renderable_Editor::next_Editor< Renderable_Editor>(scene) {} friend class Scene_3D_Base; }; class Attach_Builder : public Scene_Base::Attach_Builder::next_Builder { public: template using next_Builder = renderive::scene_inheritance::Builder_Node; private: explicit Attach_Builder(Scene_3D_Base& scene) : Scene_Base::Attach_Builder::next_Builder< Attach_Builder>(scene) {} friend class Scene_3D_Base; }; using Renderable_Edit = std::function; [[nodiscard]] Edit_Operation edit_renderables(Renderable_Edit edit); struct Observer : Scene_Base::next_Observer {}; protected: Scene_3D_Base(); explicit Scene_3D_Base(std::pmr::memory_resource& memory_resource); struct Builder : Scene_Base::next_Builder {}; struct State : Scene_Base::next_State {}; struct Impl; template using next_Builder = renderive::scene_inheritance::Builder_Node; template using next_State = renderive::scene_inheritance::State_Node; template using next_Impl = renderive::scene_inheritance::Impl_Node; template using next_Observer = renderive::scene_inheritance::Observer_Node; template using next_Editor = renderive::scene_inheritance::Editor_Node; static_assert(renderive::inheritance::Defines_Chain_Layer< Builder, Scene_Base::next_Builder, next_Builder, renderive::scene_inheritance::Builder_Node< renderive::inheritance::Chain_Probe, Builder>>); static_assert(renderive::inheritance::Defines_Chain_Layer< State, Scene_Base::next_State, next_State, renderive::scene_inheritance::State_Node< renderive::inheritance::Chain_Probe, State>>); static_assert(renderive::inheritance::Defines_Chain_Layer< Observer, Scene_Base::next_Observer, next_Observer, renderive::scene_inheritance::Observer_Node< renderive::inheritance::Chain_Probe, Observer>>); static_assert(renderive::inheritance::Defines_Chain_Layer< Renderable_Editor, Scene_Base::Renderable_Editor::next_Editor, next_Editor, renderive::scene_inheritance::Editor_Node< renderive::inheritance::Chain_Probe, Renderable_Editor>>); static_assert(renderive::inheritance::Defines_Chain_Layer< Attach_Builder, Scene_Base::Attach_Builder::next_Builder, Attach_Builder::next_Builder, renderive::scene_inheritance::Builder_Node< renderive::inheritance::Chain_Probe, Attach_Builder>>); Scene_3D_Base(std::pmr::memory_resource& memory_resource, std::unique_ptr impl); }; #include "Scene_Base.inl"