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

@@ -23,18 +23,49 @@ void SetScriptClass(
设置当前脚本组件绑定的托管类信息。
## 重载差异
- `SetScriptClass(namespaceName, className)`
- 只修改命名空间和类名。
- 保留当前 `assemblyName`,默认场景下一般就是 `GameScripts`
- `SetScriptClass(assemblyName, namespaceName, className)`
- 同时修改程序集名、命名空间和类名。
## 当前实现行为
- 两个重载都会先记录“之前是否已经有脚本类”。
- 然后覆盖程序集名、命名空间和类名。
- 如果“之前没有脚本类,设置后有脚本类”,会调用 `ScriptEngine::Get().OnScriptComponentEnabled(this)`
- 如果之前已经绑定脚本类,并且程序集名 / 命名空间 / 类名发生变化,会调用 `ScriptEngine::Get().OnScriptComponentClassChanged(this)`
两个重载都遵循同一套顺序:
1. 记录调用前是否已有脚本类绑定
2. 计算绑定字符串是否真的发生变化
3. 先把新的程序集名 / 命名空间 / 类名写入 `ScriptComponent`
4. 如果“之前没有脚本类,设置后有脚本类”,调用 `ScriptEngine::Get().OnScriptComponentEnabled(this)`
5. 如果之前已经绑定脚本类,并且绑定字符串发生变化,调用 `ScriptEngine::Get().OnScriptComponentClassChanged(this)`
## 关键语义
- “首次绑定”走的是 `OnScriptComponentEnabled()` 路径,不是 `OnScriptComponentClassChanged()`
- “已绑定后改类”走的是显式重绑定路径。
- 如果新值和旧值完全相同,当前不会重复通知 `ScriptEngine`
- 因为新字符串是先写入再通知引擎,所以运行时收到类切换通知时,`ScriptComponent` 身上已经是新绑定。
最后这一点很重要。它意味着:
- 旧托管实例的停机确实会发生。
- 但如果停机过程里有原生侧日志或调试代码读取 `component->GetFullClassName()`,读到的会是新类名,而不是旧类名。
## 设计含义
- 当前实现把“首次绑定脚本类”视作启用事件。
- 已绑定类发生变化时,`ScriptEngine` 会停掉旧实例并按新类重新跟踪,这已经是当前实现的一部分
- `SetAssemblyName()` / `SetNamespaceName()` / `SetClassName()` 这些原始 setter 不会触发同样的流程;需要真正重绑定时应走 `SetScriptClass()`
- 已绑定类发生变化时,`ScriptEngine` 会停掉旧实例并按新类重新跟踪,这正是运行时重绑定的 canonical 入口
- `SetAssemblyName()` / `SetNamespaceName()` / `SetClassName()` 这些原始 setter 不会触发同样的流程;需要真正重绑定时应走 `SetScriptClass()`
这和商业引擎里常见的“改 Inspector 脚本槽位 = 触发一次受控重绑定”是同一种设计取向。
## 真实行为依据
- `engine/src/Scripting/ScriptComponent.cpp`
- `engine/src/Scripting/ScriptEngine.cpp`
- `tests/Scripting/test_script_engine.cpp`
## 相关文档