diff --git a/.gitignore b/.gitignore index 6af6a7f..4108192 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ /.playwright-cli/ /package/ /kernel/src_old/ +/render_2D/render_2D_old/ + diff --git a/kernel/kernel/include/concurrent/Concurrent_Storage_with_dirty.hpp b/kernel/kernel/include/concurrent/Concurrent_Storage_with_dirty.hpp index 0a7e39a..fe7deba 100644 --- a/kernel/kernel/include/concurrent/Concurrent_Storage_with_dirty.hpp +++ b/kernel/kernel/include/concurrent/Concurrent_Storage_with_dirty.hpp @@ -25,7 +25,7 @@ struct Property_Dirty_Revision { std::uint64_t revision{}; /* 该成员最近一次发布所使用的整体 revision。 */ bool pending{}; /* 当前编辑面是否写入过该成员。 */ }; -template std::size_t property_dirty_key(const Struct& value, Member Struct::* member) noexcept; +template requires std::derived_from std::size_t property_dirty_key(const Struct& value, Member Owner::* member) noexcept; /* * 属性表不加锁:外部阶段只能通过 set(member) 扩展或标记属性表;advance() 完成发布后, * binder 才在同一内部线程阶段查询 revision。调用方保证这三个阶段不重叠,因此这里不需要 @@ -34,8 +34,8 @@ template std::size_t property_dirty_key(c struct Struct_Dirty_Storage_Hooks : Dirty_Storage_Hooks { template void after_advance(const Values*... before) noexcept; void on_write_access() noexcept; - template void on_write_access(const Struct& value, Member Struct::* member); - template std::uint64_t property_dirty_revision(const Struct& value, Member Struct::* member) const noexcept; + template requires std::derived_from void on_write_access(const Struct& value, Member Owner::* member); + template requires std::derived_from std::uint64_t property_dirty_revision(const Struct& value, Member Owner::* member) const noexcept; std::vector property_revisions; /* 已被成员写接口使用过的属性 revision。 */ std::uint64_t whole_property_revision{}; /* 最近一次整对象写入所发布的 revision。 */ bool pending_whole_property_dirty{}; /* 当前编辑面是否发生过整对象写入。 */ diff --git a/kernel/kernel/include/concurrent/Concurrent_Storage_with_dirty.ipp b/kernel/kernel/include/concurrent/Concurrent_Storage_with_dirty.ipp index 7e5dc1a..a2ce7b4 100644 --- a/kernel/kernel/include/concurrent/Concurrent_Storage_with_dirty.ipp +++ b/kernel/kernel/include/concurrent/Concurrent_Storage_with_dirty.ipp @@ -15,8 +15,8 @@ inline std::uint64_t Dirty_Storage_Hooks::dirty_revision() const noexcept { return revision; } -template -std::size_t property_dirty_key(const Struct& value, Member Struct::* member) noexcept { +template requires std::derived_from +std::size_t property_dirty_key(const Struct& value, Member Owner::* member) noexcept { const auto* const value_address = reinterpret_cast(std::addressof(value)); const auto* const member_address = @@ -45,10 +45,8 @@ inline void Struct_Dirty_Storage_Hooks::on_write_access() noexcept { pending_whole_property_dirty = true; } -template -void Struct_Dirty_Storage_Hooks::on_write_access( - const Struct& value, - Member Struct::* member) { +template requires std::derived_from +void Struct_Dirty_Storage_Hooks::on_write_access(const Struct& value, Member Owner::* member) { const std::size_t key = property_dirty_key(value, member); for (Property_Dirty_Revision& property : property_revisions) { if (property.key != key) continue; @@ -60,10 +58,8 @@ void Struct_Dirty_Storage_Hooks::on_write_access( Dirty_Storage_Hooks::on_write_access(); } -template -std::uint64_t Struct_Dirty_Storage_Hooks::property_dirty_revision( - const Struct& value, - Member Struct::* member) const noexcept { +template requires std::derived_from +std::uint64_t Struct_Dirty_Storage_Hooks::property_dirty_revision(const Struct& value, Member Owner::* member) const noexcept { const std::size_t key = property_dirty_key(value, member); for (const Property_Dirty_Revision& property : property_revisions) { if (property.key != key) continue; diff --git a/kernel/kernel/include/concurrent/base/Concurrent_Struct.hpp b/kernel/kernel/include/concurrent/base/Concurrent_Struct.hpp index 5ef5439..ce5e465 100644 --- a/kernel/kernel/include/concurrent/base/Concurrent_Struct.hpp +++ b/kernel/kernel/include/concurrent/base/Concurrent_Struct.hpp @@ -7,14 +7,14 @@ template struct Export_Struct { template Fn> void get(Fn&& fn) const; - template - auto get(Member Val::* member) const -> std::remove_cv_t; + template requires std::derived_from + auto get(Member Owner::* member) const -> std::remove_cv_t; struct Internal final : Storage_Hooks { /* 仅同一内部线程可调用;可写借用会记录本轮修改,且不得跨越 advance。 */ Val* use(); void advance(); template Fn> void builder_set(Fn&& fn); - template T> void builder_set(Member Val::* member, T&& value); + template T> requires std::derived_from void builder_set(Member Owner::* member, T&& value); Val internal_read{}; /* 内部线程生产面。 */ Val external_read{}; /* 外部线程稳定读面。 */ mutable std::mutex exchange_mutex; /* 仅保护发布复制与外部读取。 */ @@ -25,18 +25,18 @@ template struct Import_Struct { template Fn> void set(Fn&& fn); - template T> - void set(Member Val::* member, T&& value); + template T> requires std::derived_from + void set(Member Owner::* member, T&& value); template Fn> void get(Fn&& fn) const; - template - auto get(Member Val::* member) const -> std::remove_cv_t; + template requires std::derived_from + auto get(Member Owner::* member) const -> std::remove_cv_t; struct Internal final : Storage_Hooks { /* 仅同一内部线程可调用;返回借用不得保存到下一次 advance。 */ Val* use(); void advance(); template Fn> void builder_set(Fn&& fn); - template T> void builder_set(Member Val::* member, T&& value); + template T> requires std::derived_from void builder_set(Member Owner::* member, T&& value); Val internal_read{}; /* 内部线程稳定读面。 */ Val external_write{}; /* 外部线程编辑面。 */ mutable std::mutex exchange_mutex; /* 仅保护外部编辑与内部推进复制。 */ diff --git a/kernel/kernel/include/concurrent/base/Concurrent_Struct.ipp b/kernel/kernel/include/concurrent/base/Concurrent_Struct.ipp index 677f0c9..f896739 100644 --- a/kernel/kernel/include/concurrent/base/Concurrent_Struct.ipp +++ b/kernel/kernel/include/concurrent/base/Concurrent_Struct.ipp @@ -9,8 +9,8 @@ void Export_Struct::get(Fn&& fn) const { std::invoke(std::forward(fn), std::as_const(internal.external_read)); } template -template -auto Export_Struct::get(Member Val::* member) const -> std::remove_cv_t { +template requires std::derived_from +auto Export_Struct::get(Member Owner::* member) const -> std::remove_cv_t { std::lock_guard lock(internal.exchange_mutex); return internal.external_read.*member; } @@ -39,8 +39,8 @@ void Export_Struct::Internal::builder_set(Fn&& fn) { external_read = internal_read; } template -template T> -void Export_Struct::Internal::builder_set(Member Val::* member, T&& value) { +template T> requires std::derived_from +void Export_Struct::Internal::builder_set(Member Owner::* member, T&& value) { internal_read.*member = std::forward(value); external_read = internal_read; } @@ -54,8 +54,8 @@ void Import_Struct::set(Fn&& fn) { std::invoke(std::forward(fn), internal.external_write); } template -template T> -void Import_Struct::set(Member Val::* member, T&& value) { +template T> requires std::derived_from +void Import_Struct::set(Member Owner::* member, T&& value) { std::lock_guard lock(internal.exchange_mutex); if constexpr (requires { internal.on_write_access(internal.external_write, member); }) { internal.on_write_access(internal.external_write, member); @@ -71,8 +71,8 @@ void Import_Struct::get(Fn&& fn) const { std::invoke(std::forward(fn), std::as_const(internal.external_write)); } template -template -auto Import_Struct::get(Member Val::* member) const -> std::remove_cv_t { +template requires std::derived_from +auto Import_Struct::get(Member Owner::* member) const -> std::remove_cv_t { std::lock_guard lock(internal.exchange_mutex); return internal.external_write.*member; } @@ -98,8 +98,8 @@ void Import_Struct::Internal::builder_set(Fn&& fn) { external_write = internal_read; } template -template T> -void Import_Struct::Internal::builder_set(Member Val::* member, T&& value) { +template T> requires std::derived_from +void Import_Struct::Internal::builder_set(Member Owner::* member, T&& value) { internal_read.*member = std::forward(value); external_write = internal_read; } diff --git a/kernel/kernel/include/concurrent/design.md b/kernel/kernel/include/concurrent/design.md index c43c1f8..be92367 100644 --- a/kernel/kernel/include/concurrent/design.md +++ b/kernel/kernel/include/concurrent/design.md @@ -33,6 +33,7 @@ - 前置和后置钩子接收同一组交换前角色裸指针;指针是非拥有借用,只在当前 `advance()` 内有效。 - List 只有整体 revision;Struct 同时提供整体 revision 和属性 revision。 - `set(member, value)` 只标记对应属性,回调写入和内部 `use()` 无法识别具体成员,按整对象写入处理并使全部属性 dirty。 +- Struct 的成员接口接受当前值类型及其公开基类的成员指针,Model 值继承链可以用声明该属性的原始成员指针进行 Builder 初始化、外部 set/get 和 dirty 查询。 - 一次 `advance()` 最多推进一次整体 revision;属性只记录自己最近一次发布对应的整体 revision,不维护第二套计数器。 - `Dirty_Binder` 消费一个或多个 Storage 的整体 dirty;`Property_Dirty_Binder` 消费同一 Struct Storage 的一个或多个固定成员。 - revision 是普通 `std::uint64_t`;binder、写入和来源推进遵守同一内部线程模型约定。 diff --git a/kernel/kernel/include/model/Model.hpp b/kernel/kernel/include/model/Model.hpp index b4ee6de..7e51927 100644 --- a/kernel/kernel/include/model/Model.hpp +++ b/kernel/kernel/include/model/Model.hpp @@ -1,23 +1,41 @@ #pragma once #include "../concurrent/Concurrent_Storage_with_dirty.hpp" #include "../concurrent/storage/Tagged_Storage.hpp" +#include "../Error_handling_specification/Failure_Policy.hpp" #include "../global.hpp" #include #include +#include #include #include namespace aethera { namespace detail { -template struct Model_Private_Pointer { - using element_type = std::remove_reference_t()->d)>; - decltype(auto) operator*() const noexcept { return *model->d; } - Model_Pointer model; /* Owns or borrows the complete Model; dereference exposes its unique Private. */ -}; template struct Model_Type_List {}; +template struct Append_Model_Types; template struct Append_Model_Registrations; template struct Model_Tag_Value; template struct Model_Registration; template struct Model_Value; +template struct Model_State; +struct Model_Instance; +struct Model_Private_Access_Root { + Model_Instance* instance{}; /* 非拥有借用;Builder 物化 endpoint 后绑定到外层 Root。 */ +}; +template struct Model_Private_Base; +template struct Model_Private_Handle { + explicit Model_Private_Handle(Model_Instance* value) noexcept : instance(value) {} + decltype(auto) operator*() const noexcept; + auto operator->() const noexcept; + template void bind() noexcept; + Model_Instance* instance{}; /* 非拥有借用;与外层模型的 Root 子对象同寿命。 */ +private: + void* (*private_view)(void*){}; /* 把唯一实际 Private 调整为本层 Private 基类视图。 */ +}; +template struct Model_Private_Pointer { + using element_type = std::remove_reference_t()->d)>; + decltype(auto) operator*() const noexcept { return *model->d; } + Model_Pointer model; /* 按 Model_Pointer 的指针种类拥有或借用完整模型。 */ +}; template requires Value_Writer void initialize_model_value(Value& target, Fn&& fn); template requires std::derived_from && std::assignable_from void initialize_model_value(Value& target, Member Owner::* member, T&& value); template requires std::assignable_from void initialize_model_value(Value& target, T&& value); @@ -27,8 +45,31 @@ concept Model_Value_Initializer = requires(Value& value, Args&&... args) { }; template using Registered_Model_Value = typename Model_Value::Type; template using Registered_Model_Storage = typename Model_Registration::Type::template Storage>; -template struct Model_Private_Base; -template struct Deferred_Model_Private_Base; +template struct Model_Storage_Set; +struct Model_State_Deleter { + void operator()(void* value) const noexcept { if (destroy) destroy(value); } + void (*destroy)(void*){}; /* 与类型擦除 endpoint state 匹配的析构入口。 */ +}; +struct Model_Instance { + Model_Instance(); + ~Model_Instance(); + Model_Instance(const Model_Instance&) = delete; + Model_Instance& operator=(const Model_Instance&) = delete; + Model_Instance(Model_Instance&&) = delete; + Model_Instance& operator=(Model_Instance&&) = delete; + template void initialize_endpoint(Args&&... args); + template Model_State& state() noexcept; + [[nodiscard]] bool initialized() const noexcept; +private: + template + friend struct Model_Private_Handle; + std::unique_ptr state_owner; /* 唯一拥有当前实际 endpoint 的 Private 与完整 Storage Set。 */ +}; +template struct Model_Builder_Instance { + template void initialize_model(Args&&... args); + Self& model(); + std::unique_ptr ret; /* 构建期间唯一拥有尚未发布的最终模型。 */ +}; template