# 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)