etaf/README.zh-CN.md
2026-09-05 05:07:38 +08:00

133 lines
6.0 KiB
Markdown
Raw 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.

# ETAF
ETAF 是构建在独立 [Ebox](../ebox) 布局与渲染引擎之上的小型文本应用框架。
完整的公共模型是:
```text
Component(props, Scope) → View → Renderer → Ebox Node → Emacs buffer
```
所有可见结构都使用一种形式:
```elisp
(name :property value ... child ...)
```
子节点中唯一的计算桥接是 `expr :value`;属性值则是普通 Elisp 表达式。
```elisp
(etaf-view
(column
(text :font-weight 'bold "Hello")
(text
:color "#687386"
(expr :value (if ready "Ready" "Waiting")))))
```
定义 Component
```elisp
(etaf-define-component status-label (&key label)
"Render a status label."
:view
(text :font-weight 'bold (expr :value label)))
(etaf-mount
"*etaf-demo*"
(etaf-view (status-label :label "Connected")))
```
`etaf-view` 是唯一的公共 View 构造入口。结构 form 不使用 quotequote 仍然是普通 Elisp 数据语法,例如 `'bold`。普通 Elisp 返回 View 时,必须在 `expr` 中显式使用 `(etaf-view ...)` 构造它。
## 性能记录面板
ETAF 提供一个独立、按需加载、与具体应用无关的性能记录器。它消费 Runtime
公共 observer 报告,不使用 advice 或私有跨包探针。Event、Action、mount、flush
和 unmount 等 Runtime operation 会自动记录;同一 operation 内的 Ebox、TP、Data、
Resource 和 SQLite 等 provider 阶段按 sequence 关联到同一条记录。
```elisp
(require 'etaf-performance)
;; 在已挂载 ETAF Runtime 的 buffer 中:
(etaf-performance-mode 1)
;; 正常操作任意已挂载的 ETAF 应用。
(etaf-performance-show)
```
交互采集时先执行 `M-x etaf-performance-clear`,复现一组操作后,在面板按
`c`(或执行 `M-x etaf-performance-copy-report`)即可把完整报告复制到剪贴板;
`w`(或执行 `M-x etaf-performance-export`)可保存为 `.eld` 文件。报告包含
Emacs/显示环境、电源来源、低功耗模式、native JIT 状态、系统负载、分组
p50/p95/max、每次 operation、GC 增量和有序 provider 阶段;面板 header 也显示
同一环境信息,避免把整机降频误判成某个包的热点。
`*ETAF Performance*` 面板会显示 operation ID、generation 变化、总耗时、GC
增量,以及 flat provider 阶段的顺序和各自耗时。provider 阶段可能重叠,因此
不会伪装成 exclusive/self 时间。记录数量由 `etaf-performance-max-records`
限制;关闭 mode 只会解除当前 Runtime 的 observer不修改任何函数。
`etaf-performance-summary` 会按需计算 operation 的 p50/p95/max
`etaf-performance-operation-stage-summary` 则按 provider category 汇总单次
operation 的 flat 阶段。`etaf-performance-records` 返回 operation/stage 的防御性
快照,调用方修改返回值不会改写已保留的历史。
没有内置公共边界的任意操作,可以使用
`etaf-performance-call-operation``etaf-performance-with-operation`
包裹;它们直接委托同一个 Runtime operation 边界,不建立第二套计时器。
## 可执行示例
[`examples/`](examples/README.zh-CN.md) 目录包含三个只依赖 core 的最佳实践应用:保留式状态与 Action、Data Controller 所有权,以及 Resource 错误/清理 lifecycle。`make check` 会编译它们,并通过已挂载的公开事件路径驱动交互。
```elisp
(add-to-list 'load-path "/path/to/github/etaf/examples")
(require 'etaf-counter-example)
(etaf-counter-example-open)
```
## 文档
- [English Architecture](docs/architecture.en.md) · [中文架构](docs/architecture.zh.md)
- [English User Guide](docs/user-guide.en.md) · [中文用户指南](docs/user-guide.zh.md)
- [English Implementation Plan](docs/implementation-plan.en.md) · [中文实施计划](docs/implementation-plan.zh.md)
- [Module-boundary proposal (unimplemented)](docs/proposals/module-boundaries.en.md) · [模块边界提案(未实现)](docs/proposals/module-boundaries.zh.md)
- [English Best-practice Examples](examples/README.md) · [中文示例](examples/README.zh-CN.md)
## 独立包
| 包 | 职责 |
| --- | --- |
| [`etaf-ui`](../etaf-ui/README.md) | 官方 Component 目录Button、Checkbox、Label、Panel 和 DataGrid。 |
| [`etaf-sqlite`](../etaf-sqlite/README.md) | 具体 SQLite Data SourceData Controller 仍属于 ETAF core。 |
| [`etaf-playground`](../etaf-playground/README.md) | ETAF 示例;只有请求官方目录示例时才加载 UI 包。 |
| [`ebox-playground`](../ebox-playground/README.md) | 只使用 Ebox 的布局示例,与 ETAF 独立。 |
没有单独需要安装的 `etaf-data`Data 是 ETAF 核心能力。也没有笼统的 `etaf-adapters` 包:其他数据库、服务、文件或 ORM 应使用明确名称的具体 Data Source 包实现同一契约。
## 加载与验证
ECSS 0.1.0 与 TP 1.0.1 是互相独立的包,安装顺序任意;两者都安装后再安装 Ebox 2.0.1,最后安装 ETAF 0.1.1。ETAF 会直接声明 TP 依赖,因为 Host final-accept authority 使用 TP transaction contract渲染仍只使用 Ebox 2.0 的公共契约。
ETAF 默认选择 Ebox framework SPI v2 port。若要立即按进程完整回退旧
render/Host port必须在加载 ETAF 前把
`etaf-render-port-selection-policy` 设为 `v1`。该选择在当前 Emacs 进程中不可
变;切换时需要重启 Emacs。这个回退不会创建第二个 generation ownersemantic
CAS、单向投影的兼容 stores、retirement 和 scheduler authority 仍保持统一,因此
两个 render port 的 generation、token 与 store-version outcome 完全一致。
开发时先把同级 Ebox 检出目录加入 `load-path`
```elisp
(add-to-list 'load-path "/path/to/github/ebox")
(add-to-list 'load-path "/path/to/github/etaf")
(require 'etaf)
```
运行完整本地门禁:
```sh
make check EMACS=/Applications/Emacs.app/Contents/MacOS/Emacs
```
核心门禁会编译实现、运行 core/Data/Resource 测试,并检查文档和 API 边界。还应在同级 `etaf-ui`、`etaf-sqlite`、`etaf-playground` 和 `ebox-playground` 仓库分别运行 `make check`;它们都不会被 core facade 自动加载。