fix: 初始化竞态、用户级覆盖语义与死代码(重构四个控制器)
初始化竞态(已实证):旧 changeConfig() 整个函数体都在 if (this.player) 里,含配置赋值, WE 在 window.load 之前下发属性时被静默丢弃,导致背景/音乐已切到新壁纸、立绘还是旧的。 改为「状态先写、应用后置」:index.js 用单一 state 记录(presetId/audioSource/audioVolume), render() 决定能否立刻应用;setConfig() 无条件记录配置,create() 用记下的配置创建。 - 删除 index.js 里重复的 wallpaperRegisterListener(该 API 在本机 WE 不存在) - 删除 adjustCanvas():播放器每帧自己做 renderer.resize(1) 且已注册 resize 监听, 而它用 getBoundingClientRect() 写 canvas.width 却不乘 DPR,属于有害的重复实现 - 用户级音源/音量覆盖:切壁纸不再清回预设默认值(旧 PresetController 的启发式已移除) - 同源设置改为 no-op:否则两档壁纸共用同一首曲子时一切换就从头播放 - 只在壁纸真的变了才重建播放器,否则拖动音量滑块会触发重新下载 3.6MB 骨架+贴图 - 未知 preset id 保持现状并告警,不再静默回退 验证:属性在 DOMContentLoaded 下发时玩家动画正确为 animation(kv37); 用户自定义音源 custom-track.mp3 与音量 0.2 在切壁纸后完整保留; 重发同一预设时音乐从 1.3s 连续到 1.9s 未重启;未知 id 不崩。 对拍:与重构前同强冻结设置 8 批次 6 配置逐像素完全相同(差异 0)。
This commit is contained in:
1 parent
a391021041
commit
4662856963
8 files changed
+1209
-240
No files matched your search
Vendored
+20
-30
@@ -1,35 +1,25 @@
|
||||
// 预设查表:id → 预设数据。
|
||||
// 预设数据是 ES module 里的模块级常量,返回深拷贝,避免调用方改坏它。
|
||||
// 注意 id 必须与 project.json 里 combo 选项的 value 一致(见 docs/adr/0001)。
|
||||
export default class PresetController {
|
||||
constructor(presetStore) {
|
||||
this.presetStore = presetStore;
|
||||
this.previousPreset = "";
|
||||
this.currentPreset = "";
|
||||
constructor(presets) {
|
||||
this.presets = presets;
|
||||
this.currentId = "";
|
||||
}
|
||||
getName() {
|
||||
return Object.keys(this.presetStore);
|
||||
|
||||
get ids() {
|
||||
return Object.keys(this.presets);
|
||||
}
|
||||
set(newPreset, currentAudioSource, currentAudioVolume) {
|
||||
let newPresetData = JSON.parse(JSON.stringify(this.presetStore[newPreset]));
|
||||
if (this.previousPreset) {
|
||||
if (
|
||||
currentAudioSource &&
|
||||
this.presetStore[this.previousPreset].audioOptions.source !==
|
||||
currentAudioSource
|
||||
) {
|
||||
newPresetData.audioOptions.source = currentAudioSource;
|
||||
}
|
||||
if (
|
||||
currentAudioVolume ||
|
||||
(currentAudioVolume === 0 &&
|
||||
this.presetStore[this.previousPreset].audioOptions.volume !==
|
||||
currentAudioVolume)
|
||||
) {
|
||||
newPresetData.audioOptions.volume = currentAudioVolume;
|
||||
}
|
||||
}
|
||||
if (this.currentPreset) {
|
||||
this.previousPreset = this.currentPreset;
|
||||
}
|
||||
this.currentPreset = newPreset;
|
||||
return newPresetData;
|
||||
|
||||
has(id) {
|
||||
return Boolean(this.presets[id]);
|
||||
}
|
||||
|
||||
// 未知 id 返回 null,由调用方决定是保持现状还是回退——不在这里悄悄改成别的预设
|
||||
get(id) {
|
||||
const preset = this.presets[id];
|
||||
if (!preset) return null;
|
||||
this.currentId = id;
|
||||
return JSON.parse(JSON.stringify(preset));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user