所有权添加完成
This commit is contained in:
@@ -3,8 +3,7 @@
|
||||
|
||||
#include "../render/Blend2D_Cache.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <renderive/scene/base/Scene_Render_Context.hpp>
|
||||
#include <renderive/scene/base/Render_Contexts.hpp>
|
||||
|
||||
namespace renderive {
|
||||
|
||||
@@ -29,18 +28,6 @@ Renderable::Renderable(::Scene_Base& scene, bool cache_enabled)
|
||||
|
||||
Renderable::~Renderable() = default;
|
||||
|
||||
void attach_renderable_child(::Scene_Base& scene, const std::shared_ptr<Renderable>& renderable, const std::shared_ptr<Renderable>& parent) {
|
||||
scene.attach_renderable(renderable);
|
||||
try {
|
||||
scene.set_display_parent(*renderable, parent.get());
|
||||
scene.set_dependency_parent(*renderable, parent.get());
|
||||
} catch (...) {
|
||||
scene.detach_renderable(*renderable);
|
||||
throw;
|
||||
}
|
||||
scene.notify_model_dirty();
|
||||
}
|
||||
|
||||
Renderable_Cache_Mode Renderable::get_cache_mode() const noexcept {
|
||||
return configuration().cache_enabled
|
||||
? Renderable_Cache_Mode::Local_Pixel
|
||||
@@ -48,8 +35,9 @@ Renderable_Cache_Mode Renderable::get_cache_mode() const noexcept {
|
||||
}
|
||||
|
||||
void Renderable::set_cache_mode(Renderable_Cache_Mode mode) {
|
||||
scene().set_renderable_configuration(*this, {.cache_enabled = mode == Renderable_Cache_Mode::Local_Pixel});
|
||||
scene().notify_model_dirty();
|
||||
scene().set_renderable_configuration(
|
||||
shared_from_this(),
|
||||
{.cache_enabled = mode == Renderable_Cache_Mode::Local_Pixel});
|
||||
}
|
||||
|
||||
std::string Renderable::object_name() const {
|
||||
@@ -62,15 +50,6 @@ void Renderable::set_object_name(std::string name) {
|
||||
object_name_ = std::move(name);
|
||||
}
|
||||
|
||||
bool Renderable::is_visible() const noexcept {
|
||||
return visible_.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
void Renderable::set_visible(bool visible) {
|
||||
if (visible_.exchange(visible, std::memory_order_acq_rel) != visible)
|
||||
changed();
|
||||
}
|
||||
|
||||
Renderable_Observation Renderable::observation() const noexcept {
|
||||
return observer_.observation();
|
||||
}
|
||||
@@ -84,14 +63,14 @@ void Renderable::observe_state(Renderable_Observer_Event event,
|
||||
|
||||
void Renderable::build_prepare_graph(Renderable_Graph_Builder& builder) {
|
||||
add_prepare_task(builder, "prepare", "Prepare",
|
||||
[this](const Render_State_View& state, const Scene_Render_Context& context) {
|
||||
prepare_frame(state, context);
|
||||
[this](const Prepare_Render_Context& context) {
|
||||
prepare_frame(context);
|
||||
});
|
||||
}
|
||||
|
||||
void Renderable::build_paint_graph(Renderable_Graph_Builder& builder) {
|
||||
const auto paint_task = add_paint_task(builder, "paint", "Paint",
|
||||
[this](detail::Painter& painter, const Scene_Render_Context& context) {
|
||||
[this](detail::Painter& painter, const Paint_Render_Context& context) {
|
||||
paint(painter, context);
|
||||
});
|
||||
builder.precede(builder.find("prepare"), paint_task);
|
||||
@@ -100,13 +79,10 @@ void Renderable::build_paint_graph(Renderable_Graph_Builder& builder) {
|
||||
Renderable_Graph_Builder::Task Renderable::add_prepare_task(
|
||||
Renderable_Graph_Builder& builder,
|
||||
std::string logical_key,
|
||||
std::string name,
|
||||
Prepare_Task_Function function) {
|
||||
std::string name,
|
||||
Prepare_Task_Function function) {
|
||||
return builder.emplace(std::move(logical_key), std::move(name),
|
||||
Render_Node_Kind::prepare,
|
||||
[this, function = std::move(function)](const Scene_Render_Context& context) {
|
||||
function(render_state_view(), context);
|
||||
});
|
||||
std::move(function));
|
||||
}
|
||||
|
||||
Renderable_Graph_Builder::Task Renderable::add_paint_task(
|
||||
@@ -115,14 +91,14 @@ Renderable_Graph_Builder::Task Renderable::add_paint_task(
|
||||
std::string name,
|
||||
Paint_Task_Function function) {
|
||||
return builder.emplace(std::move(logical_key), std::move(name),
|
||||
Render_Node_Kind::paint,
|
||||
[this, function = std::move(function)](const Scene_Render_Context& context) {
|
||||
if (!is_visible() || context.color_cache == nullptr)
|
||||
[function = std::move(function)](const Paint_Render_Context& context) {
|
||||
if (!context.renderable.visible)
|
||||
return;
|
||||
auto* cache = dynamic_cast<detail::Blend2D_Color_Cache*>(context.color_cache);
|
||||
auto* cache = dynamic_cast<detail::Blend2D_Color_Cache*>(&context.color_cache);
|
||||
if (!cache)
|
||||
return;
|
||||
detail::Painter painter(*cache, {context.viewport.width, context.viewport.height});
|
||||
detail::Painter painter(*cache, {context.frame.viewport.width,
|
||||
context.frame.viewport.height});
|
||||
if (painter)
|
||||
function(painter, context);
|
||||
});
|
||||
|
||||
@@ -51,8 +51,6 @@ private:
|
||||
Renderable_Observation observation_;
|
||||
};
|
||||
|
||||
LIB_DECL void attach_renderable_child(::Scene_Base& scene, const std::shared_ptr<Renderable>& renderable, const std::shared_ptr<Renderable>& parent);
|
||||
|
||||
class LIB_DECL Renderable : public ::Renderable_Base {
|
||||
public:
|
||||
explicit Renderable(::Scene_Base& scene, bool cache_enabled = true);
|
||||
@@ -63,20 +61,17 @@ public:
|
||||
|
||||
[[nodiscard]] std::string object_name() const;
|
||||
void set_object_name(std::string name);
|
||||
[[nodiscard]] bool is_visible() const noexcept;
|
||||
void set_visible(bool visible);
|
||||
[[nodiscard]] Renderable_Observation observation() const noexcept;
|
||||
|
||||
protected:
|
||||
using Prepare_Task_Function =
|
||||
std::function<void(const Render_State_View&, const Scene_Render_Context&)>;
|
||||
std::function<void(const Prepare_Render_Context&)>;
|
||||
using Paint_Task_Function =
|
||||
std::function<void(detail::Painter&, const Scene_Render_Context&)>;
|
||||
std::function<void(detail::Painter&, const Paint_Render_Context&)>;
|
||||
|
||||
virtual void prepare_frame(const Render_State_View& state,
|
||||
const Scene_Render_Context& context) = 0;
|
||||
virtual void prepare_frame(const Prepare_Render_Context& context) = 0;
|
||||
virtual void paint(detail::Painter& painter,
|
||||
const Scene_Render_Context& context) = 0;
|
||||
const Paint_Render_Context& context) = 0;
|
||||
virtual void build_prepare_graph(Renderable_Graph_Builder& builder) override;
|
||||
virtual void build_paint_graph(Renderable_Graph_Builder& builder) override;
|
||||
Renderable_Graph_Builder::Task add_prepare_task(Renderable_Graph_Builder& builder,
|
||||
@@ -98,7 +93,6 @@ private:
|
||||
friend class detail::Renderable_State_Observer;
|
||||
mutable std::mutex metadata_mutex_;
|
||||
std::string object_name_;
|
||||
std::atomic<bool> visible_{true};
|
||||
Renderable_Observer observer_;
|
||||
};
|
||||
|
||||
|
||||
@@ -3,12 +3,58 @@
|
||||
#include <renderive/base/property/Concepts.hpp>
|
||||
#include <renderive/base/property/Validators.hpp>
|
||||
#include <renderive/scene/base/Scene_Base.hpp>
|
||||
#include <algorithm>
|
||||
#include <concepts>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
namespace renderive {
|
||||
class Abs_Axis;
|
||||
namespace detail {
|
||||
class Paint_Overlay;
|
||||
|
||||
template <class Renderable_Type>
|
||||
void append_unique(std::vector<::Scene_Base::Renderable>& renderables,
|
||||
const std::shared_ptr<Renderable_Type>& renderable) {
|
||||
::Scene_Base::Renderable base = renderable;
|
||||
if (base && std::find(renderables.begin(), renderables.end(), base) ==
|
||||
renderables.end())
|
||||
renderables.push_back(std::move(base));
|
||||
}
|
||||
|
||||
template <class Renderable_Type, class Axis_Type>
|
||||
requires std::derived_from<Renderable_Type, Renderable> &&
|
||||
std::derived_from<Axis_Type, Abs_Axis>
|
||||
void append_renderable_dependency(
|
||||
::Scene_Base::Attach_Relationships& relationships,
|
||||
const std::shared_ptr<Axis_Type>& axis) {
|
||||
if (!axis)
|
||||
return;
|
||||
append_unique(relationships.dependency_parents, axis);
|
||||
if constexpr (std::derived_from<Renderable_Type, Paint_Overlay>)
|
||||
append_unique(relationships.display_parents, axis);
|
||||
else
|
||||
append_unique(relationships.display_children, axis);
|
||||
}
|
||||
|
||||
template <class Renderable_Type, class Value>
|
||||
void append_renderable_dependency(
|
||||
::Scene_Base::Attach_Relationships&, const Value&) {}
|
||||
|
||||
template <class Control, class... Args>
|
||||
requires std::derived_from<Control, Renderable>
|
||||
auto renderable_attach_relationships(
|
||||
const std::shared_ptr<Renderable>& parent, const Args&... args)
|
||||
-> ::Scene_Base::Attach_Relationships {
|
||||
::Scene_Base::Attach_Relationships relationships;
|
||||
append_unique(relationships.display_parents, parent);
|
||||
append_unique(relationships.dependency_parents, parent);
|
||||
(append_renderable_dependency<Control>(relationships, args), ...);
|
||||
return relationships;
|
||||
}
|
||||
}
|
||||
|
||||
template <Property_Product Product_Type, Property_Set Properties_Type, Property_Validator<Properties_Type> Validator_Type = No_Property_Validator<Properties_Type>>
|
||||
class Renderable_Builder {
|
||||
public:
|
||||
@@ -38,23 +84,10 @@ public:
|
||||
if (!parent || !(valid_argument(args) && ...))
|
||||
return {};
|
||||
validator(properties);
|
||||
if constexpr (requires(Product& product) { attach_renderable_dependencies(product, args...); } &&
|
||||
(std::copy_constructible<std::decay_t<Args>> && ...)) {
|
||||
auto dependency_args = std::make_tuple(args...);
|
||||
auto result = parent->scene().template make_renderable<Product>(properties, std::forward<Args>(args)...);
|
||||
attach_renderable_child(parent->scene(), result, parent);
|
||||
try {
|
||||
std::apply([&result](const auto&... values) {
|
||||
attach_renderable_dependencies(*result, values...);
|
||||
}, dependency_args);
|
||||
} catch (...) {
|
||||
result->scene().detach_renderable(*result);
|
||||
throw;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
auto relationships =
|
||||
detail::renderable_attach_relationships<Product>(parent, args...);
|
||||
auto result = parent->scene().template make_renderable<Product>(properties, std::forward<Args>(args)...);
|
||||
attach_renderable_child(parent->scene(), result, parent);
|
||||
parent->scene().attach_renderable(result, std::move(relationships));
|
||||
return result;
|
||||
}
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user