3.5 KiB
3.5 KiB
Script 组件分析
组件职责
Script.* 负责:
- 脚本类型注册与脚本实例创建;
script_id生命周期管理;- 脚本逐帧更新;
- 脚本对 Transform 的延迟写回。
核心存储
Script.cpp 的关键结构:
entity_scripts:活跃脚本实例池id_mapping:script_id索引到实例池下标generations + free_ids:脚本 ID 代数与复用队列transform_cache:脚本写变换的缓存数组cache_map:Transform ID 到缓存下标映射
注册机制
脚本工厂注册表:
- 类型:
unordered_map<size_t, script_creator> register_script(tag, func)注册工厂get_script_creator(tag)查询工厂
通常由 REGISTER_SCRIPT 宏在静态初始化阶段完成注册。
创建流程
script::create(init_info, entity):
- 校验实体有效与工厂函数有效;
- 分配
script_id(复用或新建); - 调用工厂创建脚本实例并压入
entity_scripts; - 写入
id_mapping; - 返回
script::component句柄。
删除流程
script::remove(component c):
- 校验组件存在;
- 用无序删除移除脚本实例;
- 修正被交换元素的
id_mapping; - 将被删 id 的映射标记为无效。
更新与缓存提交流程
script::update(dt) 包含两段:
- 遍历
entity_scripts执行每个脚本的update(dt); - 若
transform_cache非空,统一调用transform::update(...)提交后清空。
这使脚本阶段不直接写 Transform 主数组,减少帧内重复写。
脚本写 Transform 的方式
entity_script::set_rotation/position/... 的行为是:
- 先通过
get_cache_ptr(entity)找到该实体缓存槽; - 设置对应
flags; - 写入新值到 cache;
- 等待帧末统一提交。
设计特点
- 句柄安全:
script_id采用 generation 机制; - 批处理友好:Transform 写入集中提交;
- 解耦:脚本逻辑与 Transform 存储细节隔离。
三条主线时序图(注册、生命周期、缓存提交)
sequenceDiagram
autonumber
participant Macro as REGISTER_SCRIPT
participant Detail as script::detail
participant Registry as script_registry
participant Entity as game_entity::entity
participant ScriptSys as script::system
participant Obj as entity_script
participant Cache as transform_cache
participant Trans as transform::system
rect rgb(236, 248, 255)
Note over Macro,Registry: 主线一:脚本类型注册
Macro->>Detail: register_script(tag, creator)
Detail->>Registry: insert(tag, creator)
Registry-->>Detail: creator 已登记
end
rect rgb(239, 252, 240)
Note over Entity,ScriptSys: 主线二:脚本实例生命周期
Entity->>ScriptSys: create(init_info, entity)
ScriptSys->>ScriptSys: 分配或复用 script_id
ScriptSys->>Registry: get_script_creator(tag)
Registry-->>ScriptSys: 返回 creator
ScriptSys->>Obj: creator(entity)
Obj-->>ScriptSys: 生成脚本实例
ScriptSys->>ScriptSys: 写入 entity_scripts 与 id_mapping
ScriptSys-->>Entity: 返回 script::component
Entity->>ScriptSys: remove(component)
ScriptSys->>ScriptSys: erase_unordered + 修正 id_mapping
end
rect rgb(255, 246, 236)
Note over Obj,Trans: 主线三:脚本写变换缓存并帧末提交
ScriptSys->>Obj: update(dt)
Obj->>Cache: set_position/rotation/scale...
Cache-->>Obj: flags + value 已缓存
ScriptSys->>Trans: transform::update(cache, count)
Trans-->>ScriptSys: 写入完成
ScriptSys->>Cache: clear()
end