Hand a shared port type on through a chain of nodes (#210)
Since #207 the output of First not empty or Select takes the type
its inputs agree on. A second node of that kind behind the first
stayed any, because the first one answered with the any it was
registered with. That was the guard against a circle of such nodes
asking each other forever. The issue asks for the type to travel
through the chain. Answered there: measure with 50 nodes and build
no cache, and the painted input pins follow along.
- shapedDef in core/graph/nested.ts takes a Trail in place of the
flag inherit. Its set open holds the nodes still being asked. A
node reached a second time reports the any it was registered
with, which ends a circle.
- The map done of the Trail keeps each answer of one question. A
node feeding both inputs of the next is asked once, so the work
does not double with every link of a chain.
- ownShape is the part of shapedDef that builds the ports before a
shared group has its say. It is split off, nothing in it changed.
- Inputs stay any and only outputs inherit, as in #207. An edge
that turns invalid further down is left in place and drawn in the
danger colour.
- paintedInputs uses one Trail for all pins of a node, so the pins
show the type handed on through the chain.
- Nothing is cached between two changes. A chain of 50 resolved in
about 10 ms where it took 2 ms before, measured earlier in this
round and not again for this commit.
Tests:
- Gate on melektaus-atx: 211 files, 3240 tests (3227 + 13), exit 0
- e2e 1-6 on melektaus-atx: 298 checks, all pass
- e2e 4,6,18,19,20,23,24,26,28,31,36,43,53: 558 checks, all pass
- No full run and no smokes. The sum of 1673 (1671 + 2) is reckoned,
1671 is what CI counted for c88f57c.
- Fourteen unit tests in shared-port-type.test.ts: a chain of two
and of three, mixed kinds, a mixed and an open input, undo at the
front, a circle of two, a node feeding itself, behind a circle, an
invalid edge further down, the chain of 40 asked once per node,
the chain of 50, and two for the pins. The test saying the type
does not pass through a second node is gone, hence 13 more.
- Two e2e checks in module 06: the second node takes number, and a
text at the front opens the whole chain again.
- Four unit counter-probes and one browser counter-probe all fail
their tests. With the old behaviour only the chain check fails.
- Not checked in the browser: the circle and the chain of three,
which have unit tests only. Nothing was looked at after the build.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c88f57cf0a
commit
9ca220a285
4 files changed
+268
-39
No files matched your search
@@ -1050,6 +1050,41 @@ export async function graph(t) {
|
||||
JSON.stringify({ pinColors, wanted }),
|
||||
);
|
||||
await shot('20-input-pin-colours');
|
||||
|
||||
// A second node of the kind behind the first (#210): the type is handed on through the chain,
|
||||
// and taken back all along it once the front of the chain disagrees again.
|
||||
await mutate(`
|
||||
__gm.state.project.assets
|
||||
.find((a) => a.id === 'picky')
|
||||
.graph.nodes.push({ id: 'p-next', type: 'FirstNotEmpty', x: 300, y: 330, params: {} });
|
||||
`);
|
||||
const nextTypes = async () => json(`__gm.graph.portTypes('p-next')`);
|
||||
await wire('p-pick', 'value', 'p-next', 'a');
|
||||
await wire('p-pick', 'value', 'p-next', 'b');
|
||||
const chainOpen = await nextTypes();
|
||||
await wire('p-a', 'value', 'p-pick', 'a');
|
||||
const chainTyped = await nextTypes();
|
||||
check(
|
||||
'a second node of the kind behind the first takes the type the first one agreed on',
|
||||
chainOpen.outputs.value === 'any' &&
|
||||
(await pickTypes()).outputs.value === 'number' &&
|
||||
chainTyped.outputs.value === 'number' &&
|
||||
chainTyped.inputs.a === 'any' &&
|
||||
chainTyped.paint.a === 'number' &&
|
||||
chainTyped.paint.b === 'number',
|
||||
JSON.stringify({ chainOpen, chainTyped }),
|
||||
);
|
||||
await shot('20b-shared-type-chain');
|
||||
await wire('p-text', 'value', 'p-pick', 'a');
|
||||
const chainMixed = await nextTypes();
|
||||
check(
|
||||
'a text plugged into the first opens the whole chain up again',
|
||||
(await pickTypes()).outputs.value === 'any' &&
|
||||
chainMixed.outputs.value === 'any' &&
|
||||
chainMixed.paint.a === 'any' &&
|
||||
chainMixed.paint.b === 'any',
|
||||
JSON.stringify(chainMixed),
|
||||
);
|
||||
await mutate(`
|
||||
const p = __gm.state.project;
|
||||
p.assets = p.assets.filter((a) => a.id !== 'picky');
|
||||
|
||||
Reference in new issue
Block a user