Struct und listen restposten #24

Closed
opened 2026-09-12 15:03:54 +02:00 by admin · 0 comments

Restposten aus dynamischen Ports / Structs

Drei Punkte, die beim Bau von List-Tab und Struct-Variablen bewusst liegen geblieben sind. Sie
standen am Ende von done/nodes-mit-dynamischer-port-zahl.md und sind hierher gezogen, damit sie
nicht mit der erledigten Notiz verschwinden.

Alle drei sind gebaut — dazu der Nebenpunkt, der beim Bauen aufgefallen war.

1. Der unverbundene Eingang zeigt das falsche Feld — ERLEDIGT

inlineInputDef (NodeRegistry.ts:131) kannte nur boolean, string/any und alles andere —
und "alles andere" wurde ein Zahlenfeld.

Beim Nachmessen war der Restposten kleiner als die Notiz behauptete: object und struct
kommen gar nicht mehr an inlineInputDef vorbei, inlineInputs siebt sie schon aus (mit der
Begründung, die die Notiz für object verlangt hat: ein Objekt ist ein lebendes Handle, ein
Struct wird aus Teilen gebaut). Offen war nur list — und dort ist es genau die Antwort geworden,
die die Notiz vorgezeichnet hat: der Knopf n items plus List-Tab.

Zwei Dinge, die dabei zu entscheiden waren:

  • Die Item-Art ist number. Kein Port deklariert eine — und das ist derselbe Vorgabewert, den
    + Variable ▸ List setzt. Der Graph typisiert eine Liste ohnehin nur als Liste.
  • Ein verbundener Port löst nicht mehr auf. Sobald eine Kante den Eingang speist, ist der
    Inline-Wert tot; der Slot liefert null, statt etwas zu bearbeiten, das der Node nicht liest.

2. Ein Struct-Feld vom Typ Liste — ERLEDIGT

Es blieb bei einer Signaturänderung, kein Umbau — aber die Naht war nicht resolveList allein,
sondern der Besitzer dahinter. Die drei Fälle (Asset, Objekt, Node) liefern jetzt nur noch,
was an key steht und wie man es liest und schreibt; ob daraus die Liste selbst oder die Liste
eines Struct-Feldes wird, entscheidet ein Schritt danach. ListSlot trägt dafür ein optionales
field.

Die Tiefenregel steht wieder in der Deklaration, nicht in einem Kommentar: StructFieldKind
(= Primitive + list) sagt, was ein Struct-Feld hält, und ein solches Listenfeld hält
ausschließlich Primitive (ListFieldDef). Genau diese eine Asymmetrie hält die speicherbaren
Formen endlich:

list   → struct → primitiv
struct → list   → primitiv

Tiefer geht nichts — und das ist buchstäblich das, was asStoredValue seit jeher durch einen
untypisierten Slot lässt. Ein Listenfeld in den Items einer Liste weist AddStructFieldCommand
deshalb ab.

Geschrieben wird immer das ganze Bündel, neu gebaut aus dem, was in dem Moment im Besitzer
steht: nur die Liste zu schreiben würde ihre Nachbarfelder verlieren, ein Schnappschuss würde eine
zwischenzeitliche Änderung zurücknehmen.

3. Liste aus Structs — ERLEDIGT

Gebaut. Zwei Annahmen dieser Notiz waren dabei falsch, und beide haben es billiger gemacht:

  • Es wird nichts gegenseitig rekursiv. Die Tiefe steckt in der Deklaration, nicht in einer
    Konvention (siehe Punkt 2).
  • Es setzt Punkt 2 nicht voraus. Ein Struct-Item braucht keinen Pfad in der Adresse, weil es
    inline gerendert wird — dieselbe Begründung, aus der ein Struct im Inspector ein Block ist
    und keine eigene Navigation bekommt. structFieldHandlers trägt die Feld-Adresse.

Nebenpunkt: die Item-Art war im Editor nicht wählbar — ERLEDIGT

+ Variable ▸ List legte immer items: 'number' an, und für items: 'struct' gab es keinen
Feld-Editor; eine Liste aus Structs konnte deshalb nur aus einer Projektdatei entstehen.

  • Die Kennmarke ist der Wähler. ≡#, ≡Aa, ≡✓, ≡◧, ≡⊞ — eine eigene Spalte gibt die
    300 px breite Leiste nicht her, und die Marke ist die eine Stelle, die es sowieso schon sagt.
  • Ein Wechsel zieht jeden Wert mit (SetListItemsCommand): deklarierter Vorgabewert, eigener
    Wert des Behaviors und jede Instanz-Abweichung, jeweils durch coerceValue gegen die neue
    Deklaration — dieselbe Umwandlung, die ein im List-Tab bearbeiteter Posten durchläuft.
  • Eine Liste aus Structs deklariert ihre Item-Form mit demselben + Field, das eine
    Struct-Variable hat — nur Namen und Arten, weil die Werte Zeile für Zeile im Tab bearbeitet
    werden. Die Feld-Kommandos gelten dafür jetzt auch für den Listen-Besitzer und fassen jedes
    Item jedes Wertes
    an, damit kein Wert eine Form behält, die seine Deklaration nicht mehr
    verspricht.

Übernommen aus todo-notes/done/struct-und-listen-restposten.md beim Umzug auf das Issue-System (2026-09-12).

  • Angelegt: 2026-09-10 · 9d62dfe — Pull the three open items out of the finished port note
  • Abgeschlossen: 2026-09-10 · 10d0303 — Finish the struct and list leftovers: inline lists, list fields, item kinds
  • Commits dazwischen: f60358c Let a list hold structs, and read or write variables in bundles
  • Gemeldet von: admin
# Restposten aus dynamischen Ports / Structs Drei Punkte, die beim Bau von List-Tab und Struct-Variablen bewusst liegen geblieben sind. Sie standen am Ende von `done/nodes-mit-dynamischer-port-zahl.md` und sind hierher gezogen, damit sie nicht mit der erledigten Notiz verschwinden. **Alle drei sind gebaut** — dazu der Nebenpunkt, der beim Bauen aufgefallen war. ## 1. Der unverbundene Eingang zeigt das falsche Feld — ERLEDIGT `inlineInputDef` (`NodeRegistry.ts:131`) kannte nur `boolean`, `string`/`any` und *alles andere* — und "alles andere" wurde ein **Zahlenfeld**. Beim Nachmessen war der Restposten **kleiner als die Notiz behauptete**: `object` und `struct` kommen gar nicht mehr an `inlineInputDef` vorbei, `inlineInputs` siebt sie schon aus (mit der Begründung, die die Notiz für `object` verlangt hat: ein Objekt ist ein lebendes Handle, ein Struct wird aus Teilen gebaut). Offen war nur `list` — und dort ist es genau die Antwort geworden, die die Notiz vorgezeichnet hat: der Knopf `n items` plus List-Tab. Zwei Dinge, die dabei zu entscheiden waren: - **Die Item-Art ist `number`.** Kein Port deklariert eine — und das ist derselbe Vorgabewert, den `+ Variable ▸ List` setzt. Der Graph typisiert eine Liste ohnehin nur als Liste. - **Ein verbundener Port löst nicht mehr auf.** Sobald eine Kante den Eingang speist, ist der Inline-Wert tot; der Slot liefert `null`, statt etwas zu bearbeiten, das der Node nicht liest. ## 2. Ein Struct-Feld vom Typ Liste — ERLEDIGT Es blieb bei einer Signaturänderung, kein Umbau — aber die Naht war nicht `resolveList` allein, sondern der **Besitzer** dahinter. Die drei Fälle (Asset, Objekt, Node) liefern jetzt nur noch, *was an `key` steht und wie man es liest und schreibt*; ob daraus die Liste selbst oder die Liste eines Struct-Feldes wird, entscheidet ein Schritt danach. `ListSlot` trägt dafür ein optionales `field`. **Die Tiefenregel steht wieder in der Deklaration, nicht in einem Kommentar:** `StructFieldKind` (= Primitive + `list`) sagt, was ein Struct-**Feld** hält, und ein solches Listenfeld hält ausschließlich **Primitive** (`ListFieldDef`). Genau diese eine Asymmetrie hält die speicherbaren Formen endlich: ``` list → struct → primitiv struct → list → primitiv ``` Tiefer geht nichts — und das ist buchstäblich das, was `asStoredValue` seit jeher durch einen untypisierten Slot lässt. Ein Listenfeld in den Items einer Liste weist `AddStructFieldCommand` deshalb ab. Geschrieben wird immer das **ganze Bündel**, neu gebaut aus dem, was in dem Moment im Besitzer steht: nur die Liste zu schreiben würde ihre Nachbarfelder verlieren, ein Schnappschuss würde eine zwischenzeitliche Änderung zurücknehmen. ## 3. Liste aus Structs — ERLEDIGT Gebaut. Zwei Annahmen dieser Notiz waren dabei **falsch**, und beide haben es billiger gemacht: - Es wird **nichts gegenseitig rekursiv**. Die Tiefe steckt in der *Deklaration*, nicht in einer Konvention (siehe Punkt 2). - Es setzt **Punkt 2 nicht voraus**. Ein Struct-Item braucht keinen Pfad in der Adresse, weil es **inline** gerendert wird — dieselbe Begründung, aus der ein Struct im Inspector ein Block ist und keine eigene Navigation bekommt. `structFieldHandlers` trägt die Feld-Adresse. ## Nebenpunkt: die Item-Art war im Editor nicht wählbar — ERLEDIGT `+ Variable ▸ List` legte immer `items: 'number'` an, und für `items: 'struct'` gab es keinen Feld-Editor; eine Liste aus Structs konnte deshalb nur aus einer Projektdatei entstehen. - **Die Kennmarke ist der Wähler.** `≡#`, `≡Aa`, `≡✓`, `≡◧`, `≡⊞` — eine eigene Spalte gibt die 300 px breite Leiste nicht her, und die Marke ist die eine Stelle, die es sowieso schon sagt. - **Ein Wechsel zieht jeden Wert mit** (`SetListItemsCommand`): deklarierter Vorgabewert, eigener Wert des Behaviors und **jede Instanz-Abweichung**, jeweils durch `coerceValue` gegen die neue Deklaration — dieselbe Umwandlung, die ein im List-Tab bearbeiteter Posten durchläuft. - **Eine Liste aus Structs deklariert ihre Item-Form mit demselben `+ Field`**, das eine Struct-Variable hat — nur Namen und Arten, weil die Werte Zeile für Zeile im Tab bearbeitet werden. Die Feld-Kommandos gelten dafür jetzt auch für den Listen-Besitzer und fassen **jedes Item jedes Wertes** an, damit kein Wert eine Form behält, die seine Deklaration nicht mehr verspricht. --- *Übernommen aus `todo-notes/done/struct-und-listen-restposten.md` beim Umzug auf das Issue-System (2026-09-12).* - **Angelegt:** 2026-09-10 · `9d62dfe` — Pull the three open items out of the finished port note - **Abgeschlossen:** 2026-09-10 · `10d0303` — Finish the struct and list leftovers: inline lists, list fields, item kinds - **Commits dazwischen:** `f60358c` Let a list hold structs, and read or write variables in bundles - **Gemeldet von:** admin
admin added the todo-note label 2026-09-12 15:03:54 +02:00
admin closed this issue 2026-09-12 15:03:55 +02:00
admin added this to the Development project 2026-09-13 13:43:26 +02:00
admin moved this to Done in Development on 2026-09-13 13:44:44 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#24