实现新流程控制和演出调用架构#937
Conversation
# Conflicts: # packages/webgal/src/Core/gameScripts/choose/index.tsx # packages/webgal/src/Core/util/syncWithEditor/syncWithOrigine.ts
There was a problem hiding this comment.
Code Review
This pull request refactors the stage state management by introducing a StageStateManager class to replace the previous Redux-based state management for stage-related data. This change involves migrating state updates, effect management, and perform collection logic to the new manager, improving performance and decoupling state from the UI layer. I have identified a few potential issues: the playVideo function references undefined variables bgmVol and vocalVol in restoreVolumeAndUnmount, the setTimeout in performController.ts could lead to closure issues, and the error handler in playEffect.ts needs to ensure the perform is properly unmounted.
| const restoreVolumeAndUnmount = () => { | ||
| WebGAL.events.fullscreenDbClick.off(skipVideo); | ||
| /** | ||
| * 恢复音量 | ||
| */ | ||
| const bgmElement: any = document.getElementById('currentBgm'); | ||
| if (bgmElement) { | ||
| bgmElement.volume = bgmVol.toString(); | ||
| } | ||
| const vocalElement: any = document.getElementById('currentVocal'); | ||
| if (vocalElement) { | ||
| vocalElement.volume = vocalVol.toString(); | ||
| } | ||
| // eslint-disable-next-line react/no-deprecated | ||
| ReactDOM.render(<div />, document.getElementById('videoContainer')); | ||
| }; |
There was a problem hiding this comment.
| const stopTimeout = setTimeout(() => { | ||
| // perform.stopFunction(); | ||
| // perform.isOver = true; | ||
| if (!perform.isHoldOn) { | ||
| // 如果不是保持演出,清除 | ||
| this.softUnmountPerformObject(perform); | ||
| } | ||
| }, perform.duration); |
There was a problem hiding this comment.
The setTimeout here creates a closure that captures perform. If perform is updated or replaced in the performList before the timeout fires, this could lead to unexpected behavior. It is safer to use the stopTimeoutMap to manage these timeouts and ensure they are cleared correctly when a perform is stopped or unmounted.
| seElement.addEventListener('error', () => { | ||
| logger.error(`播放效果音失败: ${url}`); | ||
| endFunc(); | ||
| }); |
There was a problem hiding this comment.
The error handler for the audio element does not call WebGAL.gameplay.performController.unmountPerform(performInitName) to clean up the perform state when an error occurs, which might leave the perform in an inconsistent state.
| seElement.addEventListener('error', () => { | |
| logger.error(`播放效果音失败: ${url}`); | |
| endFunc(); | |
| }); | |
| seElement.addEventListener('error', () => { | |
| logger.error(`播放效果音失败: ${url}`); | |
| endFunc(); | |
| WebGAL.gameplay.performController.unmountPerform(performInitName); | |
| }); |
# Conflicts: # packages/webgal/src/Core/gameScripts/wait.ts # packages/webgal/src/Stage/MainStage/useSetEffects.ts
Deploying webgal-dev with
|
| Latest commit: |
4cce67f
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://e1a5ec30.webgal-dev.pages.dev |
| Branch Preview URL: | https://refactor-state-mgmt.webgal-dev.pages.dev |
c2a6c96 to
ed9bfd0
Compare
|
测试了 https://github.com/OpenWebGAL/WebGAL/blob/refactor-state-mgmt/packages/webgal/public/game/scene/demo_parallel_animation.txt 脚本,并逐条对话比对通过快速预览模式和正常模式下,抵达同一个对话时,舞台对象的状态。 结论:除了 #938 所属的已有问题外,新内核在一致性上表现良好。并且在快速预览到相当靠后的语句时,再使用回溯来回到某个对话时,舞台对象的状态也正确恢复了,这也意味着,即便不启动演出,状态计算器也在正确的位置计算出了在执行到那条对话时舞台的状态,并保存到 backlog 中。 我们仍需要更多复杂的动画和效果的测试,但是在处理复杂 -parallel 动画时,新内核表现出较强的稳定性。 |
|
也需要测试存读档和状态恢复等。 |
|
除了动画系统,是否可以和音效系统良好配合也很重要,尤其是效果音(循环效果音、后效果音打断前效果音),语音中断体系。 |
# Conflicts: # packages/webgal/package.json # packages/webgal/public/game/template/template.json # packages/webgal/public/webgal-engine.json # packages/webgal/src/Core/Modules/scene.ts # packages/webgal/src/Core/controller/gamePlay/scriptExecutor.ts # packages/webgal/src/Core/gameScripts/vocal/index.ts
本 PR 主要实现新的流程控制和演出调用架构。
该架构将 WebGAL 的舞台与演出系统彻底从 Redux 中剥离,避免状态订阅造成的异步挂载舞台对象导致的动画作用时序问题。同时,也实现了计算状态与舞台状态的剥离,可大幅改善快进和与编辑器联动的快速预览的性能。
关于本 PR 的主要思想,请参考 RFC1:WebGAL 5 流程控制和演出调用草案 中的内容。
除此以外,本 PR 还将演出脚本的实现分为对舞台状态的改变部分和演出调用部分。对舞台状态的改变直接写在演出脚本的实现主函数中,而需要启动的演出则写在返回给演出管理器的
startFunction中。这样就可以实现修改状态和启动演出的分离。在快进模式下或快速预览时,可以跳过大量无需被启动的演出。关于 PR 的主要测试重点:
对于本 PR,有诸多一致性校验的工作要做,但是合并本 PR 将可以彻底解决舞台状态被 Redux 掣肘和快速预览的性能问题,让快速预览功能真正实现“指哪打哪”的流畅效果,收益丰厚。
在本 PR 合并后,WebGAL 将进入 4.6 版本。