Editor: Ziehen in Scene, Texture und Graph pro Frame statt pro Mausbewegung auswerten #213

Closed
opened 2026-09-23 07:05:35 +02:00 by meleki · 2 comments
Owner

Aus #129, Etappe 3 („Nicht angefasst: Szenen-Viewport, Texture-Tab und Graph rufen preview() genauso im Move-Handler und haben dieselbe Kostenstelle.“).

Befund

  • state.preview() (src/editor/state.ts:368) feuert emit('project'). Daran hängt die ganze Editor-Kette: Play-Sync, Invalidieren des Editor-Runs, alle Dokumente und Panels, das Neurastern erzeugter Bilder.
  • Im Vector-Art-Tab war genau das der Grund, warum ein gezogener Punkt der Maus hinterherhinkte. Gemessen bei 125 Hz Mausrate und 120 Objekten in der Szene: 36 ms je Move-Event, 120 Moves dauerten 4173 ms statt 960 ms. Mit onFrame (src/ui/render.ts:52) waren es danach 3 ms. Pixel Art nutzt onFrame inzwischen auch.
  • Dieselbe Stelle, noch ohne onFrame, bei jedem pointermove:
    • Objekte ziehen im Scene View (src/editor/viewport/SceneViewport.ts:348)
    • Frames und Slices ziehen im Texture-Tab (src/editor/texture/TextureCanvas.ts:427)
    • Nodes und Rahmen ziehen im Graph (src/editor/graph/GraphCanvas.ts:422)
  • Gemeldet ist hier noch nichts. Bei großen Szenen ist aber derselbe Rückstau zu erwarten, der im Vector-Art-Tab aufgefallen ist.

Zu bauen (Vorschlag)

  • Erst messen: Das Wegwerf-Modul aus #129 (120 Moves im 8-ms-Takt) gegen Scene View, Texture-Tab und Graph fahren, mit 0, 40 und 120 Objekten bzw. Nodes.
  • Wo es sich zeigt: Der Move-Handler schreibt weiter sofort ins Modell, preview() läuft aber über onFrame(key, …) einmal pro Frame. Beim Loslassen cancelFrameWork und das Kommando wie heute.
  • Tests: Unit, dass mehrere Moves in einem Frame ein einziges preview() auslösen. Der Geschwindigkeitsbeleg ist die Node-Messung, kein Zeitcheck im Browser (unter CI-Last wackelig, wie bei #129).

Offen (mit Vorschlag)

  1. Nur, wo die Messung einen Rückstau zeigt, oder überall gleich? Vorschlag: überall gleich, dann ist es ein Muster und keine Ausnahme.
Aus #129, Etappe 3 („Nicht angefasst: Szenen-Viewport, Texture-Tab und Graph rufen `preview()` genauso im Move-Handler und haben dieselbe Kostenstelle.“). ## Befund - `state.preview()` (`src/editor/state.ts:368`) feuert `emit('project')`. Daran hängt die ganze Editor-Kette: Play-Sync, Invalidieren des Editor-Runs, alle Dokumente und Panels, das Neurastern erzeugter Bilder. - Im Vector-Art-Tab war genau das der Grund, warum ein gezogener Punkt der Maus hinterherhinkte. Gemessen bei 125 Hz Mausrate und 120 Objekten in der Szene: **36 ms je Move-Event**, 120 Moves dauerten 4173 ms statt 960 ms. Mit `onFrame` (`src/ui/render.ts:52`) waren es danach **3 ms**. Pixel Art nutzt `onFrame` inzwischen auch. - Dieselbe Stelle, noch ohne `onFrame`, bei jedem `pointermove`: - Objekte ziehen im Scene View (`src/editor/viewport/SceneViewport.ts:348`) - Frames und Slices ziehen im Texture-Tab (`src/editor/texture/TextureCanvas.ts:427`) - Nodes und Rahmen ziehen im Graph (`src/editor/graph/GraphCanvas.ts:422`) - Gemeldet ist hier noch nichts. Bei großen Szenen ist aber derselbe Rückstau zu erwarten, der im Vector-Art-Tab aufgefallen ist. ## Zu bauen (Vorschlag) - Erst **messen**: Das Wegwerf-Modul aus #129 (120 Moves im 8-ms-Takt) gegen Scene View, Texture-Tab und Graph fahren, mit 0, 40 und 120 Objekten bzw. Nodes. - Wo es sich zeigt: Der Move-Handler schreibt weiter sofort ins Modell, `preview()` läuft aber über `onFrame(key, …)` einmal pro Frame. Beim Loslassen `cancelFrameWork` und das Kommando wie heute. - Tests: Unit, dass mehrere Moves in einem Frame ein einziges `preview()` auslösen. Der Geschwindigkeitsbeleg ist die Node-Messung, kein Zeitcheck im Browser (unter CI-Last wackelig, wie bei #129). ## Offen (mit Vorschlag) 1. **Nur, wo die Messung einen Rückstau zeigt, oder überall gleich?** Vorschlag: überall gleich, dann ist es ein Muster und keine Ausnahme.
meleki added the new label 2026-09-23 07:05:35 +02:00

vorschlag passt

vorschlag passt
admin removed the new label 2026-09-23 07:07:38 +02:00
admin added this to the Development project 2026-09-23 07:14:43 +02:00
admin moved this to Next in Development on 2026-09-23 07:15:03 +02:00
Author
Owner

Erledigt in 30fb3a2, wie im Kommentar besprochen überall gleich, als ein Muster.

Umbau

  • Neuer Baustein FramePreview (src/editor/framePreview.ts): request() im Move-Handler, cancel() beim Loslassen. Das Modell wird weiter bei jeder Bewegung geschrieben, nur state.preview() wartet auf den nächsten Frame.
  • Umgestellt: Scene View (Objekte ziehen, Polygon-Ecken, Tilemap-Striche), Texture-Tab (Frames, Slice-Kanten, Kollisionsecken), Graph (Nodes, Gruppen, Kommentare über GraphDrags, damit auch State Machine, Shader und Partikel).
  • Vector Art bleibt, wie es seit #129 ist.

Messung (Wegwerf-Sonde, 120 Moves im 8-ms-Takt)

Zusatzobjekte Scene Texture Graph
0 15,6 → 13,6 ms/Move 17,0 → 12,8 16,3 → 14,5
40 18,8 → 16,4 22,8 → 14,4 17,8 → 15,1
120 26,2 → 18,5 34,2 → 17,9 28,8 → 17,0

Bei 120 Objekten sanken die project-Events von 120/232/119 auf 48/48/41. In den Zahlen steckt auch der CDP-Umlauf der Sonde selbst.

Befund

Der Texture-Tab hat bisher doppelt gezahlt (232 Events für 120 Moves): Pixi schickt 4 bis 8 ms nach jeder echten Bewegung dasselbe Pointer-Event noch einmal als Hover-Update. Mit dem Umbau fällt das in denselben Frame und kostet nichts mehr.

Tests

  • ./check.sh: 147 Dateien, 2204 Tests, grün (vorher 146 / 2199).
  • 5 neue Unit-Tests in tests/editor/frame-preview.test.ts, einer davon mit den echten GraphDrags. Drei Gegenproben greifen je am erwarteten Test.
  • e2e 1-16,29,31,36,37,39-43: 708 Checks grün, 1-16,26,28: 634 Checks grün.
  • Kein neuer e2e-Check, die Check-Summe bleibt 1314.

Nicht angefasst

Das Scrubben im Inspector und das Ziehen der Farbstopps im GradientBar lösen preview() weiter bei jeder Eingabe aus. Beide liegen außerhalb der drei Leinwände. Mit FramePreview wäre es je eine Zeile, falls gewünscht.

Wiki: Architecture ergänzt (314c09e).

Erledigt in `30fb3a2`, wie im Kommentar besprochen überall gleich, als ein Muster. ## Umbau - Neuer Baustein **`FramePreview`** (`src/editor/framePreview.ts`): `request()` im Move-Handler, `cancel()` beim Loslassen. Das Modell wird weiter bei jeder Bewegung geschrieben, nur `state.preview()` wartet auf den nächsten Frame. - Umgestellt: Scene View (Objekte ziehen, Polygon-Ecken, Tilemap-Striche), Texture-Tab (Frames, Slice-Kanten, Kollisionsecken), Graph (Nodes, Gruppen, Kommentare über `GraphDrags`, damit auch State Machine, Shader und Partikel). - Vector Art bleibt, wie es seit #129 ist. ## Messung (Wegwerf-Sonde, 120 Moves im 8-ms-Takt) | Zusatzobjekte | Scene | Texture | Graph | |---|---|---|---| | 0 | 15,6 → 13,6 ms/Move | 17,0 → 12,8 | 16,3 → 14,5 | | 40 | 18,8 → 16,4 | 22,8 → 14,4 | 17,8 → 15,1 | | 120 | 26,2 → 18,5 | 34,2 → 17,9 | 28,8 → 17,0 | Bei 120 Objekten sanken die `project`-Events von 120/232/119 auf 48/48/41. In den Zahlen steckt auch der CDP-Umlauf der Sonde selbst. ## Befund Der Texture-Tab hat bisher doppelt gezahlt (232 Events für 120 Moves): Pixi schickt 4 bis 8 ms nach jeder echten Bewegung dasselbe Pointer-Event noch einmal als Hover-Update. Mit dem Umbau fällt das in denselben Frame und kostet nichts mehr. ## Tests - `./check.sh`: 147 Dateien, 2204 Tests, grün (vorher 146 / 2199). - 5 neue Unit-Tests in `tests/editor/frame-preview.test.ts`, einer davon mit den echten `GraphDrags`. Drei Gegenproben greifen je am erwarteten Test. - e2e `1-16,29,31,36,37,39-43`: 708 Checks grün, `1-16,26,28`: 634 Checks grün. - Kein neuer e2e-Check, die Check-Summe bleibt 1314. ## Nicht angefasst Das Scrubben im Inspector und das Ziehen der Farbstopps im `GradientBar` lösen `preview()` weiter bei jeder Eingabe aus. Beide liegen außerhalb der drei Leinwände. Mit `FramePreview` wäre es je eine Zeile, falls gewünscht. Wiki: *Architecture* ergänzt (`314c09e`).
admin moved this to Done in Development on 2026-09-23 12:43:57 +02:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#213