fix(editor): possible race condition in viewport clipping (#12503)

This commit is contained in:
Yifeng Wang
2025-05-26 17:08:31 +08:00
committed by GitHub
parent 051dc4296d
commit 9d2330fc2b

View File

@@ -70,32 +70,36 @@ export class GfxViewportElement extends WithDisposable(ShadowlessElement) {
if (!this.host) return; if (!this.host) return;
const gfx = this.host.std.get(GfxControllerIdentifier); const gfx = this.host.std.get(GfxControllerIdentifier);
const nextVisibleModels = new Set([ const currentViewportModels = this.getModelsInViewport();
...this.getModelsInViewport(), const currentSelectedModels = this._getSelectedModels();
...this._getSelectedModels(), const shouldBeVisible = new Set([
...currentViewportModels,
...currentSelectedModels,
]); ]);
batch(() => { const previousVisible = this._lastVisibleModels
nextVisibleModels.forEach(model => { ? new Set(this._lastVisibleModels)
const view = gfx.view.get(model); : new Set<GfxBlockElementModel>();
if (isGfxBlockComponent(view)) {
view.transformState$.value = 'active';
}
if (this._lastVisibleModels?.has(model)) { batch(() => {
this._lastVisibleModels!.delete(model); // Step 1: Activate all the blocks that should be visible
} shouldBeVisible.forEach(model => {
const view = gfx.view.get(model);
if (!isGfxBlockComponent(view)) return;
view.transformState$.value = 'active';
}); });
this._lastVisibleModels?.forEach(model => { // Step 2: Hide all the blocks that should not be visible
previousVisible.forEach(model => {
if (shouldBeVisible.has(model)) return;
const view = gfx.view.get(model); const view = gfx.view.get(model);
if (isGfxBlockComponent(view)) { if (!isGfxBlockComponent(view)) return;
view.transformState$.value = 'idle'; view.transformState$.value = 'idle';
}
}); });
}); });
this._lastVisibleModels = nextVisibleModels; this._lastVisibleModels = shouldBeVisible;
}; };
private _lastVisibleModels?: Set<GfxBlockElementModel>; private _lastVisibleModels?: Set<GfxBlockElementModel>;