Finish the struct and list leftovers: inline lists, list fields, item kinds
An unconnected list input is a button into the List tab instead of a number field; a struct field can hold a list, so ListSlot carries an optional field name and the three owner cases only say what sits at a key; and a list variable picks its item kind in the inspector (marker doubles as the chooser), so a list of structs no longer has to be born from a project file. The declaration keeps the storable shapes finite: a struct field may be a list, but that list holds primitives only, so list->struct->primitive and struct->list->primitive are the two deepest forms. check 674, e2e 483, jump-run 24, Tetris 19. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fe3c63c48c
commit
10d030376a
18 files changed
+984
-184
No files matched your search
@@ -94,6 +94,47 @@ export async function structVariable(t) {
|
||||
JSON.stringify(await piece()),
|
||||
);
|
||||
|
||||
// 6. A field may itself be a list. Its row is the same "n items" button a list property has,
|
||||
// and it opens the List tab one level down – on the field, not on the whole bundle.
|
||||
await clickText('+ Field');
|
||||
await sleep(150);
|
||||
// "List" is also the tab bar's own label, so the menu entry is reached as the last drawn one.
|
||||
const listOption = await json(`__gm.locate('List', true)`);
|
||||
await click(listOption.x, listOption.y);
|
||||
await sleep(250);
|
||||
check(
|
||||
'+ Field ▸ List gives the bundle an empty list',
|
||||
Array.isArray((await piece()).field1),
|
||||
JSON.stringify(await piece()),
|
||||
);
|
||||
const itemsButton = await find('0 items');
|
||||
check('and that field reads as an item count', itemsButton !== null);
|
||||
|
||||
await click(itemsButton.x, itemsButton.y);
|
||||
await sleep(250);
|
||||
check('clicking it opens the List tab', (await json('__gm.tab()')) === 'list');
|
||||
const info = await json('__gm.list.info()');
|
||||
check('whose title names the field inside the bundle', info.title.endsWith('· field1'), info.title);
|
||||
|
||||
await clickText('+ Item');
|
||||
await sleep(250);
|
||||
check(
|
||||
'and an item added there leaves the neighbouring fields alone',
|
||||
JSON.stringify(await piece()) === '{"column":30,"tag":"tee","field1":[0]}',
|
||||
JSON.stringify(await piece()),
|
||||
);
|
||||
await shot('03-list-field');
|
||||
await undo();
|
||||
await undo();
|
||||
await sleep(200);
|
||||
check(
|
||||
'undo takes the list field back out of the bundle',
|
||||
!('field1' in (await piece())),
|
||||
JSON.stringify(await piece()),
|
||||
);
|
||||
|
||||
await mutate('__gm.state.openList(null)');
|
||||
await sleep(200);
|
||||
await mutate(`
|
||||
const p = __gm.state.project;
|
||||
p.assets = p.assets.filter((a) => a.id !== 'structy');
|
||||
|
||||
Reference in new issue
Block a user