Skip to content

feat: 增强编辑器预览 transform 查询协议与 overlay reference box 能力#991

Open
A-kirami wants to merge 12 commits into
OpenWebGAL:devfrom
A-kirami:feat/editor-preview-transform-queries
Open

feat: 增强编辑器预览 transform 查询协议与 overlay reference box 能力#991
A-kirami wants to merge 12 commits into
OpenWebGAL:devfrom
A-kirami:feat/editor-preview-transform-queries

Conversation

@A-kirami

@A-kirami A-kirami commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

背景

这次改动的核心目标,是给编辑器的拖拽变换系统提供稳定、可信的运行时信息,避免编辑器自己去猜目标对象的几何和 transform 继承结果。

在拖拽、缩放、旋转这类交互里,编辑器真正需要的是:

  • target 的 reference box
  • 当前 runtime 的 base transform
  • target 在当前编辑语句执行前的 transform baseline

如果这些信息不由引擎明确提供,编辑器就只能从快照、当前舞台状态或本地默认值里间接推断,结果容易出现几何不准、继承错误、双重应用 transform、以及动画中间态误导编辑的问题。

在此基础上,这次还补充解决了另一个性能和语义问题:preview.command.set-effect 在拖拽预览期间本质上是高频 hot path,但旧实现会把每一帧预览都当作完整的 stage mutation 处理,走 full commit、snapshot、订阅通知等整条链路。这样不仅会放大主线程和通信压力,也会把本应是 transient 的预览态写进 runtime state。

因此,这次 PR 也把 set-effect 预览明确建模为“仅更新可见 Pixi 状态的 preview phase”,把最终 durable 更新留到确认提交时执行。

主要改动

1. 扩展编辑器预览同步协议

新增以下查询能力:

  • preview.query.reference-box
  • preview.query.base-transform
  • preview.query.transform-baseline

同时扩展 preview.command.sync-scene,增加:

  • settleMode?: 'normal' | 'immediate'
  • transformBaselineRevision?: string

另外补充了通用 preview request error envelope,用于统一表达非法请求、未知请求类型和运行时内部失败。

除此之外,preview.command.set-effect 现在增加了:

  • phase?: 'preview' | 'commit'

语义上:

  • phase: 'preview' 表示仅做 transient visual preview
  • phase: 'commit' 表示执行最终的 durable runtime state update
  • 缺省不传时仍按原有 commit 行为处理,保持兼容

2. 给拖拽变换系统提供 reference box 查询

  • PixiStage 增加 queryTargetReferenceBox()waitForTargetReferenceBox()
  • 新增 referenceBoxQueryHandler
  • WebGALPixiContainer 增加基础原点和 local bounds 查询能力
  • 在背景、立绘、Live2D 等对象挂载/移除后通知 reference box 已变化

这部分的目标是让编辑器拿到 target 的稳定 reference geometry,而不是去读取资源的尺寸。

当目标资源尚未稳定挂载时,查询会先返回 loading,并在短时间内等待一次几何就绪后再返回结果,避免过早回复不可信数据。

3. 给拖拽变换系统提供 transform baseline 查询

  • 新增 current runtime baseTransform 查询
  • 新增 target transform baseline 查询
  • 引入 latest-only 的 baseline revision/snapshot 管理
  • set-effect 的 preview baseline 改为基于 baseTransform + baseline override 计算

这部分解决的是“空字段该继承什么”的问题。编辑器不再需要从当前 mutable stage 或快照里猜 target 的继承值,而是直接消费 runtime 提供的基线结果。

4. 支持 effect editor 的 settled 编辑态同步

  • sync-scene 支持 settleMode
  • settleMode: 'immediate' 会让 preview 尽快进入可编辑的 settled 状态
  • fast preview 链路新增目标语句执行前回调,用于精确捕获 baseline snapshot
  • forward / scriptExecutor 增加执行前钩子,确保 snapshot 捕获点正确

这部分主要是避免编辑器在动画中间态上做拖拽编辑,否则画面位置和编辑器数值会对不上。

5. 为 set-effect 拖拽预览引入 preview-phase hot path

  • 抽取共享的 Pixi transform 应用 helper,统一 preview path 和 commit path 的 transform 转换语义
  • applyStageEffects() 改为复用共享 helper,避免两条路径在 position / scale / alpha 等字段上出现分叉
  • 新增 target-only 的 applyStageEffectToTarget(),只更新指定 target 的可见 Pixi container
  • previewSyncRuntime 处理 set-effect 时,仍先基于 session baseline 合成最终 transform,并保持“先停止目标动画”的既有可见语义
  • phase === 'preview' 时,只对当前 target 做 Pixi transform 更新并请求 render,不再走 full stage commit
  • phase === 'commit' 或未传 phase 时,仍沿用原有 updateEffectAndCommit() 路径,执行最终一次 durable commit

这部分的核心收益是:

  • 拖拽中的每一帧预览不再 clone 整个 stage state
  • 不再把 transient preview 写入 runtime stage state
  • 不再为每一帧预览触发 snapshot 发布、React notify、autosave 等完整 commit 副作用
  • 最终确认时仍保留一次完整 commit,使 runtime state 和最终可见结果收敛

结果

这次改动之后,编辑器拖拽变换系统可以直接从预览 runtime 获取:

  • target 的 reference box
  • runtime canonical baseTransform
  • target 的 transform baseline

同时,set-effect 的高频拖拽预览也被拆分成了明确的 preview / commit 两个阶段:

  • 拖拽中的预览只更新目标可见 Pixi transform
  • 鼠标松手或确认操作时,再执行一次最终 commit
  • preview path 和 commit path 复用同一套 transform 应用规则,减少语义漂移

也就是说,编辑器不需要再自己猜:

  • 几何锚点在哪里
  • 当前对象的基础尺寸是多少
  • 空字段应该继承哪个 transform
  • 当前看到的是不是动画中间态
  • 拖拽中的中间值是否已经被 durable 地写入 runtime state

这样可以把拖拽、缩放、旋转、实时预览和最终保存建立在同一套 runtime 真相源上,同时减少偏移、漂移、错误继承,以及拖拽期间不必要的快照和提交开销。

影响范围

主要涉及:

  • 编辑器预览协议定义
  • preview sync runtime 请求分发
  • set-effect 的 preview / commit phase 语义
  • sync-scene settled 同步链路
  • target transform baseline snapshot 管理
  • Pixi reference box 几何计算与等待机制
  • Pixi stage 的 target-only effect apply 和共享 transform helper

验证建议

建议合并前重点验证:

  • 打开 setTransform 编辑器时,空字段能正确拿到 inherited baseline
  • writeDefault=true 时只使用 baseTransform
  • setTransform 编辑器进入 settled 编辑态,但不会错误继承 target runtime transform
  • preview.query.reference-box 对常见 target 返回正确状态和几何
  • 资源未挂载时先返回 loading,就绪后能得到 ready
  • 拖拽 / 缩放 / 旋转时不会出现双重应用 transform 导致的漂移
  • preview.command.set-effect 未传 phase 时保持旧 commit 行为
  • phase: 'preview' 时只更新当前 target 的可见 transform,不触发完整 stage commit
  • phase: 'preview' 期间不会发布拖拽中的 stage.snapshot.updated,也不会触发 autosave 等完整 commit 副作用
  • 连续 preview 后执行一次 final commit,最终 stage state 与可见结果一致
  • target 不存在或尚未加载时,preview 会 no-op accepted,不污染 stage state,也不阻塞后续 commit
  • 旧 revision、runtime reset、run-scene-contentrun-snippet 后,baseline query 会正确返回 unavailable
  • 非法请求、未知请求类型和 handler 内部异常会返回通用 error envelope

风险与兼容性

  • 这是一次协议扩展,编辑器侧需要按新的 query、sync-scene 字段以及 set-effect phase 语义消费
  • transform baseline 采用 latest-only revision 语义,旧 revision 不保证可查询
  • request error envelope 改变了运行时对非法/未知请求的反馈方式,调用方需要按 error envelope 处理
  • 对不支持 phase 的旧 runtime,set-effect 会退化回原有 commit path:功能仍可用,但不会获得 preview-phase 的副作用抑制和性能收益
  • preview phase 会直接更新可见 Pixi 状态,因此在最终 commit 或重新同步之前,runtime durable state 与可见 preview state 可能短暂不一致;这是这条优化链路的预期语义,需要由 final commit 或 resync 收敛

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors and extends the editor preview protocol and runtime. It introduces a unified Transform type, adds support for querying and waiting on target reference boxes in the Pixi stage, and implements a transform baseline manager to track and override baseline transforms during fast preview syncs. Additionally, the script executor is updated to support execution callbacks. The review feedback highlights an issue in getChildReferenceBounds where rotation and shear are ignored during bounds calculation, which can cause incorrect reference boxes for rotated elements, and suggests using matrix multiplication to transform the bounds' corners.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant