#pragma once #include "../base/Geometry.h" #include "../base/Object_Semantics.h" #include "../base/Text.h" #include "../event/Event.h" #include "../event/Key_Event.h" #include "../event/Pointer_Event.h" #include "../event/Resize_Event.h" #include "../event/Wheel_Event.h" #include "../render/Canvas.h" #include "../render/Image.h" #include "../render/Renderable_Frame_Node.h" #include "Render_Data.h" #include "Render_Config.h" #include #include #include #include #include #include #include #include #include namespace renderive { class Plot_Core; class Renderable; class Render_Task_Subflow; struct Plot_Render_Context; template struct Renderable_Binding; template struct Hover_Tooltip_Mixin; class Renderable : public std::enable_shared_from_this { public: virtual Render_Object_Owner create_render_data() { return make_render_object(); } virtual Render_Object_Owner create_render_state() { return make_render_object(); } virtual Render_Object_Owner create_input_data() { return {}; } virtual void init(const std::shared_ptr& parent); virtual void init_root(Plot_Core* plot); void add_child(const std::shared_ptr& child); void remove_child(const std::shared_ptr& child); std::vector> children_snapshot() const; std::vector> hit_renderables(const PointF& pos); void append_tree_snapshot( Renderable_Frame_Tree& snapshot, std::uint64_t parent_node_id = 0, const std::string& parent_object_name = {}, int render_tree_depth = 0, std::uint64_t cache_parent_node_id = 0, const std::string& cache_parent_object_name = {}, int cache_tree_depth = 0); void render(Canvas& canvas, const Render_Frame_Snapshot& snapshot); void render_tree_snapshot(Canvas& canvas, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_Tree& tree, std::size_t index); void draw(Canvas& canvas, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_View& frame_view); void prepare_data(const Render_Frame_Snapshot& snapshot, const Renderable_Frame_View& frame_view); bool select_test(const PointF& pos); void plot_event(const Event& event); void mouse_press_event(const Pointer_Event& event); void mouse_move_event(const Pointer_Event& event); void mouse_release_event(const Pointer_Event& event); void set_hover_state(Point pos, bool active); void key_press_event(const Key_Event& event); void key_release_event(const Key_Event& event); void resize_event(const Resize_Event& event); void wheel_event(const Wheel_Event& event); Renderable_Cache_Mode get_cache_mode() const; void set_cache_mode(Renderable_Cache_Mode mode); [[nodiscard]] bool attached_to_plot() const; [[nodiscard]] bool shares_plot_with(const Renderable& other) const; [[nodiscard]] const std::string& object_name() const; [[nodiscard]] std::uint64_t node_id() const; void set_object_name(std::string name); [[nodiscard]] bool is_visible() const; void set_visible(bool value); [[nodiscard]] bool should_prepare() const; void detach_from_parent(); std::string cache_parent_object_name() const; int cache_tree_depth() const; std::string render_parent_object_name() const; int render_tree_depth() const; void mark_render_dirty(Dirty_Reason reason = Dirty_Reason::Core_Data); [[nodiscard]] bool ok() const; [[nodiscard]] bool get_retiring() const; virtual ~Renderable(); private: friend void build_renderable_prepare(Renderable& renderable, Render_Task_Subflow& subflow, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_View& frame_view); friend void drain_renderable_prepare_updates(Renderable& renderable, std::pmr::vector>& output); template friend struct Renderable_Binding; template friend struct Hover_Tooltip_Mixin; Render_Object_Owner d_owner; Render_Data* d_ptr{}; Plot_Core* plot{}; std::uint64_t node_id_{}; std::string object_name_; std::weak_ptr parent_renderable; std::atomic_bool visible_{true}; std::vector> children; mutable std::mutex children_mutex; std::weak_ptr plot_context; std::atomic cache_mode{Renderable_Cache_Mode::Direct}; std::atomic cache_edit_version{1}; std::atomic cache_ready_version{0}; Image cache_image; Rect cache_bounds; std::atomic_bool retiring{true}; std::atomic_bool initialized{false}; void init_common(Plot_Core* plot); void render_direct(Canvas& canvas, const Render_Frame_Snapshot& snapshot); void render_cached(Canvas& canvas, const Render_Frame_Snapshot& snapshot); void render_self(Canvas& canvas, const Render_Frame_Snapshot& snapshot); void render_children(Canvas& canvas, const Render_Frame_Snapshot& snapshot); void render_cache_image(const Rect& bounds, const Render_Frame_Snapshot& snapshot, std::uint64_t version); std::size_t render_tree_node(Canvas& canvas, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_Tree& tree, std::size_t index); void render_direct_tree_node(Canvas& canvas, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_Tree& tree, std::size_t index); void render_cached_tree_node(Canvas& canvas, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_Tree& tree, std::size_t index); void render_cache_image_tree_node(const Rect& bounds, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_Tree& tree, std::size_t index, std::uint64_t version); void render_self(Canvas& canvas, const Render_Frame_Snapshot& snapshot, const Renderable_Frame_Node* node); void append_hit_renderables(std::vector>& hits, const PointF& pos); void detach_from_plot_tree(); }; } // namespace renderive