Appearance
变换选中物状态源
系统概览
统一「当前选中物」状态源(ADR-171 面板化核心):记录当前面板选中的变换目标 {kind, id},并据全局拖拽开关(transform-mode.ts)联动挂载/卸载 Gizmo。解决此前模型(focusedModelId)、灯光(activeStageLightId)、镜子(无选中态)三套分散状态源无法统一驱动 Gizmo 的问题。
核心职责
- 维护
TransformTarget { kind: ResourceKind; id: string } | null(模块级_selected) setSelectedTransformTarget(target):记录选中并syncDragMode()(面板渲染buildTransformCard时声明)。同 kind+id 重复声明跳过 syncDragMode(避免面板无关重渲染触发独占式 gizmo 重建抖动)clearSelectedTransformTarget():清空选中并detachGizmo()(面板关闭/切换时卸载)syncDragMode():开关关→detachGizmo();开且有选中→若getGizmoTargetId() === _selected.id则跳过重复 attach(防场景点击 setSelected 后 detach+重建闪烁)并清空 pending,否则attachGizmoForKind(kind,id);开但无选中→静默retryPendingAttachment():attachGizmoForKind返回 false(节点未就绪)时记录_pendingRetry,模型加载完成(registerLoadRefreshHook)后补挂。守卫:只要当前已挂任何 gizmo 目标(getGizmoTargetId() !== null,无论是否 pending 本身)即视为达成并放弃重试——retry 唯一目的是「当前无 gizmo 时补挂」,已有目标(场景点击挂载或其他路径)则避免重复 detach+重建闪烁(P2 修复)
对外 API
getSelectedTransformTarget(): TransformTarget | nullsetSelectedTransformTarget(target: TransformTarget)clearSelectedTransformTarget()syncDragMode()retryPendingAttachment()
关键约定
- 类型
TransformTarget:{ kind: ResourceKind; id: string } - 同目标去重:
sameTarget(a,b)比较 kind+id,未变则不重挂 - 卸载双保险(两条通道互补,勿合并):
reconcileTransformSelection()(resource-detail-helpers.ts导出):检测_activeCardEl是否仍挂载于 DOM(isConnected)——仅捕「DOM 移除」场景(面板 pop 回根层 panel 重建)。ESC/closeAllOverlays 只去.visibleclass、DOM 仍挂载,此分支捕不到closeAllOverlays()(ESC / 外部关闭)经addOnCloseAllOverlays注册的无条件清理回调(_activeCardEl = null; clearSelectedTransformTarget())——menu-overlay.ts的_extraCloseAllOverlaysSet 通道(与setOnCloseAllOverlays单回调通道分离,避免与 events.ts 的 import 顺序依赖)
与其他子系统关系
- 依赖
transform-mode.ts(isDragModeEnabled)、transform-adapter.ts(attachGizmoForKind/detachGizmo/getGizmoTargetId)、core/load-manager(ResourceKind) - 被
resource-detail-helpers.tsbuildTransformCard消费(渲染即声明选中);scene-menu.ts拖拽开关 onChange 调syncDragMode() - 被
transform-pick.tstryAttachGizmoFromPick消费:场景点击挂载成功后setSelectedTransformTarget(result)同步选中态(同向依赖,无循环) - 被
model-ops.tsremoveModel消费:删除的正是当前选中物时clearSelectedTransformTarget()(P4 防御) - 场景点击拖拽(
scene.tstryAttachGizmoFromPick,ADR-171)与面板选中走同一attachGizmoForKind,机制并存