Files
XCEngine/docs/api/XCEngine/Scripting/ScriptComponent/SetScriptClass.md

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)
    • 同时修改程序集名、命名空间和类名。

当前实现行为

两个重载都遵循同一套顺序:

  1. 记录调用前是否已有脚本类绑定。
  2. 计算绑定字符串是否真的发生变化。
  3. 先把新的程序集名 / 命名空间 / 类名写入 ScriptComponent
  4. 如果“之前没有脚本类,设置后有脚本类”,调用 ScriptEngine::Get().OnScriptComponentEnabled(this)
  5. 如果之前已经绑定脚本类,并且绑定字符串发生变化,调用 ScriptEngine::Get().OnScriptComponentClassChanged(this)

关键语义

  • “首次绑定”走的是 OnScriptComponentEnabled() 路径,不是 OnScriptComponentClassChanged()
  • “已绑定后改类”走的是显式重绑定路径。
  • 如果新值和旧值完全相同,当前不会重复通知 ScriptEngine
  • 因为新字符串是先写入再通知引擎,所以运行时收到类切换通知时,ScriptComponent 身上已经是新绑定。

最后这一点很重要。它意味着:

  • 旧托管实例的停机确实会发生。
  • 但如果停机过程里有原生侧日志或调试代码读取 component->GetFullClassName(),读到的会是新类名,而不是旧类名。

设计含义

  • 当前实现把“首次绑定脚本类”视作启用事件。
  • 已绑定类发生变化时,ScriptEngine 会停掉旧实例并按新类重新跟踪,这正是运行时重绑定的 canonical 入口。
  • SetAssemblyName() / SetNamespaceName() / SetClassName() 这些原始 setter 不会触发同样的流程;需要真正重绑定时应走 SetScriptClass()

这和商业引擎里常见的“改 Inspector 脚本槽位 = 触发一次受控重绑定”是同一种设计取向。

真实行为依据

  • engine/src/Scripting/ScriptComponent.cpp
  • engine/src/Scripting/ScriptEngine.cpp
  • tests/Scripting/test_script_engine.cpp

相关文档