Several transitions between the same pair of states: make transition onto a state that is already connected in that direction adds another transition, which gets its own name right away (Transition 2, Transition 3, skipping names that already leave the state), so two unnamed transitions between one pair never exist; renaming is refused when another transition between the same pair in the same direction already carries the name, the empty name included, while equal names to other targets are only warned about as before; the behavior graph keeps Already connected; self transitions may repeat too, each further loop drawn as a ring around the previous one with the preview showing the next ring, and transition labels that would cover another one slide along their own edge until they are free (pure function freeLabelSpot); test hook transitionLabelAt also returns width and height, e2e 26e6 (#162)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
010b6a7f6c
commit
25ec7879a0
9 files changed
+402
-34
No files matched your search
@@ -323,6 +323,48 @@ export async function stateMachine(t) {
|
||||
await undo();
|
||||
check('undo takes the loop back', (await transitions()).length === beforeLoop);
|
||||
|
||||
// 26e6. (#162) A second transition between the same pair, in the same direction: it gets a name
|
||||
// of its own, is drawn beside the first, and cannot be renamed into the first one's name.
|
||||
await makeTransition(first, second);
|
||||
const pair = (await transitions()).filter((e) => e.from.node === first && e.to.node === second);
|
||||
const extra = pair.find((e) => e.label !== 'alarm');
|
||||
check(
|
||||
'a second transition between the same states is made, under a name of its own',
|
||||
pair.length === 2 && extra?.label === 'Transition 2',
|
||||
JSON.stringify(pair),
|
||||
);
|
||||
const pairLabels = await Promise.all(
|
||||
pair.map((e) => json(`__gm.stateMachine.transitionLabelAt(${JSON.stringify(e.id)})`)),
|
||||
);
|
||||
check(
|
||||
'both are stroked, their names side by side rather than on top of each other',
|
||||
pairLabels.every((l) => l !== null) &&
|
||||
!(
|
||||
pairLabels[0].x < pairLabels[1].x + pairLabels[1].w &&
|
||||
pairLabels[1].x < pairLabels[0].x + pairLabels[0].w &&
|
||||
pairLabels[0].y < pairLabels[1].y + pairLabels[1].h &&
|
||||
pairLabels[1].y < pairLabels[0].y + pairLabels[0].h
|
||||
),
|
||||
JSON.stringify(pairLabels),
|
||||
);
|
||||
await shot('05e-parallel');
|
||||
await evaluate("__gm.state.notice = ''");
|
||||
const extraField = await locate('Transition 2', true);
|
||||
await doubleClick(extraField.x, extraField.y);
|
||||
await typeText('alarm');
|
||||
await press('Enter');
|
||||
check(
|
||||
"renaming it into the first one's name is refused with a notice",
|
||||
(await transitions()).find((e) => e.id === extra?.id)?.label === 'Transition 2' &&
|
||||
(await json('__gm.state.notice')).includes('already called "alarm"'),
|
||||
JSON.stringify({ edges: await transitions(), notice: await json('__gm.state.notice') }),
|
||||
);
|
||||
await undo();
|
||||
check(
|
||||
'undo takes the second one back and leaves the first',
|
||||
(await transitions()).filter((e) => e.from.node === first && e.to.node === second).length === 1,
|
||||
);
|
||||
|
||||
// 26f. A behavior reads the machine: Set state on start, State branch every frame.
|
||||
const rig = await scaffoldBehavior(t, {
|
||||
assetId: 'sm-logic',
|
||||
|
||||
Reference in new issue
Block a user