核心第一版修订
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
\ae\proj\Aethera\cmake-build-vs2022_debug --target Aethera_Kernel_check -j 30 默认每次运行程序都通过CDB运行 D:
|
\ae\proj\Aethera\cmake-build-vs2022_debug --target Aethera_Kernel_check -j 30 默认每次运行程序都通过CDB运行 D:
|
||||||
\ae\ewdk\EWDK_22621_230929-1800\Program Files\Windows Kits\10\Debuggers\x64\cdb.exe
|
\ae\ewdk\EWDK_22621_230929-1800\Program Files\Windows Kits\10\Debuggers\x64\cdb.exe
|
||||||
|
|
||||||
编译器环境脚本 C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\vsdevcmd\ext\VsDevCmd.bat
|
编译器环境脚本 C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat
|
||||||
-host_arch=x64 -arch=x64
|
-host_arch=x64 -arch=x64
|
||||||
|
|
||||||
D:\ae\tools 可能会有有用的工具
|
D:\ae\tools 可能会有有用的工具
|
||||||
@@ -16,6 +16,7 @@ D:\ae\tools 可能会有有用的工具
|
|||||||
写函数 和模块使用下面的约定
|
写函数 和模块使用下面的约定
|
||||||
[错误处理规范](./Error_handling_specification.md)
|
[错误处理规范](./Error_handling_specification.md)
|
||||||
[命名约定](./Project_naming_conventions.md)
|
[命名约定](./Project_naming_conventions.md)
|
||||||
|
[项目细节规范](./Project_detail_specification.md)
|
||||||
|
|
||||||
0. 跟你审计报告 就要大刀阔斧的改 一次性先把问题一次改完 在批量检查 要大步前进
|
0. 跟你审计报告 就要大刀阔斧的改 一次性先把问题一次改完 在批量检查 要大步前进
|
||||||
1. 每个状态只能有一个权威来源,禁止在不同对象中重复保存并手工同步。
|
1. 每个状态只能有一个权威来源,禁止在不同对象中重复保存并手工同步。
|
||||||
|
|||||||
@@ -55,4 +55,27 @@ Low_Latency_Strategy.inl
|
|||||||
|
|
||||||
* 内部实现统一使用 `detail` 命名空间。
|
* 内部实现统一使用 `detail` 命名空间。
|
||||||
|
|
||||||
**总规则:类型大写下划线,值和函数,成员变量小写下划线,字段注释保持行尾注释并且保持对齐**
|
## 普通字段注释
|
||||||
|
|
||||||
|
* 普通数据字段必须在声明同行使用 `/* ... */` 注释;不要为每个普通字段单独占用前一行。
|
||||||
|
* 同一个结构体、类或连续字段分组内,行尾注释的起始列必须对齐。以该分组中最长的声明为基准,并至少保留一个空格。
|
||||||
|
* 注释应说明字段的业务含义;存在单位、有效条件、触发时机、零值语义、所有权或生命周期约束时,必须一并写明。
|
||||||
|
* 禁止只把字段名或类型换成中文重复一遍,也不要把与字段无关的实现流程写进字段注释。
|
||||||
|
* 复杂不变量可在字段分组前增加块注释,但字段本身仍应保留简短、对齐的行尾摘要,避免为了塞入全部说明制造超长单行。
|
||||||
|
* 函数、类型别名、嵌套类型和 CRTP 定制点不属于普通字段,应使用声明前注释说明契约。
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
bool rebuilt{}; /* 本次提交是否重新构建任务图。 */
|
||||||
|
std::uint64_t execution_time_ns{}; /* 本次执行耗时,单位为纳秒;未执行时为 0。 */
|
||||||
|
```
|
||||||
|
|
||||||
|
## Private 实现放置
|
||||||
|
|
||||||
|
* 对外 `.hpp` 中只前置声明嵌套的 `struct Private;`,不得展开其字段、内部派发表、线程状态、缓冲角色或实现函数。
|
||||||
|
* `Owner::Private` 的完整声明放在对应 `.ipp` 中;模板实现继续放在 `.ipp`,非模板实现可放在 `.cpp`。
|
||||||
|
* 派生方可覆盖的 CRTP 函数和能力契约,必须在 `.ipp` 的 `Private` 完整声明处逐项注释;派生 `Private` 必须继承 `Prev_Private`。
|
||||||
|
* 禁止在 `.hpp` 与 `.ipp` 各保留一份 `Private` 定义,也禁止为旧布局保留兼容转发层。
|
||||||
|
|
||||||
|
更完整的代码组织和设计约束见 [项目细节规范](./Project_detail_specification.md)。
|
||||||
|
|
||||||
|
**总规则:类型使用大写下划线;值、函数和成员变量使用小写下划线;普通字段使用对齐的同行注释;Private 的完整实现声明放在对应 `.ipp`。**
|
||||||
|
|||||||
@@ -70,52 +70,11 @@ struct Renderable : Def<Renderable, Root, State_Type<Renderable_State_Tag>, Tagg
|
|||||||
std::size_t paint_task_count{}; /* Paint 子图的任务数;数据模式固定为 1。 */
|
std::size_t paint_task_count{}; /* Paint 子图的任务数;数据模式固定为 1。 */
|
||||||
std::uint64_t prepare_execution_time_ns{}; /* 本次 Prepare 阶段实际执行耗时,单位为纳秒;未执行时为 0。 */
|
std::uint64_t prepare_execution_time_ns{}; /* 本次 Prepare 阶段实际执行耗时,单位为纳秒;未执行时为 0。 */
|
||||||
std::uint64_t paint_execution_time_ns{}; /* 本次 Paint 阶段实际执行耗时,单位为纳秒;未执行时为 0。 */
|
std::uint64_t paint_execution_time_ns{}; /* 本次 Paint 阶段实际执行耗时,单位为纳秒;未执行时为 0。 */
|
||||||
bool operator==(const State&) const = default; /* 支持测试、快照比较和变更检测的逐字段相等比较。 */
|
/* 支持测试、快照比较和变更检测的逐字段相等比较。 */
|
||||||
};
|
bool operator==(const State&) const = default;
|
||||||
struct Private : Prev_Private {
|
|
||||||
/*
|
|
||||||
* 派生 Renderable 的 Private 必须继承 Prev_Private,并为 Prepare/Paint 各提供一种能力:
|
|
||||||
* void prepare_data(T* object) 或 tf::Taskflow build_prepare_graph(T* object, const T::State& state);
|
|
||||||
* void paint(T* object) 或 tf::Taskflow build_paint_graph(T* object, const T::State& state)。
|
|
||||||
*/
|
|
||||||
using Run_Predicate = bool (*)(Root*, bool);
|
|
||||||
using Rebuild_Predicate = bool (*)(Root*);
|
|
||||||
using Stage_Run = void (*)(Root*);
|
|
||||||
using Graph_Builder = tf::Taskflow (*)(Root*);
|
|
||||||
using State_Get = State* (*)(Root*);
|
|
||||||
using State_Notify = void (*)(Root*);
|
|
||||||
struct Stage_Dispatch {
|
|
||||||
Run_Predicate predicate; /* 判断该阶段本次是否执行。 */
|
|
||||||
Rebuild_Predicate rebuild_predicate; /* 判断已有阶段子图是否重建。 */
|
|
||||||
Stage_Run run; /* 数据模式执行入口;子图模式为空。 */
|
|
||||||
Graph_Builder builder; /* 子图模式构建入口;数据模式为空。 */
|
|
||||||
};
|
|
||||||
struct State_Dispatch {
|
|
||||||
State_Get get; /* 获取最终对象的 Renderable 状态层。 */
|
|
||||||
State_Notify notify; /* 发布最终对象的 Renderable 状态。 */
|
|
||||||
};
|
|
||||||
struct Dispatch {
|
|
||||||
Stage_Dispatch prepare; /* Prepare 阶段分派。 */
|
|
||||||
Stage_Dispatch paint; /* Paint 阶段分派。 */
|
|
||||||
State_Dispatch state; /* Renderable 状态访问与发布分派。 */
|
|
||||||
};
|
|
||||||
const Dispatch* dispatch{}; /* 绑定最终对象类型后指向其静态分派表。 */
|
|
||||||
std::unique_ptr<tf::Taskflow> prepare_graph; /* Prepare 子图模式的当前构建产物。 */
|
|
||||||
std::unique_ptr<tf::Taskflow> paint_graph; /* Paint 子图模式的当前构建产物。 */
|
|
||||||
bool prepare_graph_built{}; /* Prepare 子图是否至少成功构建过一次。 */
|
|
||||||
bool paint_graph_built{}; /* Paint 子图是否至少成功构建过一次。 */
|
|
||||||
/* CRTP 可覆盖:决定已构建的 Prepare 子图是否重建;默认返回 false。 */
|
|
||||||
bool should_rebuild_prepare_graph(Attached auto* object, const State& state);
|
|
||||||
/* CRTP 可覆盖:决定已构建的 Paint 子图是否重建;默认返回 false。 */
|
|
||||||
bool should_rebuild_paint_graph(Attached auto* object, const State& state);
|
|
||||||
/* CRTP 可覆盖:决定本次是否执行 Prepare;默认返回 dirty。 */
|
|
||||||
bool should_prepare(Attached auto* object, const State& state, bool dirty);
|
|
||||||
/* CRTP 可覆盖:决定本次是否执行 Paint;默认返回 dirty。 */
|
|
||||||
bool should_paint(Attached auto* object, const State& state, bool dirty);
|
|
||||||
/* CRTP 可覆盖:prepare_data(...) 完成后按派生类到基类顺序调用;默认不处理。 */
|
|
||||||
void after_prepare_data(Attached auto* object);
|
|
||||||
/* Def::Private 的四个 State 生命周期 hook 同样可在派生 Private 中覆盖,并通过 State_Access::get<Tag>() 访问状态层。 */
|
|
||||||
};
|
};
|
||||||
|
/* 完整声明、内部派发以及 Prepare/Paint CRTP 能力契约见 renderable.ipp 中的 Renderable::Private。 */
|
||||||
|
struct Private;
|
||||||
private:
|
private:
|
||||||
/* 数据模式的内部调度入口:执行最终对象 prepare_data(...),再触发各 CRTP 层 after_prepare_data(...)。 */
|
/* 数据模式的内部调度入口:执行最终对象 prepare_data(...),再触发各 CRTP 层 after_prepare_data(...)。 */
|
||||||
template <Prepare_Data_Renderable Object>
|
template <Prepare_Data_Renderable Object>
|
||||||
|
|||||||
@@ -1,6 +1,51 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <memory>
|
#include <memory>
|
||||||
namespace aethera {
|
namespace aethera {
|
||||||
|
struct Renderable::Private : Prev_Private {
|
||||||
|
/*
|
||||||
|
* 派生 Renderable 的 Private 必须继承 Prev_Private,并为 Prepare/Paint 各提供一种执行能力。
|
||||||
|
* Prepare 在编译期按能力选择:存在 build_prepare_graph(...) 时使用子图模式,否则使用 prepare_data(...);两者同时存在时子图优先。
|
||||||
|
* Paint 在编译期按能力选择:存在 build_paint_graph(...) 时使用子图模式,否则使用 paint(...);两者同时存在时子图优先。
|
||||||
|
* should_rebuild_prepare_graph(...) 和 should_rebuild_paint_graph(...) 只决定已选中子图模式后的重建时机,不负责选择模式。
|
||||||
|
*/
|
||||||
|
using Run_Predicate = bool (*)(Root*, bool);
|
||||||
|
using Rebuild_Predicate = bool (*)(Root*);
|
||||||
|
using Stage_Run = void (*)(Root*);
|
||||||
|
using Graph_Builder = tf::Taskflow (*)(Root*);
|
||||||
|
using State_Get = State* (*)(Root*);
|
||||||
|
using State_Notify = void (*)(Root*);
|
||||||
|
struct Stage_Dispatch {
|
||||||
|
Run_Predicate predicate; /* 判断该阶段本次是否执行。 */
|
||||||
|
Rebuild_Predicate rebuild_predicate; /* 判断已有阶段子图是否重建。 */
|
||||||
|
Stage_Run run; /* 数据模式执行入口;子图模式为空。 */
|
||||||
|
Graph_Builder builder; /* 子图模式构建入口;数据模式为空。 */
|
||||||
|
};
|
||||||
|
struct State_Dispatch {
|
||||||
|
State_Get get; /* 获取最终对象的 Renderable 状态层。 */
|
||||||
|
State_Notify notify; /* 发布最终对象的 Renderable 状态。 */
|
||||||
|
};
|
||||||
|
struct Dispatch {
|
||||||
|
Stage_Dispatch prepare; /* Prepare 阶段分派。 */
|
||||||
|
Stage_Dispatch paint; /* Paint 阶段分派。 */
|
||||||
|
State_Dispatch state; /* Renderable 状态访问与发布分派。 */
|
||||||
|
};
|
||||||
|
const Dispatch* dispatch{}; /* 绑定最终对象类型后指向其静态分派表。 */
|
||||||
|
std::unique_ptr<tf::Taskflow> prepare_graph; /* Prepare 子图模式的当前构建产物。 */
|
||||||
|
std::unique_ptr<tf::Taskflow> paint_graph; /* Paint 子图模式的当前构建产物。 */
|
||||||
|
bool prepare_graph_built{}; /* Prepare 子图是否至少成功构建过一次。 */
|
||||||
|
bool paint_graph_built{}; /* Paint 子图是否至少成功构建过一次。 */
|
||||||
|
/* CRTP 可覆盖:决定已选中子图模式的 Prepare 子图是否重建;object 为最终对象,state 为当前发布状态;默认返回 false。 */
|
||||||
|
bool should_rebuild_prepare_graph(Attached auto* object, const State& state);
|
||||||
|
/* CRTP 可覆盖:决定已选中子图模式的 Paint 子图是否重建;object 为最终对象,state 为当前发布状态;默认返回 false。 */
|
||||||
|
bool should_rebuild_paint_graph(Attached auto* object, const State& state);
|
||||||
|
/* CRTP 可覆盖:决定本次是否执行 Prepare;object 为最终对象,state 为当前发布状态,dirty 为 Prepare dirty;默认返回 dirty。 */
|
||||||
|
bool should_prepare(Attached auto* object, const State& state, bool dirty);
|
||||||
|
/* CRTP 可覆盖:决定本次是否执行 Paint;object 为最终对象,state 为当前发布状态,dirty 为 Paint dirty;默认返回 dirty。 */
|
||||||
|
bool should_paint(Attached auto* object, const State& state, bool dirty);
|
||||||
|
/* CRTP 可覆盖:prepare_data(...) 完成后按派生类到基类顺序调用;object 为最终对象;默认不处理。 */
|
||||||
|
void after_prepare_data(Attached auto* object);
|
||||||
|
/* Def::Private 的四个 State 生命周期 hook 同样可在派生 Private 中覆盖,并通过 State_Access::get<Tag>() 访问状态层。 */
|
||||||
|
};
|
||||||
template <Prepare_Data_Renderable Object>
|
template <Prepare_Data_Renderable Object>
|
||||||
void Renderable::run_prepare_data(Object* object) {
|
void Renderable::run_prepare_data(Object* object) {
|
||||||
auto& private_data = static_cast<typename Object::Private&>(object->d);
|
auto& private_data = static_cast<typename Object::Private&>(object->d);
|
||||||
|
|||||||
@@ -19,26 +19,11 @@ struct Scene : Def<Scene, Root, State_Type<Scene_State_Tag>, Dependency_Graph_Ty
|
|||||||
std::size_t taskflow_max_predecessors{}; /* 当前总 Taskflow 中单个任务的最大直接前驱数量。 */
|
std::size_t taskflow_max_predecessors{}; /* 当前总 Taskflow 中单个任务的最大直接前驱数量。 */
|
||||||
std::size_t taskflow_max_successors{}; /* 当前总 Taskflow 中单个任务的最大直接后继数量。 */
|
std::size_t taskflow_max_successors{}; /* 当前总 Taskflow 中单个任务的最大直接后继数量。 */
|
||||||
std::uint64_t taskflow_execution_time_ns{}; /* 本次 process(...) 执行总 Taskflow 的耗时,单位为纳秒;没有任务时为 0。 */
|
std::uint64_t taskflow_execution_time_ns{}; /* 本次 process(...) 执行总 Taskflow 的耗时,单位为纳秒;没有任务时为 0。 */
|
||||||
bool operator==(const State&) const = default; /* 支持测试、快照比较和变更检测的逐字段相等比较。 */
|
/* 支持测试、快照比较和变更检测的逐字段相等比较。 */
|
||||||
};
|
bool operator==(const State&) const = default;
|
||||||
struct Private : Prev_Private {
|
|
||||||
struct Result {}; /* process(...) 完成回调的结果类型;当前仅表示完成。 */
|
|
||||||
struct Runtime; /* Scene 的 Taskflow 构建产物,定义保留在实现文件。 */
|
|
||||||
std::unique_ptr<Runtime> runtime; /* Scene 唯一运行时构建产物的所有权。 */
|
|
||||||
Private();
|
|
||||||
~Private();
|
|
||||||
/* Def CRTP hook:所有缓冲推进后重建必要的总 Taskflow,并更新 Scene_State_Tag 状态层。 */
|
|
||||||
template <Attached Object>
|
|
||||||
void after_advance(Object* object,
|
|
||||||
Prop* pending_prop,
|
|
||||||
State_Access<State> pending_states,
|
|
||||||
const Prop* current_prop,
|
|
||||||
State_Access<State> current_states);
|
|
||||||
/* Impl CRTP 入口:同步执行当前总 Taskflow;派生 Private 只有在替换完整 Scene 处理语义时才应覆盖。 */
|
|
||||||
template <Attached Object, typename Callback>
|
|
||||||
void process(Object* object, Callback&& callback) requires std::invocable<Callback, const Result&>;
|
|
||||||
/* 派生 Scene 的 Private 还可覆盖 Def::Private 的四个 State 生命周期 hook,并通过 State_Access::get<Tag>() 访问状态层。 */
|
|
||||||
};
|
};
|
||||||
|
/* 完整声明、字段及可覆盖 CRTP hook 见 scene.ipp 中的 Scene::Private。 */
|
||||||
|
struct Private;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#include "scene.ipp"
|
#include "scene.ipp"
|
||||||
|
|||||||
@@ -4,8 +4,26 @@
|
|||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
namespace aethera {
|
namespace aethera {
|
||||||
|
struct Scene::Private : Prev_Private {
|
||||||
|
struct Result {}; /* process(...) 完成回调的结果类型;当前仅表示完成。 */
|
||||||
|
struct Runtime; /* Scene 的 Taskflow 构建产物;完整定义位于本文件下方。 */
|
||||||
|
std::unique_ptr<Runtime> runtime; /* Scene 唯一运行时构建产物的所有权。 */
|
||||||
|
Private();
|
||||||
|
~Private();
|
||||||
|
/* Def CRTP hook:所有缓冲推进后重建必要的总 Taskflow,并更新 Scene_State_Tag 状态层。 */
|
||||||
|
template <Attached Object>
|
||||||
|
void after_advance(Object* object,
|
||||||
|
Prop* pending_prop,
|
||||||
|
State_Access<State> pending_states,
|
||||||
|
const Prop* current_prop,
|
||||||
|
State_Access<State> current_states);
|
||||||
|
/* Impl CRTP 入口:同步执行当前总 Taskflow;派生 Private 只有在替换完整 Scene 处理语义时才应覆盖。 */
|
||||||
|
template <Attached Object, typename Callback>
|
||||||
|
void process(Object* object, Callback&& callback) requires std::invocable<Callback, const Result&>;
|
||||||
|
/* 派生 Scene 的 Private 还可覆盖 Def::Private 的四个 State 生命周期 hook,并通过 State_Access::get<Tag>() 访问状态层。 */
|
||||||
|
};
|
||||||
struct Scene::Private::Runtime {
|
struct Scene::Private::Runtime {
|
||||||
std::unique_ptr<tf::Taskflow> taskflow;
|
std::unique_ptr<tf::Taskflow> taskflow; /* 当前已构建的总 Taskflow;为空表示尚未构建。 */
|
||||||
};
|
};
|
||||||
template <Attached Object, typename Callback>
|
template <Attached Object, typename Callback>
|
||||||
void Scene::Private::process(Object* object, Callback&& callback) requires std::invocable<Callback, const Result&> {
|
void Scene::Private::process(Object* object, Callback&& callback) requires std::invocable<Callback, const Result&> {
|
||||||
@@ -62,10 +80,10 @@ void Scene::Private::after_advance(Object* object,
|
|||||||
detail::clear_stage_observers(&taskflow);
|
detail::clear_stage_observers(&taskflow);
|
||||||
taskflow.clear();
|
taskflow.clear();
|
||||||
struct Stage_Tasks {
|
struct Stage_Tasks {
|
||||||
tf::Task prepare_entry;
|
tf::Task prepare_entry; /* Prepare 条件任务,作为该阶段依赖入口。 */
|
||||||
tf::Task prepare_exit;
|
tf::Task prepare_exit; /* Prepare 完成任务,作为该阶段依赖出口。 */
|
||||||
tf::Task paint_entry;
|
tf::Task paint_entry; /* Paint 条件任务,作为该阶段依赖入口。 */
|
||||||
tf::Task paint_exit;
|
tf::Task paint_exit; /* Paint 完成任务,作为该阶段依赖出口。 */
|
||||||
};
|
};
|
||||||
std::pmr::unordered_map<Root*, Stage_Tasks> stage_tasks{resource};
|
std::pmr::unordered_map<Root*, Stage_Tasks> stage_tasks{resource};
|
||||||
for (auto* renderable : renderables) {
|
for (auto* renderable : renderables) {
|
||||||
|
|||||||
Reference in New Issue
Block a user