Files
XCEngine/docs/api/XCEngine/Scripting/ScriptEngine/OnScriptComponentClassChanged.md

61 lines
2.4 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.
# ScriptEngine::OnScriptComponentClassChanged
**命名空间**: `XCEngine::Scripting`
**类型**: `method`
**头文件**: `XCEngine/Scripting/ScriptEngine.h`
## 签名
```cpp
void OnScriptComponentClassChanged(ScriptComponent* component);
```
## 作用
处理脚本组件在运行时中的类绑定变化。
## 当前实现流程
1. 忽略空指针。
2. 如果运行时未启动,直接返回。
3. 若该组件当前已被跟踪,则先执行 `StopTrackingScript(..., false)`
- 如有实例,会触发 `OnDisable -> OnDestroy -> DestroyScriptInstance`
- 然后从跟踪表移除
4. 如果组件已经没有脚本类,流程结束。
5. 否则按当前组件上的新绑定重新 `TrackScriptComponent()`
6. 若新状态满足 `ShouldScriptRun()`,立即 `EnsureScriptReady(..., true)`,从而创建新实例并触发 `Awake / OnEnable`
## 关键语义
- `ScriptComponent::SetScriptClass()` / `ClearScriptClass()` 是先写入组件上的新绑定,再调用这里。因此这个方法执行时,`component` 身上已经是“新类名”或“清空后的类名”。
- 这意味着“停掉旧实例”和“读取组件当前绑定字符串”是两件不同的事:
- 停掉的是旧托管实例
- 但如果此时有人通过 `component->GetFullClassName()` 看组件数据,看到的会是新绑定或空绑定
- 如果清空绑定,方法会只执行停机和移除跟踪,不会重新创建状态。
- 如果新绑定仍存在,但运行时后续无法创建新实例,这个方法不会回滚组件上的新绑定;组件会保留新类信息,只是当前没有活体实例。
## 使用场景
`ScriptComponent::SetScriptClass()` 在已绑定类发生变化时会调用这里;`ClearScriptClass()` 也会走同一条停机路径。
## 设计意义
商业引擎里脚本类切换通常都不是“裸改字段”,而是“显式重绑定动作”。当前实现把这条链路收口到 `ScriptEngine`,好处是:
- 生命周期停机顺序固定。
- 跟踪表和实例缓存不会漏清。
- 后续即便更换脚本后端,类切换的上层语义也能保持一致。
## 真实行为依据
- `engine/src/Scripting/ScriptEngine.cpp`
- `engine/src/Scripting/ScriptComponent.cpp`
- `tests/Scripting/test_script_engine.cpp`
## 相关文档
- [OnScriptComponentEnabled](OnScriptComponentEnabled.md)
- [ScriptComponent::SetScriptClass](../ScriptComponent/SetScriptClass.md)