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