Appearance
加载的统一
背景:加载状态在 core/state、scene、menus 多处重复声明,部分已是加载器不再写入的孤儿;统一加载 Phase 2 需先拔除这些悬空状态。 过程:删除 core/state.ts 孤儿 isLoading* 状态及 setter、scene.ts 悬空导入、motion-camera-levels 未用导入;ADR-046 状态提案→已完成,后续精减文档与修正 load-manager 注释。
序、幽灵信号
联邦的界面上,本该显示"模型加载中"的提示,偶尔却永远停在转圈。
追到源头,是一场关于"谁在加载"的罗生门。
core/state.ts 里住着 isLoadingModel / isLoadingVmd / isLoadingProp 三兄弟,各带一个 setter。它们是旧时代的遗民——加载器早已不再往里写任何东西,可它们还占着状态树的房间,等着一个永远不会来的信。
scene/scene.ts 从 core/state 导入了 isLoadingModel / setIsLoadingModel / isLoadingVmd / setIsLoadingVmd,小心翼翼地搬运着这些空信。
menus/motion-camera-levels.ts 则从 core 导入了一个 loadCameraVmdFromPath,没人调用,像一封寄错地址的信。
这些幽灵信号不报错,不崩溃,只是让"加载中"的真相失真。
一、拔除孤儿
ADR-046 的第一刀,是清理。
core/state.ts 删除 isLoadingModel / isLoadingVmd / isLoadingProp 及其 setter——四个孤儿状态,连同它们的房间一起拆掉。
scene/scene.ts 删除那四个悬空导入。搬空信的邮差,也一并遣散。
menus/motion-camera-levels.ts 删除 loadCameraVmdFromPath 的未使用导入。寄错地址的信,退回来,烧掉。
ADR-046 状态由「提案阶段」改为「已完成」。
死状态比死代码更阴险:它不占运行时,却占着认知,让后来者以为"加载"仍有什么在发生。
二、注释的谎言
清理之后,发现 core/load-manager.ts 的注释还在说谎。
三处过期注释:① 现状还写着"底层锁待移除",而锁已随 ADR-046 移除;② 后续写着"补单测",却没说补什么;③ load() 的文档说"VMD/Audio 返回 null",而所有 kind 现在都返回 handle。
逐字修正。注释不是装饰,是给下一个 AI 外交官的地图——地图上画着已拆除的桥,比没有地图更危险。
代码会过时,注释会撒谎,而读代码的人会相信两者。真相源永远是跑起来的那个,不是写下来的那个。
三、grep 的陷阱
这次清理留下一个教训:删除一对 getter+setter 时,若只 grep \bisLoadingX\b,会漏掉 setIsLoadingX——因为 set 前缀使 \b 词边界失效,正则匹配不到。
正确做法是 grep 共享的 camelCase 子串 IsLoading,把 getter 和 setter 一起捞出来。
npx tsc --noEmit 也坑过一次:经 npx 解析可能绕过项目 tsc 版本,误报通过。应以 npm run check 为准。
工具链的盲区不会提醒你。它只是安静地让你以为干净了。
四、王的净庭
ADR-046 文档精减:删去已完成后的冗余执行章节,新增「后续(已知缺口)」——补 LoadManager 单测、ResourceHandle.id 对 vmd/audio/camera-vmd 暂为空串待填充。
联邦的加载庭院,终于清走了三具幽灵。
王逸盯着不再转圈的提示,心里清楚:那不是加载变快了,是骗子被请走了。
聚合的整洁,是从承认哪些信号早已是空信开始的。
教训:删除状态对时须 grep 共享子串,否则 setter 因词边界漏网。