Keep drags at full speed in large projects (#394)
Dragging a band of a Filter or a Parametric EQ ran at about 30 fps in a large project. Each frame of a drag announces the changed project, and every listener of that event ran, also those whose work nobody sees while the drag goes on. - FramePreview marks its own frame, read through isDragFrame(). - The Scene view behind another tab skips such a frame and draws on coming back, as it already did while a game runs (#265). - preloadProjectFiles skips it as well. It walks every asset and checks every bake, which costs milliseconds in a large project. - The command that ends a drag emits for itself, and a drag that changes nothing ends with a plain preview, so both catch up then. - This holds for every drag through FramePreview, the knobs of the devices in the graph included. Measured on stein2 with a copy of a project of 162 assets, a band of a Parametric EQ dragged at 250 pointer moves a second for 3 s: - Listeners per frame: 17 ms before, 7.4 ms after. - Hidden Scene view: 814 ms before, 53 ms after. - preloadProjectFiles: 514 ms before, 0.4 ms after. - What is left is mostly the Hierarchy and Assets panels on screen (about 3 and 1.3 ms a frame). They stay as they are. Tests: - Unit frame-preview, play-throttle: 29 passed (1 new) - Counter-check: without the mark the new test fails - e2e 34 (melektaus-atx): ALL PASSED, 136 checks - Gate (melektaus-atx): CHECK EXIT 0, 288 files, 4417 tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3f7eb03143
commit
cb3183227b
4 files changed
+44
-11
No files matched your search
@@ -19,7 +19,7 @@ import type {
|
||||
import { PALETTE_KEY } from '../../src/core/model/pixelart';
|
||||
import { createEmptyProject } from '../../src/core/model/Project';
|
||||
import { CurveCanvas } from '../../src/editor/curve/CurveCanvas';
|
||||
import { FramePreview } from '../../src/editor/framePreview';
|
||||
import { FramePreview, isDragFrame } from '../../src/editor/framePreview';
|
||||
import { GraphDrags } from '../../src/editor/graph/graphDrags';
|
||||
import type { GraphCanvasHost } from '../../src/editor/graph/graphHost';
|
||||
import type { InspectorHost } from '../../src/editor/inspector/host';
|
||||
@@ -89,6 +89,18 @@ describe('FramePreview', () => {
|
||||
expect(state.preview).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('says during its own preview that the event is a drag frame, and at no other time (#394)', () => {
|
||||
const tick = frames();
|
||||
const seen: boolean[] = [];
|
||||
const state = { preview: vi.fn(() => seen.push(isDragFrame())) };
|
||||
new FramePreview(state, 'drag').request();
|
||||
expect(isDragFrame()).toBe(false);
|
||||
tick();
|
||||
state.preview();
|
||||
expect(seen).toEqual([true, false]);
|
||||
expect(isDragFrame()).toBe(false);
|
||||
});
|
||||
|
||||
it('keeps two gestures of the same name apart', () => {
|
||||
const tick = frames();
|
||||
const a = fakeState();
|
||||
|
||||
Reference in new issue
Block a user