docs: sync api and planning docs

This commit is contained in:
2026-04-08 16:07:03 +08:00
parent 08c3278e10
commit 31756847ab
1826 changed files with 44502 additions and 29645 deletions

View File

@@ -14,30 +14,62 @@
- 这个组件绑定的是哪个程序集、命名空间和类。
- 这个脚本组件自己的稳定 UUID。
- 这份脚本实例的可持久化字段缓存 `ScriptFieldStorage`
- 这份脚本实例的可持久化字段缓存 [ScriptFieldStorage](../ScriptFieldStorage/ScriptFieldStorage.md)
这和 Unity 场景里挂着的 `MonoBehaviour` 槽位很接近,但当前实现更明确地区分了“原生数据层”和“运行时实例层”。
这和 Unity 场景里“脚本槽位”的定位很接近,但当前实现更明确地区分了:
## 生命周期
- 原生场景数据
- 运行时活体实例
也正因为如此,`ScriptComponent` 既可以在 Mono 未初始化时参与序列化和 Inspector 编辑,又可以在运行时作为 `ScriptEngine` 的实例描述对象。
## 生命周期与绑定语义
- 构造时会生成一个非零随机 `scriptComponentUUID`
- 默认程序集名是 `GameScripts`
- 首次绑定脚本类时,会通知 `ScriptEngine::OnScriptComponentEnabled()`
- 首次从“无脚本类”切到“有脚本类”时,会通知 `ScriptEngine::OnScriptComponentEnabled()`
- 已绑定脚本类发生变化时,会通知 `ScriptEngine::OnScriptComponentClassChanged()`,触发当前运行时实例停机并按新类重建。
- `ClearScriptClass()` 会保留当前 `assemblyName`,只清空命名空间和类名。
- 启用、禁用、销毁回调会直接转发给 `ScriptEngine`
- 序列化/反序列化会持久化 UUID、脚本类绑定和字段存储内容。
- 序列化 / 反序列化会持久化 UUID、脚本类绑定和字段存储内容。
这里有两个容易误判的实现细节:
- `HasScriptClass()` 当前只检查 `className` 是否非空。
- `SetScriptClass()` / `ClearScriptClass()` 是会触发运行时链路的高层 API`SetAssemblyName()` / `SetNamespaceName()` / `SetClassName()` 只是裸字段写入。
如果你只是改三个字符串,运行时并不会自动知道“类绑定已经变了”。
## 为什么它不是“托管实例本身”
很多脚本系统文档都会把“脚本组件”和“脚本实例”混着讲,但当前实现刻意没这么做。原因很现实:
- 场景资产在未运行时也要保存脚本绑定和字段覆盖值。
- 反序列化或拷贝场景对象时,不应该强依赖托管运行时已经启动。
- 编辑器大量操作只想读写字段和类名,不想立即创建 Mono 对象。
因此 `ScriptComponent` 更像“脚本实例描述与持久化容器”,而不是托管对象本体。
## 字段存储语义
`ScriptFieldStorage``ScriptComponent` 的内嵌成员,不单独分配。它承担的是“本地持久化覆盖值”这一层语义。
当前需要特别注意:
- `ClearScriptClass()` 不会清空字段存储;只是清空类绑定。
- `SetFieldStorage()` 是整体覆盖本地缓存,不会自动把当前活体托管实例同步成完全相同的状态。
- 运行时字段回写也是经由 `ScriptEngine -> IScriptRuntime::SyncManagedFieldsToStorage()` 完成,而不是 `ScriptComponent` 自己主动驱动。
## 所有权
- `ScriptComponent` 本身 `GameObject` 所有。
- `ScriptComponent` 本身 `GameObject` 所有。
- `ScriptFieldStorage` 作为成员对象直接内嵌,不单独分配。
## 当前实现边界
- 只有 `SetScriptClass()` / `ClearScriptClass()` 会通知 `ScriptEngine``SetAssemblyName()``SetNamespaceName()``SetClassName()` 是纯字段写入,不会自动触发重绑定。
- 反序列化使用引擎私有的分号分隔文本格式,不是通用 JSON/YAML。
- `SetFieldStorage()` 直接整体覆盖本地字段缓存,不会自动把活体托管实例同步到同一状态
- 反序列化使用引擎私有的分号分隔文本格式,不是通用 JSON / YAML。
- `ClearScriptClass()` 清空的是命名空间和类名,不会重置程序集名,也不会删除字段缓存
## 常用访问器
@@ -66,9 +98,10 @@
## 真实行为依据
- `engine/include/XCEngine/Scripting/ScriptComponent.h`
- `engine/src/Scripting/ScriptComponent.cpp`
- `tests/scripting/test_script_component.cpp`
- `tests/scripting/test_script_engine.cpp`
- `tests/Scripting/test_script_component.cpp`
- `tests/Scripting/test_script_engine.cpp`
## 相关文档