Tilemap: Rechteck-Werkzeug legt leere Undo-Schritte an #212

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

Aus #85, Refactoring-Runde 6 (Fund, dort bewusst nicht behoben, weil es eine Verhaltensänderung wäre).

Befund

  • PaintTilesCommand.changes() (src/core/commands/tilemapCommands.ts:60) soll laut Kommentar leere Undo-Schritte verhindern: „Nothing to do when every cell already holds what the stroke would write – no empty undo step.“ Die Methode wird nirgends aufgerufen (gemessen per Grep über src/).
  • Der Pinsel braucht sie nicht: paintCells (src/editor/viewport/SceneViewport.ts) nimmt eine Zelle, die schon die richtige Kachel hat, gar nicht erst in edits auf. Ein Strich ohne Änderung legt deshalb keinen Befehl an.
  • Das Rechteck dagegen baut seine Zellen beim Loslassen aus cellsInRect und reicht sie ungeprüft an PaintTilesCommand weiter (endStroke). Zieht man ein Rechteck über Zellen, die schon genau diese Kachel tragen, entsteht ein Undo-Schritt, der nichts tut. Das Projekt gilt danach auch als geändert.

Zu bauen (Vorschlag)

  • In endStroke vor dem Ausführen PaintTilesCommand.changes(layer, edits) fragen. Ist nichts zu tun, kein Befehl, nur preview().
  • Den Füllen-Pfad (fillFrom) mit demselben Test absichern, falls floodFill je Zellen mit gleicher Kachel liefert.
  • Tests: Unit für den Rechteck-Pfad (Undo-Stapel bleibt gleich lang), e2e in Modul 40 (Rechteck über bereits gemalte Zellen, danach führt Undo den vorherigen Schritt aus).

Offen

Keine Rückfrage. Es ist genau das Verhalten, das der Kommentar an changes() schon verspricht.

Aus #85, Refactoring-Runde 6 (Fund, dort bewusst nicht behoben, weil es eine Verhaltensänderung wäre). ## Befund - `PaintTilesCommand.changes()` (`src/core/commands/tilemapCommands.ts:60`) soll laut Kommentar leere Undo-Schritte verhindern: „Nothing to do when every cell already holds what the stroke would write – no empty undo step.“ **Die Methode wird nirgends aufgerufen** (gemessen per Grep über `src/`). - Der **Pinsel** braucht sie nicht: `paintCells` (`src/editor/viewport/SceneViewport.ts`) nimmt eine Zelle, die schon die richtige Kachel hat, gar nicht erst in `edits` auf. Ein Strich ohne Änderung legt deshalb keinen Befehl an. - Das **Rechteck** dagegen baut seine Zellen beim Loslassen aus `cellsInRect` und reicht sie ungeprüft an `PaintTilesCommand` weiter (`endStroke`). Zieht man ein Rechteck über Zellen, die schon genau diese Kachel tragen, entsteht ein Undo-Schritt, der nichts tut. Das Projekt gilt danach auch als geändert. ## Zu bauen (Vorschlag) - In `endStroke` vor dem Ausführen `PaintTilesCommand.changes(layer, edits)` fragen. Ist nichts zu tun, kein Befehl, nur `preview()`. - Den Füllen-Pfad (`fillFrom`) mit demselben Test absichern, falls `floodFill` je Zellen mit gleicher Kachel liefert. - Tests: Unit für den Rechteck-Pfad (Undo-Stapel bleibt gleich lang), e2e in Modul 40 (Rechteck über bereits gemalte Zellen, danach führt Undo den vorherigen Schritt aus). ## Offen Keine Rückfrage. Es ist genau das Verhalten, das der Kommentar an `changes()` schon verspricht.
meleki added the new label 2026-09-23 07:05:35 +02:00
admin added high-priority and removed new labels 2026-09-23 07:07:11 +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:14:51 +02:00
Author
Owner

Erledigt in 487b3aa.

Was jetzt passiert

Ein Rechteck über Zellen, die schon genau diese Kachel haben, erzeugt keinen Undo-Schritt mehr. Das Projekt gilt danach auch nicht mehr als geändert.

  • Neue Funktion paintTiles() in src/core/commands/tilemapCommands.ts. Sie liefert den Befehl für einen fertigen Strich oder eine Füllung, oder null, wenn sich keine Zelle ändert. Dafür ruft sie PaintTilesCommand.changes() auf, das seit #128 niemand mehr aufgerufen hat.
  • Alle drei Malwege im Scene View laufen darüber: Pinsel/Radierer und Rechteck (in endStroke) und das Füllen (in fillFrom).
  • Beim Füllen gab es den Fehler nicht, weil floodFill bei gleicher Kachel schon [] liefert. Die Absicherung aus dem Vorschlag ist trotzdem drin.
  • Ein Rechteck, das auch nur eine Zelle ändert, bleibt ein normaler Undo-Schritt.

Tests

./check.sh                  → 145 Files, 2190 Tests, CHECK EXIT 0   (vorher 2187)
GM_STEPS=39,40 (Endstand)   → ALL PASSED – 81 checks
npm run build               → BUILD EXIT 0
  • 3 neue Unit-Tests in tests/core/tilemap.test.ts: dasselbe Rechteck zweimal ergibt keinen Befehl (und das eine Undo nimmt das erste zurück), ein breiteres Rechteck bleibt ein Undo-Schritt, eine Füllung ohne Treffer ergibt keinen Befehl.
  • 1 neuer e2e-Check in 40d: dasselbe Rechteck noch einmal, danach muss ein Undo 9 Zellen auf 0 bringen. Ein redo stellt sie für die folgenden Blöcke wieder her.
  • Gegenprobe mit changes(...) || true: in den Unit-Tests fallen genau die zwei „keinen Befehl"-Tests, im Browser genau der neue Check mit {"afterUndo":9}. Original per cmp zurück (IDENTICAL), neu gebaut, 39,40 wieder grün.
  • Check-Summe: CI hat an 0e85856 1312 gemessen. Neu sind 1313, gerechnet.

Doku

Wiki 4d97ec8: Tilemaps sagt, dass ein Strich, ein Rechteck oder eine Füllung ohne Änderung keinen Undo-Schritt anlegt. Development hat die neue Summe.

Erledigt in 487b3aa. ## Was jetzt passiert Ein Rechteck über Zellen, die schon genau diese Kachel haben, erzeugt keinen Undo-Schritt mehr. Das Projekt gilt danach auch nicht mehr als geändert. - **Neue Funktion `paintTiles()`** in `src/core/commands/tilemapCommands.ts`. Sie liefert den Befehl für einen fertigen Strich oder eine Füllung, oder `null`, wenn sich keine Zelle ändert. Dafür ruft sie `PaintTilesCommand.changes()` auf, das seit #128 niemand mehr aufgerufen hat. - **Alle drei Malwege im Scene View laufen darüber:** Pinsel/Radierer und Rechteck (in `endStroke`) und das Füllen (in `fillFrom`). - Beim Füllen gab es den Fehler nicht, weil `floodFill` bei gleicher Kachel schon `[]` liefert. Die Absicherung aus dem Vorschlag ist trotzdem drin. - Ein Rechteck, das auch nur eine Zelle ändert, bleibt ein normaler Undo-Schritt. ## Tests ``` ./check.sh → 145 Files, 2190 Tests, CHECK EXIT 0 (vorher 2187) GM_STEPS=39,40 (Endstand) → ALL PASSED – 81 checks npm run build → BUILD EXIT 0 ``` - **3 neue Unit-Tests** in `tests/core/tilemap.test.ts`: dasselbe Rechteck zweimal ergibt keinen Befehl (und das eine Undo nimmt das erste zurück), ein breiteres Rechteck bleibt ein Undo-Schritt, eine Füllung ohne Treffer ergibt keinen Befehl. - **1 neuer e2e-Check in 40d:** dasselbe Rechteck noch einmal, danach muss ein Undo 9 Zellen auf 0 bringen. Ein `redo` stellt sie für die folgenden Blöcke wieder her. - **Gegenprobe** mit `changes(...) || true`: in den Unit-Tests fallen genau die zwei „keinen Befehl"-Tests, im Browser genau der neue Check mit `{"afterUndo":9}`. Original per `cmp` zurück (`IDENTICAL`), neu gebaut, 39,40 wieder grün. - **Check-Summe:** CI hat an `0e85856` 1312 gemessen. Neu sind 1313, gerechnet. ## Doku Wiki `4d97ec8`: *Tilemaps* sagt, dass ein Strich, ein Rechteck oder eine Füllung ohne Änderung keinen Undo-Schritt anlegt. *Development* hat die neue Summe.
admin moved this to Done in Development on 2026-09-23 09:09:59 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#212