Let a list hold structs, and read or write variables in bundles
A list item may now be a struct. The depth is bounded in the declaration
rather than by a comment: FieldKind (number|text|boolean|color) says what a
struct field holds, ListItemKind adds struct on top and says what a list
holds, so list -> struct -> primitive is the deepest storable shape and
sameValue stays finite. A struct item renders inline in the List tab, which
is why it needs no path in the slot address.
Four paths silently assumed a list item was a primitive: sameValue compared
items with ===, textOf would have printed [object Object], asListItem turned
a struct into text on Set item and Fill, and Index of used indexOf, which is
reference equality and could never have found a struct.
Tetris now runs on bundles. shapes is 112 {x, y} structs instead of 224 loose
numbers, piece and the candidate are structs, so Next move hands back a whole
candidate and each strand packs only the field it changes, since mergeStruct
leaves the rest standing. Declared behavior ports drop 49 -> 35, the master's
variables 18 -> 13, its graph 84/94 -> 69/76 nodes/edges.
Get variables and Set variables declare their ports from a list of variable
names, the way Pack and Expand already do, so one node can read or write
several at once. Renaming a variable rewires them, because there the port key
is the variable name.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
9d62dfea7b
commit
f60358c951
32 files changed
+1083
-253
No files matched your search
@@ -0,0 +1,2 @@
|
||||
beim expand und pack node habe ich mir eigentlich auch vorgestellt, dass man sich eine struct variable auswählt und automatisch die felder erzeugt werden.
|
||||
wir können das so lassen wie es ist (eigene felder definieren), aber eine helfer auswahl von structs das die felder erstellt wäre gut.
|
||||
@@ -4,6 +4,13 @@ Drei Punkte, die beim Bau von List-Tab und Struct-Variablen bewusst liegen gebli
|
||||
standen am Ende von `done/nodes-mit-dynamischer-port-zahl.md` und sind hierher gezogen, damit sie
|
||||
nicht mit der erledigten Notiz verschwinden.
|
||||
|
||||
**Punkt 3 ist inzwischen gebaut** (siehe unten). Offen sind noch 1 und 2.
|
||||
|
||||
Fehlender Nebenpunkt, der dabei aufgefallen ist: eine Listen-Variable kann ihre **Item-Art im
|
||||
Editor gar nicht wählen** — `+ Variable ▸ List` legt immer `items: 'number'` an, und für
|
||||
`items: 'struct'` gibt es keinen Feld-Editor. Eine Liste aus Structs entsteht deshalb heute nur
|
||||
aus einer Projektdatei (Seeder); bearbeiten lässt sie sich danach normal.
|
||||
|
||||
## 1. Der unverbundene Eingang zeigt das falsche Feld
|
||||
|
||||
`inlineInputDef` (`NodeRegistry.ts:131`) kennt nur `boolean`, `string`/`any` und *alles andere* —
|
||||
@@ -21,15 +28,14 @@ Ein deklariertes Struct-Feld ist heute ein Primitiv (Zahl, Text, Ja/Nein, Farbe)
|
||||
einen **Pfad in der Slot-Adresse** (`ListSlot` in `state.ts` hat bewusst keinen). Die Naht ist die
|
||||
eine Funktion `resolveList` — eine Signaturänderung, kein Umbau.
|
||||
|
||||
## 3. Liste aus Structs
|
||||
## 3. Liste aus Structs — ERLEDIGT
|
||||
|
||||
Der teuerste der drei. `ListValue` ist heute `readonly (number | string | boolean)[]` und
|
||||
`FieldValue` hält fest, dass kein Feld selbst ein Struct ist (`Properties.ts:5-8`); `sameValue`
|
||||
verlässt sich darauf ("recurses exactly one level deep", `Properties.ts:50`), und
|
||||
`LIST_ITEM_KINDS` macht eine Liste homogen.
|
||||
Gebaut. Zwei Annahmen dieser Notiz waren dabei **falsch**, und beide haben es billiger gemacht:
|
||||
|
||||
Structs in Listen machen `ListValue` und `StructValue` **gegenseitig rekursiv**: beliebige
|
||||
Schachtelungstiefe, echter Deep-Compare, und die Items brauchen eine gemeinsame deklarierte
|
||||
Feldform — die im Typmodell keine Heimat hat, solange sie nur an *einer* Property hängt.
|
||||
|
||||
Setzt Punkt 2 voraus (Pfad in der Adresse).
|
||||
- Es wird **nichts gegenseitig rekursiv**. Die Tiefe steckt in der *Deklaration*, nicht in einer
|
||||
Konvention: `FieldKind` (Primitive) sagt, was ein Struct-**Feld** hält, `ListItemKind`
|
||||
(= `FieldKind` + `struct`) sagt, was eine **Liste** hält. Damit ist `list → struct → primitiv`
|
||||
die tiefste gespeicherte Form — kein beliebiges Schachteln, `sameValue` bleibt endlich.
|
||||
- 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.
|
||||
@@ -1 +1,2 @@
|
||||
Tetris Game mit Structs neu bauen
|
||||
...und mit neuen `Get variables` / `Set variables` node
|
||||
Reference in new issue
Block a user