From 55e2f633130f6dff67edeae2ffc7041be8d19d73 Mon Sep 17 00:00:00 2001 From: wyc <1104749580@qq.com> Date: Tue, 1 Sep 2026 11:01:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../function/frame_policy/Frame_Policy.hpp | 29 +++--- .../frame_policy/Throttled_Latest_Only.hpp | 3 +- kernel/kernel/include/model/Model.hpp | 86 +++++++++++------ kernel/kernel/include/model/Model.ipp | 94 ++++++++++++------- kernel/kernel/include/model/design.md | 2 +- kernel/kernel/test/model/Model_Tests.cpp | 18 ++-- 6 files changed, 142 insertions(+), 90 deletions(-) diff --git a/kernel/kernel/include/function/frame_policy/Frame_Policy.hpp b/kernel/kernel/include/function/frame_policy/Frame_Policy.hpp index 93b3636..1c3b16c 100644 --- a/kernel/kernel/include/function/frame_policy/Frame_Policy.hpp +++ b/kernel/kernel/include/function/frame_policy/Frame_Policy.hpp @@ -1,14 +1,11 @@ #pragma once - #include "concurrent/base/Concurrent_Struct.hpp" #include "model/Model.hpp" #include "statistics/Sliding_Statistics.hpp" - #include #include #include #include - namespace aethera { /* 所有帧策略共享的自适应限速配置、公开状态和统计实现,不拥有具体调度状态。 */ struct Frame_Policy : Model_Layer< @@ -16,28 +13,26 @@ struct Frame_Policy : Model_Layer< Storage_Registration, Storage_Registration> { static constexpr double Default_Frames_Per_Second{30.0}; - struct Prop : Prev { std::optional user_frames_per_second; /* 有值时作为用户帧率上限;无值时不参与限速。 */ - bool render_rate_limit_enabled{}; /* true 时用渲染平均耗时推导理论生成上限。 */ - bool send_rate_limit_enabled{}; /* true 时用发送平均耗时推导理论发送上限。 */ - bool statistics_enabled{}; /* true 时对外发布完整滑动统计。 */ - std::size_t statistics_window_size{120}; /* 统计或理论限速启用时的样本窗口容量。 */ + bool render_rate_limit_enabled{}; /* true 时用渲染平均耗时推导理论生成上限。 */ + bool send_rate_limit_enabled{}; /* true 时用发送平均耗时推导理论发送上限。 */ + bool statistics_enabled{}; /* true 时对外发布完整滑动统计。 */ + std::size_t statistics_window_size{120}; /* 统计或理论限速启用时的样本窗口容量。 */ }; struct State : Prev { - std::uint64_t timer_ticks{}; /* 已处理的调度到期次数。 */ - std::uint64_t dropped_timer_ticks{}; /* 到期时三帧均忙而丢弃的次数。 */ - std::uint64_t completed_frames{}; /* 已完成媒体发送的帧数。 */ - std::optional render_capacity_fps; /* 有渲染样本时推导出的理论最大生成帧率。 */ - std::optional send_capacity_fps; /* 有发送样本时推导出的理论最大发送帧率。 */ + std::uint64_t timer_ticks{}; /* 已处理的调度到期次数。 */ + std::uint64_t dropped_timer_ticks{}; /* 到期时三帧均忙而丢弃的次数。 */ + std::uint64_t completed_frames{}; /* 已完成媒体发送的帧数。 */ + std::optional render_capacity_fps; /* 有渲染样本时推导出的理论最大生成帧率。 */ + std::optional send_capacity_fps; /* 有发送样本时推导出的理论最大发送帧率。 */ double effective_frames_per_second{Default_Frames_Per_Second}; /* 当前有效限速来源的最小值。 */ - Statistics_Summary render_time_ns; /* 渲染耗时滑动统计,单位纳秒。 */ - Statistics_Summary send_time_ns; /* 发送耗时滑动统计,单位纳秒。 */ - Statistics_Summary end_to_end_time_ns; /* 渲染开始至发送完成耗时统计,单位纳秒。 */ + Statistics_Summary render_time_ns; /* 渲染耗时滑动统计,单位纳秒。 */ + Statistics_Summary send_time_ns; /* 发送耗时滑动统计,单位纳秒。 */ + Statistics_Summary end_to_end_time_ns; /* 渲染开始至发送完成耗时统计,单位纳秒。 */ }; struct Private; struct Builder : Prev_Builder {}; }; } - #include "Frame_Policy.ipp" diff --git a/kernel/kernel/include/function/frame_policy/Throttled_Latest_Only.hpp b/kernel/kernel/include/function/frame_policy/Throttled_Latest_Only.hpp index d9c6ad1..da65c5b 100644 --- a/kernel/kernel/include/function/frame_policy/Throttled_Latest_Only.hpp +++ b/kernel/kernel/include/function/frame_policy/Throttled_Latest_Only.hpp @@ -8,8 +8,7 @@ namespace aethera { * 自适应限速、最多三帧在途的 latest-only 策略。Scene 创建三个具体帧;策略轮转复用, * 三槽均忙时丢弃本次 tick;stop completion 前排空 Scene/Sink 借用并销毁全部帧。 */ -struct Throttled_Latest_only : -Def { +struct Throttled_Latest_only : Def { enum struct Start_Result : std::uint8_t { started, already_running, diff --git a/kernel/kernel/include/model/Model.hpp b/kernel/kernel/include/model/Model.hpp index 7930baf..9f0dd10 100644 --- a/kernel/kernel/include/model/Model.hpp +++ b/kernel/kernel/include/model/Model.hpp @@ -3,33 +3,60 @@ #include "../concurrent/storage/Tagged_Storage.hpp" #include #include +#include namespace aethera { namespace detail { template struct Model_Type_List {}; template struct Append_Model_Registrations; -template struct Model_Tag_Registered; -template struct Previous_Model_Value; -struct Empty_Prop {}; -struct Empty_State {}; +template struct Model_Tag_Value; +template struct Model_Registration; +template struct Model_Value; +template < + template typename Concurrent_Storage, + typename Tag, + typename Layer, + typename... Args> +concept Writable_Model_Value = requires( + Concurrent_Storage::Type>& storage, + Args&&... args) { + storage.write(std::forward(args)...); +}; +template < + template typename Concurrent_Storage, + typename Tag, + typename Layer, + typename... Args> +concept Readable_Model_Value = requires( + const Concurrent_Storage::Type>& storage, + Args&&... args) { + storage.read(std::forward(args)...); +}; +struct Empty_Model_Value {}; } -/* Tag 负责选择各定义层的 Prop 类型;同一个 Tag 在注册表中只允许出现一次。 */ struct Prop_Tag { - using Root_Type = detail::Empty_Prop; template using Value = typename Layer::Prop; }; -/* Tag 负责选择各定义层的 State 类型。 */ struct State_Tag { - using Root_Type = detail::Empty_State; template using Value = typename Layer::State; }; /* 把一个业务 Tag 注册到接受单个值类型的 Concurrent Storage 模板。 */ -template typename Concurrent_Storage> struct Storage_Registration { +template < + typename Tag, + template typename Concurrent_Storage> +struct Storage_Registration { using Tag_Type = Tag; template using Storage = Concurrent_Storage; + template + using Value = typename detail::Model_Tag_Value::Type; }; struct Root { using Storage_Registrations = detail::Model_Type_List<>; - template using Prev = typename Tag::Root_Type; struct Private {}; struct Builder {}; }; @@ -40,12 +67,10 @@ template struct Model_Layer : Base { using Storage_Registrations = typename detail::Append_Model_Registrations< typename Base::Storage_Registrations, Registrations...>::Type; - template using Prev = typename detail::Previous_Model_Value< + template using Prev = typename detail::Model_Value< Tag, Base, - detail::Model_Tag_Registered< - Tag, - typename Base::Storage_Registrations>::value>::Type; + Storage_Registrations>::Type; using Prev_Private = typename Base::Private; using Prev_Builder = typename Base::Builder; }; @@ -61,31 +86,34 @@ template struct Def : template < template typename Concurrent_Storage, typename Tag, - typename... Args> requires requires( - Concurrent_Storage>& storage, - Args&&... args) { - storage.write(std::forward(args)...); - } + typename... Args> + requires detail::Writable_Model_Value< + Concurrent_Storage, + Tag, + Self, + Args...> Builder& set(Args&&... args); std::unique_ptr ret; /* 构建期间唯一拥有尚未发布的对象。 */ }; template < template typename Concurrent_Storage, typename Tag, - typename... Args> requires requires( - Concurrent_Storage>& storage, - Args&&... args) { - storage.write(std::forward(args)...); - } + typename... Args> + requires detail::Writable_Model_Value< + Concurrent_Storage, + Tag, + Self, + Args...> Self& write(Args&&... args); template < template typename Concurrent_Storage, typename Tag, - typename... Args> requires requires( - const Concurrent_Storage>& storage, - Args&&... args) { - storage.read(std::forward(args)...); - } + typename... Args> + requires detail::Readable_Model_Value< + Concurrent_Storage, + Tag, + Self, + Args...> const Self& read(Args&&... args) const; template explicit Def(Args&&... args); std::unique_ptr d; /* 唯一拥有最终 Private 和完整 Tagged Storage 集。 */ diff --git a/kernel/kernel/include/model/Model.ipp b/kernel/kernel/include/model/Model.ipp index 19d2a3d..d82c8b9 100644 --- a/kernel/kernel/include/model/Model.ipp +++ b/kernel/kernel/include/model/Model.ipp @@ -28,13 +28,18 @@ struct Append_Model_Registrations< using Type = Model_Type_List; }; -template -struct Model_Tag_Registered; +template +struct Model_Tag_Value { + using Type = Empty_Model_Value; +}; -template -struct Model_Tag_Registered> : - std::bool_constant<( - std::same_as || ...)> {}; +template +struct Model_Tag_Value< + Tag, + Layer, + std::void_t>> { + using Type = typename Tag::template Value; +}; template struct Unique_Model_Tags; @@ -50,23 +55,37 @@ struct Unique_Model_Tags> : typename Rest::Tag_Type> && ...) && Unique_Model_Tags>::value> {}; -template -struct Previous_Model_Value; +template +struct Model_Registration; -template -struct Previous_Model_Value { - using Type = typename Tag::Root_Type; +template +struct Model_Registration< + Tag, + Model_Type_List> : + Model_Registration> {}; + +template < + typename Tag, + template typename Concurrent_Storage, + typename... Rest> +struct Model_Registration< + Tag, + Model_Type_List< + Storage_Registration, + Rest...>> { + using Type = Storage_Registration; }; -template -struct Previous_Model_Value { - using Type = typename Tag::template Value; +template +struct Model_Value { + using Registration = typename Model_Registration::Type; + using Type = typename Registration::template Value; }; template struct Attached_Model_Storage { using Tag = typename Registration::Tag_Type; - using Value = typename Tag::template Value; + using Value = typename Registration::template Value; using Type = Tagged_Storage< Tag, typename Registration::template Storage>; @@ -115,15 +134,18 @@ template < template typename Concurrent_Storage, typename Tag, typename... Args> -requires requires( - Concurrent_Storage>& storage, - Args&&... args) { - storage.write(std::forward(args)...); -} +requires detail::Writable_Model_Value< + Concurrent_Storage, + Tag, + Self, + Args...> typename Def::Builder& Def::Builder::set(Args&&... args) { auto& storage = ret->d->template get(); - using Value = typename Tag::template Value; + using Value = typename detail::Model_Value< + Tag, + Self, + Storage_Registrations>::Type; static_assert(std::same_as< std::remove_cvref_t, Concurrent_Storage>, @@ -147,14 +169,17 @@ template < template typename Concurrent_Storage, typename Tag, typename... Args> -requires requires( - Concurrent_Storage>& storage, - Args&&... args) { - storage.write(std::forward(args)...); -} +requires detail::Writable_Model_Value< + Concurrent_Storage, + Tag, + Self, + Args...> Self& Def::write(Args&&... args) { auto& storage = d->template get(); - using Value = typename Tag::template Value; + using Value = typename detail::Model_Value< + Tag, + Self, + Storage_Registrations>::Type; static_assert(std::same_as< std::remove_cvref_t, Concurrent_Storage>, @@ -168,14 +193,17 @@ template < template typename Concurrent_Storage, typename Tag, typename... Args> -requires requires( - const Concurrent_Storage>& storage, - Args&&... args) { - storage.read(std::forward(args)...); -} +requires detail::Readable_Model_Value< + Concurrent_Storage, + Tag, + Self, + Args...> const Self& Def::read(Args&&... args) const { const auto& storage = d->template get(); - using Value = typename Tag::template Value; + using Value = typename detail::Model_Value< + Tag, + Self, + Storage_Registrations>::Type; static_assert(std::same_as< std::remove_cvref_t, Concurrent_Storage>, diff --git a/kernel/kernel/include/model/design.md b/kernel/kernel/include/model/design.md index 3222376..18f0c74 100644 --- a/kernel/kernel/include/model/design.md +++ b/kernel/kernel/include/model/design.md @@ -5,7 +5,7 @@ | `Model.hpp/.ipp` | 按 Tag 组合定义链,并在最终 `Def` 挂接注册存储。 | | `../concurrent/` | Model 使用的并发存储机制;拥有独立设计文档。 | -`Model_Layer` 通过 `Storage_Registration` 注册一条业务值链。每个定义层用 `Prev` 取得前一层值类型并继承;最终 `Def::Private` 根据完整注册表只创建一次 `Tagged_Storage_Set`。同一 Tag 重复注册属于编译期错误。 +`Model_Layer` 通过 `Storage_Registration` 注册一条业务值链。Tag 只定义如何从 Layer 选择对应业务类型;选择不到时,模型统一使用默认空类型。每个定义层用 `Prev` 取得前一层值类型并继承;最终 `Def::Private` 根据完整注册表只创建一次 `Tagged_Storage_Set`。同一 Tag 重复注册属于编译期错误。 Builder 使用 `set(...)`,最终模型使用 `write(...)` 和 `read(...)`。两个模板参数必须命中同一注册项,参数能力直接由对应并发存储的 `write/read(...)` 重载约束:Struct 可以整对象或按成员读写,List 保留自身批次语义。Builder 对 Struct 同时建立内部读面和外部写面且不产生 dirty;其他存储保留自身写入/消费语义。 diff --git a/kernel/kernel/test/model/Model_Tests.cpp b/kernel/kernel/test/model/Model_Tests.cpp index 8ba468e..cd253b2 100644 --- a/kernel/kernel/test/model/Model_Tests.cpp +++ b/kernel/kernel/test/model/Model_Tests.cpp @@ -6,25 +6,27 @@ #include #include -namespace { -struct Number_List_Root : std::vector {}; - +namespace model_test { struct Number_List_Tag { - using Root_Type = Number_List_Root; - template - using Value = typename Layer::Numbers; + template using Value = typename Layer::Numbers; }; +} + +namespace { +using model_test::Number_List_Tag; struct Test_Model_Base : aethera::Model_Layer< aethera::Root, aethera::Storage_Registration< aethera::Prop_Tag, aethera::Import_Struct_With_Dirty>, - aethera::Storage_Registration> { + aethera::Storage_Registration< + Number_List_Tag, + aethera::Import_List>> { struct Prop : Prev { int base_number{}; }; - struct Numbers : Prev {}; + struct Numbers : Prev, std::vector {}; struct Private : Prev_Private {}; struct Builder : Prev_Builder {}; };