Files
Renderive/Core/architecture/Renderable.h
T
2026-08-02 19:26:50 +08:00

130 lines
6.2 KiB
C++

#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 <atomic>
#include <concepts>
#include <cstdint>
#include <cstddef>
#include <memory>
#include <mutex>
#include <string>
#include <type_traits>
#include <vector>
namespace renderive {
class Plot_Core;
class Renderable;
class Render_Task_Subflow;
struct Plot_Render_Context;
template <typename Owner, Render_Data_Type Data, Render_State_Type State, Input_Data_Type Input>
struct Renderable_Binding;
template <typename That>
struct Hover_Tooltip_Mixin;
class Renderable : public std::enable_shared_from_this<Renderable> {
public:
virtual Render_Object_Owner create_render_data() {
return make_render_object<Base_Render_Data>();
}
virtual Render_Object_Owner create_render_state() {
return make_render_object<Render_State>();
}
virtual Render_Object_Owner create_input_data() {
return {};
}
virtual void init(const std::shared_ptr<Renderable>& parent);
virtual void init_root(Plot_Core* plot);
void add_child(const std::shared_ptr<Renderable>& child);
void remove_child(const std::shared_ptr<Renderable>& child);
std::vector<std::shared_ptr<Renderable>> children_snapshot() const;
std::vector<std::shared_ptr<Renderable>> 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<std::shared_ptr<Update_State>>& output);
template <typename Owner, Render_Data_Type Data, Render_State_Type State, Input_Data_Type Input>
friend struct Renderable_Binding;
template <typename That>
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<Renderable> parent_renderable;
std::atomic_bool visible_{true};
std::vector<std::shared_ptr<Renderable>> children;
mutable std::mutex children_mutex;
std::weak_ptr<Plot_Render_Context> plot_context;
std::atomic<Renderable_Cache_Mode> cache_mode{Renderable_Cache_Mode::Direct};
std::atomic<std::uint64_t> cache_edit_version{1};
std::atomic<std::uint64_t> 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<std::shared_ptr<Renderable>>& hits, const PointF& pos);
void detach_from_plot_tree();
};
} // namespace renderive