Container: Objekt im Template löschen lässt Verweise in anderen Szenen stehen #269

Closed
opened 2026-09-29 18:26:29 +02:00 by meleki · 2 comments
Owner

Aus #258 („Deleting a template object in the container editor does not clean up references in other scenes.“, dort unter Not done).

Befund

  • Seit #258 zeigt eine Object-Variable (auch ein Object-Feld oder Object-Item) auf ein Objekt derselben Szene, gespeichert als {"$object": "<id>"}. Inhalt eines platzierten Containers bekommt nur Objekte desselben Containers zur Wahl. Die Wahl steht in den instanceEdits der Platzierung, also in der Szene, nicht im Template.
  • RemoveSceneObjectsCommand (src/core/commands/sceneObjectCommands.ts:119) leert beim Löschen nur die Verweise im selben Holder: swapReferences(holder.objects, …) in Zeile 124.
  • Löscht man im Container-Tab ein Template-Objekt, bleiben die Verweise darauf in den instanceEdits jeder Platzierung stehen, in allen Szenen und in anderen Container-Templates.
  • Folge: Der Inspector der Platzierung zeigt (missing), im Spiel liest sich der Wert als null, und der tote Verweis bleibt in der Projektdatei. In der eigenen Szene fällt derselbe Verweis dagegen im selben Undo-Schritt weg, wie in #258 vereinbart.

Zu bauen (Vorschlag)

  • Beim Löschen in einem Container-Template zusätzlich alle Platzierungen dieses Containers im Projekt durchgehen (Szenen und andere Templates, auch verschachtelt) und dort die Verweise auf die gelöschten Ids leeren. Das läuft über denselben Recorder, damit ein Undo alles zurückbringt.
  • Die Suche nach den Platzierungen als reine Funktion neben swapReferences in src/core/model/objectRefs.ts.
  • Tests: Unit mit einem Container, der in zwei Szenen platziert ist und dort je einen Verweis trägt. Löschen leert beide, Undo stellt beide wieder her. e2e im Container-Tab (Modul 57 baut die Verweise schon auf): Template-Objekt löschen, danach zeigt die Platzierung None statt (missing).

Offen (mit Vorschlag)

  1. Verweise, die schon tot in Projekten stehen? Vorschlag: keine Migration. Sie lesen sich weiter als (missing) und verschwinden beim nächsten Setzen.
Aus #258 („Deleting a template object in the container editor does not clean up references in other scenes.“, dort unter *Not done*). ## Befund - Seit #258 zeigt eine Object-Variable (auch ein Object-Feld oder Object-Item) auf ein Objekt derselben Szene, gespeichert als `{"$object": "<id>"}`. Inhalt eines platzierten Containers bekommt nur Objekte desselben Containers zur Wahl. Die Wahl steht in den `instanceEdits` der Platzierung, also in der Szene, nicht im Template. - `RemoveSceneObjectsCommand` (`src/core/commands/sceneObjectCommands.ts:119`) leert beim Löschen nur die Verweise im selben Holder: `swapReferences(holder.objects, …)` in Zeile 124. - Löscht man im Container-Tab ein Template-Objekt, bleiben die Verweise darauf in den `instanceEdits` jeder Platzierung stehen, in allen Szenen und in anderen Container-Templates. - Folge: Der Inspector der Platzierung zeigt `(missing)`, im Spiel liest sich der Wert als `null`, und der tote Verweis bleibt in der Projektdatei. In der eigenen Szene fällt derselbe Verweis dagegen im selben Undo-Schritt weg, wie in #258 vereinbart. ## Zu bauen (Vorschlag) - Beim Löschen in einem Container-Template zusätzlich alle Platzierungen dieses Containers im Projekt durchgehen (Szenen und andere Templates, auch verschachtelt) und dort die Verweise auf die gelöschten Ids leeren. Das läuft über denselben `Recorder`, damit ein Undo alles zurückbringt. - Die Suche nach den Platzierungen als reine Funktion neben `swapReferences` in `src/core/model/objectRefs.ts`. - Tests: Unit mit einem Container, der in zwei Szenen platziert ist und dort je einen Verweis trägt. Löschen leert beide, Undo stellt beide wieder her. e2e im Container-Tab (Modul 57 baut die Verweise schon auf): Template-Objekt löschen, danach zeigt die Platzierung `None` statt `(missing)`. ## Offen (mit Vorschlag) 1. **Verweise, die schon tot in Projekten stehen?** Vorschlag: keine Migration. Sie lesen sich weiter als `(missing)` und verschwinden beim nächsten Setzen.
meleki added the new label 2026-09-29 18:26:29 +02:00

vorschlag passt

vorschlag passt
admin removed the new label 2026-09-29 18:41:31 +02:00
admin added this to the Development project 2026-09-29 18:41:33 +02:00
admin moved this to Next in Development on 2026-09-29 18:41:38 +02:00
Author
Owner

Done in 214218d, wiki 06fd1ec (Behaviors, Containers, Development).

What changes

  • Deleting a template object in a container tab now clears every reference to it, in the same undo step:
    • in the template itself (as before)
    • in the instanceEdits of every placement, in all scenes and in other container templates, nested ones included
    • on objects outside a placement that name its copy by full id (p~crate)
  • The row then shows None instead of (missing). One undo brings all references back.
  • References that were already dead in saved projects stay untouched, as agreed. They go away the next time the value is set.

Different from the proposal

  • Instead of searching for placements, the command compares which objects every holder shows before and after the delete (shownObjectIds and dropReferencesToGone in src/core/model/objectRefs.ts). A reference is resolved from its own place with referenceCandidates, the same way the runtime does. One rule covers all cases, nested placements too, and it also applies when a whole container placement is deleted in a scene.
  • A cleared instance edit is dropped when it now says the same as the template, so the placement follows the template again. That only happens when the template has its own value there. It is the same rule as in the setter and in deviatesFromTemplate, which compare overrides on purpose, not effective values.
  • When the template has no own value, a marked None stays, yellow and with Reset, just as if None had been picked by hand. Reset hands the row back to the template.
  • When the template points somewhere else, the placement stays at None. It does not jump silently to the template's value.

Tests

unit object-references (melektaus-atx)  17 passed (13 + 4)
gate (melektaus-atx)                    198 files, 2873 tests, CHECK EXIT 0 (2869 + 4)
e2e 1-17,57                             ALL PASSED - 564 checks (57 has 13, +1 for 57h)
  • 57h deletes the crate in the container tab with the real Delete key. Before, the row shows Crate 57. After, it shows None without (missing), and undo brings the reference back.

  • Counter-checks work, each bent on its own in a container copy:

    Bent Failing tests
    raw ids only 3
    scenes skipped 5
    no undo 4
    clear everything named 3
    edit not cleaned up 1
  • The browser counter-check works too: 57h then fails with exactly the picture from this issue, (missing) and the reference still in place.

  • Screenshot checked: under "Box 57" only Aim 57 is left, target shows None.

  • The e2e total of 1607 is computed (1606 + 1). CI is still switched off, so there is no run for 214218d.

Found on the way, not fixed here

  • #285: a reference from a container into a nested placement is stored as q~<id>, but the copy is named r~q/<id> in every placement. That reference is dead from the start.
  • #286: Delete asset removes placed objects by cascade but does not clear references to them.
Done in `214218d`, wiki `06fd1ec` (*Behaviors*, *Containers*, *Development*). **What changes** - Deleting a template object in a container tab now clears every reference to it, in the same undo step: - in the template itself (as before) - in the `instanceEdits` of every placement, in all scenes and in other container templates, nested ones included - on objects outside a placement that name its copy by full id (`p~crate`) - The row then shows **None** instead of `(missing)`. One undo brings all references back. - References that were already dead in saved projects stay untouched, as agreed. They go away the next time the value is set. **Different from the proposal** - Instead of searching for placements, the command compares which objects every holder shows before and after the delete (`shownObjectIds` and `dropReferencesToGone` in `src/core/model/objectRefs.ts`). A reference is resolved from its own place with `referenceCandidates`, the same way the runtime does. One rule covers all cases, nested placements too, and it also applies when a whole container placement is deleted in a scene. - A cleared instance edit is dropped when it now says the same as the template, so the placement follows the template again. That only happens when the template has its own value there. It is the same rule as in the setter and in `deviatesFromTemplate`, which compare overrides on purpose, not effective values. - **When the template has no own value, a marked None stays**, yellow and with Reset, just as if None had been picked by hand. Reset hands the row back to the template. - When the template points somewhere else, the placement stays at None. It does not jump silently to the template's value. **Tests** ``` unit object-references (melektaus-atx) 17 passed (13 + 4) gate (melektaus-atx) 198 files, 2873 tests, CHECK EXIT 0 (2869 + 4) e2e 1-17,57 ALL PASSED - 564 checks (57 has 13, +1 for 57h) ``` - **57h** deletes the crate in the container tab with the real Delete key. Before, the row shows `Crate 57`. After, it shows `None` without `(missing)`, and undo brings the reference back. - Counter-checks work, each bent on its own in a container copy: | Bent | Failing tests | |---|---| | raw ids only | 3 | | scenes skipped | 5 | | no undo | 4 | | clear everything named | 3 | | edit not cleaned up | 1 | - The browser counter-check works too: 57h then fails with exactly the picture from this issue, `(missing)` and the reference still in place. - Screenshot checked: under "Box 57" only Aim 57 is left, *target* shows None. - The e2e total of 1607 is computed (1606 + 1). CI is still switched off, so there is no run for `214218d`. **Found on the way, not fixed here** - #285: a reference from a container into a nested placement is stored as `q~<id>`, but the copy is named `r~q/<id>` in every placement. That reference is dead from the start. - #286: *Delete asset* removes placed objects by cascade but does not clear references to them.
admin moved this to Done in Development on 2026-09-30 22:38:51 +02:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#269