Define a struct once as an asset and reuse its shape (#253)
A struct used to declare its fields wherever it stood. The same shape in two variables meant typing it twice, and Pack/Expand copied it once without staying in sync. A Struct asset now holds the shape in one place, and every struct that picks it as its type follows it. - New asset type "Struct" (not placeable, group Structs, own icon). The inspector shows its fields with name, kind and default value, and "Open" shows them in the variables tab. - Struct variables and struct fields get a Type row: own fields, any Struct asset, or "Make struct type". With a type the fields come from the asset and cannot be added, renamed or removed there. The values stay per variable, overrides on placed objects still work. - Pack and Expand get the setting Type. With a type their ports are the fields of the asset and read-only in the inspector. - A change to the asset reaches every typed place in one undo step (syncStructTypes). A new field arrives with its default. A removed field goes along with its port, edge and typed value. A renamed field keeps its value in variables, overrides and on ports with edges, also through nested types. - Undo for these edits records plain assignments (Recorder), because the reach of a change is not known in advance. - Cycles such as Loot in Loot, also through another type, are refused and not offered in the picker. - Deleting the asset names how many places use it. Afterwards each place keeps its fields as its own. - Loading reshapes a stale copy in a project file to its type. - "Make struct type" creates an asset from an existing struct and links the place to it. Differs from the plan: - A changed default value applies to new fields and newly typed places only. Existing values stay. - Removing a single field shows no warning. Undo brings it back. Typed lists are left for #254. Lists stay dynamic for now. Found by e2e: after deleting or renaming the type the inspector did not rebuild and kept showing the old name. Fixed, the check was red before. Tests: - ./check.sh: 182 files, 2661 tests, CHECK EXIT 0 - GM_STEPS=1,4,21,22,54: ALL PASSED, 176 checks - 14 unit tests in tests/core/struct-types.test.ts - New e2e module 54 with 14 checks, real mouse. Module 04 counts 23 asset types. - Counter-probes: without the rename pass 4 unit tests fail, without reshaping values 8, without the cycle rule 1. In the browser, without spreading changes and with + Field despite a type, 3 checks fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4857bb75e6
commit
61bbb96a96
29 files changed
+1523
-66
No files matched your search
@@ -4,6 +4,7 @@
|
||||
* One editor for every such tab, pointed at the target of the one showing, like the asset editors.
|
||||
*/
|
||||
import type { Container } from 'pixi.js';
|
||||
import { isVariableOwner } from '../../core/model/Asset';
|
||||
import { findObject } from '../../core/model/hierarchy';
|
||||
import { findAsset } from '../../core/model/Project';
|
||||
import { Label, ScrollContainer, Theme, ui, VStack, HStack } from '../../ui';
|
||||
@@ -20,7 +21,7 @@ function ownerOf(state: EditorState, target: Extract<ValuesTarget, { kind: 'vari
|
||||
const { owner } = target;
|
||||
if (owner.kind === 'asset') {
|
||||
const asset = findAsset(state.project, owner.assetId);
|
||||
return asset?.type === 'behavior' || asset?.type === 'variables' ? { asset, name: asset.name } : null;
|
||||
return isVariableOwner(asset) ? { asset, name: asset.name } : null;
|
||||
}
|
||||
const view = viewOf(state.project, owner.holderId);
|
||||
const object = view && findObject(view, owner.objectId);
|
||||
@@ -32,7 +33,8 @@ function ownerOf(state: EditorState, target: Extract<ValuesTarget, { kind: 'vari
|
||||
export function valuesTitle(state: EditorState, target: ValuesTarget, live?: LiveVariables): string | null {
|
||||
if (target.kind === 'list') return resolveList(state, target.slot, live)?.title ?? null;
|
||||
const owner = ownerOf(state, target);
|
||||
return owner ? `${owner.name} · Variables` : null;
|
||||
if (!owner) return null;
|
||||
return `${owner.name} · ${owner.asset.type === 'struct' ? 'Fields' : 'Variables'}`;
|
||||
}
|
||||
|
||||
export class VariablesEditor extends VStack {
|
||||
|
||||
Reference in new issue
Block a user