Files
Renderive/render_2D/renderable/Renderable.h
T
2026-08-13 13:32:23 +08:00

134 lines
4.2 KiB
C++

#pragma once
#include "../base/Types.h"
#include "../event/Event.h"
#include <renderive/renderable/base/Renderable_Base.hpp>
#include <renderive/renderable/base/Renderive_Owner.hpp>
#include <renderive/renderable/Renderable_Graph_Builder.hpp>
#include <atomic>
#include <concepts>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <type_traits>
namespace renderive {
class Renderable;
namespace detail {
class Painter;
class Renderable_State_Observer;
}
class Event_Handler {
public:
virtual ~Event_Handler() = default;
virtual void handle_event(const Event& event) = 0;
};
enum class Renderable_Observer_Event {
None,
Cache_Updated,
Published
};
struct Renderable_Observation {
Renderable_Observer_Event event{Renderable_Observer_Event::None};
std::uint64_t event_time_ns{};
std::uint64_t cache_update_count{};
std::uint64_t publish_count{};
};
class LIB_DECL Renderable : public ::Renderable_Base {
public:
explicit Renderable(bool cache_enabled = true);
~Renderable() override;
[[nodiscard]] Renderable_Cache_Mode get_cache_mode() const noexcept;
void set_cache_mode(Renderable_Cache_Mode mode);
[[nodiscard]] std::string object_name() const;
void set_object_name(std::string name);
[[nodiscard]] Renderable_Observation observation() const noexcept;
protected:
class Impl;
template <class Implementation>
explicit Renderable(std::unique_ptr<Implementation> implementation,
bool cache_enabled)
: ::Renderable_Base(
std::move(implementation),
{.cache_enabled = cache_enabled}) {}
using Prepare_Task_Function =
std::function<void(const Prepare_Render_Context&)>;
using Paint_Task_Function =
std::function<void(detail::Painter&, const Paint_Render_Context&)>;
virtual void prepare_frame(const Prepare_Render_Context& context) = 0;
virtual void paint(detail::Painter& painter,
const Paint_Render_Context& context) = 0;
virtual void build_prepare_graph(Renderable_Graph_Builder& builder);
virtual void build_paint_graph(Renderable_Graph_Builder& builder);
Renderable_Graph_Builder::Task add_prepare_task(Renderable_Graph_Builder& builder,
std::string logical_key,
std::string name,
Prepare_Task_Function function);
Renderable_Graph_Builder::Task add_paint_task(Renderable_Graph_Builder& builder,
std::string logical_key,
std::string name,
Paint_Task_Function function);
void changed() noexcept;
void paint_changed() noexcept;
void render_graph_changed();
private:
void observe_state(Renderable_Observer_Event event, std::uint64_t time_ns,
std::uint64_t cache_update_count,
std::uint64_t publish_count) noexcept;
friend class detail::Renderable_State_Observer;
};
namespace detail {
class Renderable_State_Observer {
public:
static constexpr bool enabled = true;
explicit Renderable_State_Observer(Renderable* renderable) noexcept : renderable_(renderable) {}
template <class Observation>
void observe(const Observation& observation) noexcept {
const bool cache_updated =
observation.event == decltype(observation.event)::cache_updated;
renderable_->observe_state(
cache_updated ? Renderable_Observer_Event::Cache_Updated
: Renderable_Observer_Event::Published,
observation.time_ns,
observation.cache_update_count,
observation.publish_count
);
}
private:
Renderable* renderable_;
};
} // namespace detail
namespace detail {
template <class Value>
inline constexpr bool Paint_Only_Property_Value =
std::same_as<std::remove_cvref_t<Value>, Color> ||
std::same_as<std::remove_cvref_t<Value>, Pen> ||
std::same_as<std::remove_cvref_t<Value>, Brush>;
} // namespace detail
} // namespace renderive