Files
Aethera/Project_detail_specification.md
2026-08-30 00:38:56 +08:00

57 lines
6.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 项目细节规范
## 代码组织
* `.hpp` 只放业务契约和必要前置声明,不允许出现函数体;构造函数、薄壳函数及模板函数也只能声明。模板定义统一放对应 `.ipp`
,非模板定义放 `.cpp` 或仅供头文件实例化的 `.ipp`
* 嵌套 `Private``.hpp` 只写 `struct Private;`,完整定义、内部字段和 CRTP 定制点放在对应 `.ipp`
* 派生 `Private` 必须继承 `Prev_Private`。可覆盖或必需的 CRTP 能力必须在 `Private` 定义处写清用途、参数、返回值、默认行为、调用时机和编译期选择优先级。
* 状态处理、算法和内部协作都实现在 `Private`;只有外部消费者需要的业务能力才在原始类声明薄壳,并通过 `d` 调用最终
`Private`
* 替换实现时删除旧实现,不保留重复定义、兼容别名或转发层。
## 状态与接口
* 每个状态只能有一个权威来源。双缓冲交换后的当前结构就是稳定读面,跨对象直接读取该结构;禁止为无锁访问再复制一份快照、View、镜像字段或同步缓存。
* `Prop` 保存外部可读写的业务属性,`State` 保存实现向外发布的运行结果,`Private` 保存实现细节;三者不得互相复制并手工同步。
* 每个 `Def` 定义层自动以自身类型生成 `Base_Tag`Prop、State、Private 分别在隔离的标签空间中复用该标签,禁止再声明
`XXX_Prop_Tag``XXX_State_Tag``XXX_Private_Tag`
* 依赖可以选择 Prop/State 的单字段或整个 `Base_Tag` 层;字段写入必须同时发出字段级和所属层级变更,使用方按实际重建粒度选择一种依赖。
* 整体对象依赖只表达依赖图中的拓扑顺序,不传播 dirty;准备顺序、绘图顺序等业务含义由各自 Tag 解释。具体字段依赖才用于对应
Tag 的 dirty 传播,例如绘图缓存失效。
* Kernel `Scene` 只负责 2D/3D 共有的 Prepare 数据阶段;Paint、缓存失效、像素合成和异步后端提交由对应渲染模块自己的
Scene、Tag 与 Taskflow 负责。
* `Scene::Private` 是输入事件流的唯一所有者:外部转移事件对象所有权,并发提交到 Def 注册的 MPMC
三缓冲;收集、内部渲染、外部查询分别占用一份队列,Prepare 入口只在交换锁下轮换三者并清空过期查询队列。事件不得独立触发帧。2D
按 Renderable 区域与 Paint 顺序形成接受链,区域默认整个 viewport;3D 无等待提交渲染域,满载时保留当前事件供下一次 Prepare
重试。
* 帧由 Frame_Policy 创建、持有和复用;每次 `render(frame*)` 只借用该帧并在完成回调返回同一地址。Scene、异步后端和 Web
层只向帧写入固定语义的单调时间点与原始耗时,不保存平均值、分位数或波动等衍生统计。
* Frame_Policy 借用抽象 Scene 并调用 `render(frame*)``fixed_rate` 只由其具体 Policy 子类持有的 Frame_Scheduler 周期时钟驱动,
完成回调不得改变 deadline。`maximum_rate` 子类只在 Scene 开放后续生产或 Policy 回收物理帧槽后异步投递下一次生产任务;
回调不得直接重入 `render()`、不得同步等待。Scene 回调发布 2D 原生 BGRA 或 3D 原生 RGBA;每个 Plot 只服从自身
Frame_Policy。Gallery 仅按 Plot 完成帧的到达顺序更新对应图集槽位,不拥有采样时钟、帧准入、合并或丢帧策略; 每次槽位更新均在唯一串行
Taskflow 媒体 DAG 中组成图集并由 FFmpeg/libx264 编码 H.264 Annex-B。Drogon WebSocket 只传输压缩 access
unit,不得用在途窗口反向跳过已通过 Plot 策略的帧;浏览器由 WebCodecs 解码后按槽位提交各 Plot Canvas。Plot 输入和控制也统一使用
Drogon WebSocket。
* 帧策略及其时钟实现统一归属 `kernel/src/kernel/Frame_Policy`。Manual、Fixed-rate 和 Maximum-rate 分别由具体 Policy 子类表达,
禁止在基类中再保存模式联合体。Policy 直接接收 Scene 回调并通过 `double_buffer/model.hpp` 发布自身 State,不建立事件流或
Taskflow consumer。模式替换必须调用旧 Policy 的异步 `stop(callback)`;停止排空全部 Scene 借用和媒体分派后,在回调中创建 新
Policy。禁止同步等待、策略状态快照、策略历史、轮询累加器或重复诊断字段。
* 相机是 3D Scene 组件,只允许定义在 `render_3D/camera`;Kernel 和 2D 不得依赖相机类型。Web 层只为已有 `Camera_3D`
增加协议描述,不复制相机配置。Gallery 服务同一时刻只允许一个页面实例持有;该页面的所有 Plot 连接共享页面令牌,其他标签页或浏览器实例必须被拒绝。
* `Time_Axis` 是时间与 tick 的唯一权威来源;使用层先推进时间轴,再把同一 tick 分发给所有相关数据图元。时间窗口从第一条数据起始终锚定最新
tick,未产生数据的槽位保持背景。
* 图表选区保存两根轴上的数据范围,绘制时才映射为像素;选区作为独立 Renderable 在使用层与图元组合,禁止在各图元内复制选区状态。
* `Root` 只保存一个最终 `Private` 指针;`Builder::build()` 校验成功后创建并挂接完整 Private,`Root` 通过公共 Private
基类的虚析构统一释放。禁止直接公开该指针。
* 能从权威结构查询或计算的数据即时获取,不保存为成员。类只保存自身职责需要且无法推导的状态,并检查每个新增成员的读写者和生命周期。
* 公共接口只表达业务语义,不暴露 `Private`、内部指针、线程状态或缓冲区角色;接口保持正交,不增加空配置、未完成接口、无消费者统计或只做转发的
getter/setter。
## 注释与修改
* 普通字段使用对齐的同行 `/* ... */` 注释,写清含义、单位、有效条件和生命周期;函数、类型及 CRTP 契约使用声明前注释。
* 审计和重命名应一次完成结构、引用、测试及文档闭环。任何 fallback 必须先写明触发条件、影响范围和验证方式,再实施。
* 修改后完整编译相关目标;需要运行程序时按 `AGENTS.md` 通过 CDB 执行。