Files
Renderive/Kernel/src/renderive/scene/Scene3D_Context.hpp
T
2026-08-15 00:23:52 +08:00

103 lines
4.9 KiB
C++

#pragma once
#include <concepts>
#include <memory>
#include <memory_resource>
#include <utility>
#include "renderive/base/observer/Observer.hpp"
#include "renderive/frame_control/Frame_Control.hpp"
#include "renderive/state/Triple_State_Storage.hpp"
#include "base/Scene_Base.hpp"
struct Scene3D_Frame_Data : Abstract_Frame {};
struct Scene3D_State {
std::uint64_t revision{};
};
template <class Frame_Control, class... Args>
concept Scene3D_Frame_Control_Constructible = std::constructible_from<Frame_Control, Args...> || std::constructible_from<Frame_Control, std::pmr::memory_resource&, Args...>;
template <class Strategy = Low_Latency_Strategy<Scene3D_Frame_Data>, class State = Scene3D_State, class State_Observer = Observer_State<>, class Scene_Observer = Observer_State<>>
requires Frame_Control_Strategy_For<Strategy, Scene3D_Frame_Data> && State_Value<State>
class Scene3D_Context : public Scene_3D_Base,
public Triple_State_Storage<
State, Atomic_Spin_Mutex, State_Observer> {
public:
using Scene_State_Strategy =
Triple_State_Storage<State, Atomic_Spin_Mutex, State_Observer>;
using Frame_Control = Strategy;
using Frame = typename Frame_Control::Frame;
using Painter_Lease = typename Frame_Control::Painter_Lease;
using Render_Lease = typename Frame_Control::Render_Lease;
template <class... Args>
requires Scene3D_Frame_Control_Constructible<Frame_Control, Args&&...>
explicit Scene3D_Context(Args&&... args) : Scene3D_Context(*std::pmr::get_default_resource(), std::forward<Args>(args)...) {}
template <class... Args>
requires Scene3D_Frame_Control_Constructible<Frame_Control, Args&&...>
explicit Scene3D_Context(std::pmr::memory_resource& memory_resource, Args&&... args)
: Scene_3D_Base(memory_resource, std::make_unique<Impl>()),
Scene_State_Strategy(State{}),
frame_control(make_frame_control(this->memory_resource(),
std::forward<Args>(args)...)) {}
template <class... Args>
requires Scene3D_Frame_Control_Constructible<Frame_Control, Args&&...>
Scene3D_Context(With_Observer<State_Observer> state_observer, With_Observer<Scene_Observer> scene_observer, Args&&... args)
: Scene3D_Context(*std::pmr::get_default_resource(), std::move(state_observer), std::move(scene_observer), std::forward<Args>(args)...) {}
template <class... Args>
requires Scene3D_Frame_Control_Constructible<Frame_Control, Args&&...>
Scene3D_Context(std::pmr::memory_resource& memory_resource, With_Observer<State_Observer> state_observer, With_Observer<Scene_Observer> scene_observer, Args&&... args)
: Scene_3D_Base(
memory_resource,
std::make_unique<Impl>(std::move(scene_observer.observer))),
Scene_State_Strategy(State{}, std::move(state_observer)),
frame_control(make_frame_control(this->memory_resource(),
std::forward<Args>(args)...)) {}
~Scene3D_Context() override {
this->shutdown();
}
Frame_Control frame_control;
protected:
Frame_Control_Strategy_Base& frame_control_strategy_impl() noexcept override {
return frame_control;
}
const Frame_Control_Strategy_Base& frame_control_strategy_impl() const noexcept override {
return frame_control;
}
std::uint64_t acquire_scene_state() override {
return this->Scene_State_Strategy::acquire_render_state();
}
void capture_scene_state(Frame_Render_Snapshot& snapshot) const override {
snapshot.set_scene_state(
this->Scene_State_Strategy::render_state_value());
}
private:
struct Context_State_Layer
: renderive::scene_inheritance::State_Node<
Context_State_Layer, Scene_3D_Base::State_Layer> {};
struct Impl
: renderive::scene_inheritance::Impl_Node<Impl, Scene_3D_Base::Impl> {
struct Observer
: renderive::scene_inheritance::Observer_Node<
Impl, Scene_3D_Base::Impl::Observer> {
static void handle(Impl& layer,
const Scene_Base::Observation& observation) {
layer.scene_observer.observe(observation);
}
};
Impl() = default;
explicit Impl(Scene_Observer observer)
: scene_observer(std::move(observer)) {}
std::uint64_t now_ns() const noexcept override {
return scene_observer.now_ns();
}
Scene_Observer scene_observer;
};
template <class... Args>
static Frame_Control make_frame_control(std::pmr::memory_resource& memory_resource, Args&&... args) {
if constexpr (std::constructible_from<Frame_Control, std::pmr::memory_resource&, Args&&...>) {
return Frame_Control(memory_resource, std::forward<Args>(args)...);
} else {
return Frame_Control(std::forward<Args>(args)...);
}
}
};