mirror of
https://github.com/xodio/xod.git
synced 2026-02-20 02:01:20 +01:00
Merge pull request #2025 from xodio/fix-stale-output-terminals-without-links-below
Fix flatten: get rid of stale output custom type terminals
This commit is contained in:
@@ -645,7 +645,7 @@ const isLinkOutputNodeIdOneOf = R.curry((terminalNodeIds, link) =>
|
||||
// :: [NodeId] -> [Link] -> [[NodeId], [Link]]
|
||||
const traverseUpAndCollectTerminalChain = R.curry(
|
||||
(terminalNodeIds, links, collected) => {
|
||||
const curLink = R.compose(R.last, R.last)(collected);
|
||||
const curLink = R.last(collected[1]);
|
||||
|
||||
if (isLinkOutputNodeIdOneOf(terminalNodeIds, curLink)) {
|
||||
// collect nodeId + next link & run recursion
|
||||
@@ -654,8 +654,10 @@ const traverseUpAndCollectTerminalChain = R.curry(
|
||||
R.compose(R.equals(nextNodeId), Link.getLinkInputNodeId),
|
||||
links
|
||||
);
|
||||
// If the uppermost node has no input link — return collected data
|
||||
if (!nextLink) return collected;
|
||||
// If the upper terminal node has no input link — return tuple of empty lists
|
||||
// to avoid removing this chain of terminals, because it will be done in the
|
||||
// further step with passing bound values
|
||||
if (!nextLink) return [[], []];
|
||||
|
||||
return R.compose(
|
||||
traverseUpAndCollectTerminalChain(terminalNodeIds, links),
|
||||
@@ -683,16 +685,26 @@ const replaceGenericTerminalsWithCastNodes = R.curry(
|
||||
|
||||
const linksConnectedToTerminals = R.filter(
|
||||
R.compose(
|
||||
linkNodeIds => R.any(R.contains(R.__, linkNodeIds), terminalNodeIds),
|
||||
linkNodeIds => R.any(isAmong(linkNodeIds), terminalNodeIds),
|
||||
Link.getLinkNodeIds
|
||||
),
|
||||
links
|
||||
);
|
||||
|
||||
const lowermostTerminalLinks = R.filter(
|
||||
R.compose(
|
||||
R.complement(R.contains)(R.__, terminalNodeIds),
|
||||
Link.getLinkInputNodeId
|
||||
R.either(
|
||||
// link inputs into non terminal node
|
||||
R.compose(
|
||||
R.complement(isAmong(terminalNodeIds)),
|
||||
Link.getLinkInputNodeId
|
||||
),
|
||||
// or into terminal node, which not have a links below
|
||||
R.compose(
|
||||
R.not,
|
||||
R.find(R.__, links),
|
||||
Link.isLinkOutputNodeIdEquals,
|
||||
Link.getLinkInputNodeId
|
||||
)
|
||||
),
|
||||
linksConnectedToTerminals
|
||||
);
|
||||
@@ -742,14 +754,13 @@ const replaceGenericTerminalsWithCastNodes = R.curry(
|
||||
)(terminalChains);
|
||||
|
||||
const nodesWithoutTerminals = R.reject(
|
||||
R.compose(R.contains(R.__, nodeIdsToOmit), Node.getNodeId),
|
||||
R.compose(isAmong(nodeIdsToOmit), Node.getNodeId),
|
||||
nodes
|
||||
);
|
||||
const linksWithoutTerminalLinks = R.reject(
|
||||
R.compose(R.contains(R.__, linkIdsToOmit), Link.getLinkId),
|
||||
R.compose(isAmong(linkIdsToOmit), Link.getLinkId),
|
||||
links
|
||||
);
|
||||
|
||||
const newNodesAndLinks = R.map(
|
||||
splitLinkWithCastNode(project, patchTuples, nodesWithoutTerminals),
|
||||
directLinks
|
||||
|
||||
@@ -665,6 +665,261 @@
|
||||
}
|
||||
},
|
||||
"path": "xod/i2c/test"
|
||||
},
|
||||
"@/test-unlinked-lowermost-terminal": {
|
||||
"links": {
|
||||
"original1": {
|
||||
"id": "original1",
|
||||
"input": {
|
||||
"nodeId": "testNode",
|
||||
"pinKey": "input-color"
|
||||
},
|
||||
"output": {
|
||||
"nodeId": "colorHslNode",
|
||||
"pinKey": "output-color"
|
||||
}
|
||||
},
|
||||
"toWatch": {
|
||||
"id": "toWatch",
|
||||
"input": {
|
||||
"nodeId": "watch-node",
|
||||
"pinKey": "input-string"
|
||||
},
|
||||
"output": {
|
||||
"nodeId": "testNode",
|
||||
"pinKey": "output-string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"testNode": {
|
||||
"id": "testNode",
|
||||
"position": {
|
||||
"x": -8,
|
||||
"y": -1,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "@/unlinked-custom-terminal"
|
||||
},
|
||||
"colorHslNode": {
|
||||
"id": "colorHslNode",
|
||||
"position": {
|
||||
"x": -8,
|
||||
"y": -2,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "xod/color/color-hsl"
|
||||
},
|
||||
"watch-node": {
|
||||
"id": "watch-node",
|
||||
"position": {
|
||||
"x": -8,
|
||||
"y": 1,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "xod/debug/watch"
|
||||
}
|
||||
},
|
||||
"path": "@/test-unlinked-lowermost-terminal"
|
||||
},
|
||||
"@/unlinked-custom-terminal": {
|
||||
"links": {
|
||||
"toFormatColor": {
|
||||
"id": "toFormatColor",
|
||||
"input": {
|
||||
"nodeId": "formatColorNode",
|
||||
"pinKey": "input-color"
|
||||
},
|
||||
"output": {
|
||||
"nodeId": "input-color",
|
||||
"pinKey": "__out__"
|
||||
}
|
||||
},
|
||||
"toOutputString": {
|
||||
"id": "toOutputString",
|
||||
"input": {
|
||||
"nodeId": "output-string",
|
||||
"pinKey": "__in__"
|
||||
},
|
||||
"output": {
|
||||
"nodeId": "formatColorNode",
|
||||
"pinKey": "output-string"
|
||||
}
|
||||
},
|
||||
"toOutputColor": {
|
||||
"id": "toOutputColor",
|
||||
"input": {
|
||||
"nodeId": "output-color",
|
||||
"pinKey": "__in__"
|
||||
},
|
||||
"output": {
|
||||
"nodeId": "input-color",
|
||||
"pinKey": "__out__"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"output-color": {
|
||||
"id": "output-color",
|
||||
"position": {
|
||||
"x": 0,
|
||||
"y": 2,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "xod/color/output-color"
|
||||
},
|
||||
"formatColorNode": {
|
||||
"id": "formatColorNode",
|
||||
"position": {
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "xod/color/format-color"
|
||||
},
|
||||
"input-color": {
|
||||
"id": "input-color",
|
||||
"position": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "xod/color/input-color"
|
||||
},
|
||||
"output-string": {
|
||||
"id": "output-string",
|
||||
"position": {
|
||||
"x": 2,
|
||||
"y": 2,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "xod/patch-nodes/output-string"
|
||||
}
|
||||
},
|
||||
"path": "@/unlinked-custom-terminal"
|
||||
},
|
||||
"@/test-nested-input-color": {
|
||||
"nodes": {
|
||||
"nested-format-color": {
|
||||
"boundLiterals": {
|
||||
"input-color-1": "#0000FF",
|
||||
"input-color-2": "#FF0000"
|
||||
},
|
||||
"id": "nested-format-color",
|
||||
"position": {
|
||||
"x": -5,
|
||||
"y": -1,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "@/nested-format-color"
|
||||
}
|
||||
},
|
||||
"path": "@/test-nested-input-color"
|
||||
},
|
||||
"@/nested-format-color": {
|
||||
"links": {
|
||||
"ByAbAISQv": {
|
||||
"id": "ByAbAISQv",
|
||||
"input": {
|
||||
"nodeId": "format-color-1",
|
||||
"pinKey": "input-color"
|
||||
},
|
||||
"output": {
|
||||
"nodeId": "input-color-1",
|
||||
"pinKey": "__out__"
|
||||
}
|
||||
},
|
||||
"H1MG0IBQv": {
|
||||
"id": "H1MG0IBQv",
|
||||
"input": {
|
||||
"nodeId": "output-string-1",
|
||||
"pinKey": "__in__"
|
||||
},
|
||||
"output": {
|
||||
"nodeId": "format-color-2",
|
||||
"pinKey": "output-string"
|
||||
}
|
||||
},
|
||||
"SJLMAIH7w": {
|
||||
"id": "SJLMAIH7w",
|
||||
"input": {
|
||||
"nodeId": "output-string-2",
|
||||
"pinKey": "__in__"
|
||||
},
|
||||
"output": {
|
||||
"nodeId": "format-color-1",
|
||||
"pinKey": "output-string"
|
||||
}
|
||||
},
|
||||
"SJqbR8BQw": {
|
||||
"id": "SJqbR8BQw",
|
||||
"input": {
|
||||
"nodeId": "format-color-2",
|
||||
"pinKey": "input-color"
|
||||
},
|
||||
"output": {
|
||||
"nodeId": "input-color-2",
|
||||
"pinKey": "__out__"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"input-color-1": {
|
||||
"id": "input-color-1",
|
||||
"position": {
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "xod/color/input-color"
|
||||
},
|
||||
"format-color-1": {
|
||||
"id": "format-color-1",
|
||||
"position": {
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "xod/color/format-color"
|
||||
},
|
||||
"output-string-1": {
|
||||
"id": "output-string-1",
|
||||
"position": {
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "xod/patch-nodes/output-string"
|
||||
},
|
||||
"input-color-2": {
|
||||
"id": "input-color-2",
|
||||
"position": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "xod/color/input-color"
|
||||
},
|
||||
"output-string-2": {
|
||||
"id": "output-string-2",
|
||||
"position": {
|
||||
"x": 3,
|
||||
"y": 2,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "xod/patch-nodes/output-string"
|
||||
},
|
||||
"format-color-2": {
|
||||
"id": "format-color-2",
|
||||
"position": {
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"units": "slots"
|
||||
},
|
||||
"type": "xod/color/format-color"
|
||||
}
|
||||
},
|
||||
"path": "@/nested-format-color"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import * as Helper from './helpers';
|
||||
import * as Project from '../src/project';
|
||||
import * as Patch from '../src/patch';
|
||||
import * as Node from '../src/node';
|
||||
import * as Link from '../src/link';
|
||||
import * as Attachment from '../src/attachment';
|
||||
import * as CONST from '../src/constants';
|
||||
import flatten, { extractPatches, extractLeafPatches } from '../src/flatten';
|
||||
@@ -1378,6 +1379,60 @@ describe('Flatten', () => {
|
||||
}, flatProject);
|
||||
});
|
||||
|
||||
it('should get rid of output terminals without output links', () => {
|
||||
const flatProject = flatten(
|
||||
project,
|
||||
'@/test-unlinked-lowermost-terminal'
|
||||
);
|
||||
Helper.expectEitherRight(newProject => {
|
||||
const nodeIds = R.compose(
|
||||
R.map(Node.getNodeId),
|
||||
Patch.listNodes,
|
||||
Project.getPatchByPathUnsafe('@/test-unlinked-lowermost-terminal')
|
||||
)(newProject);
|
||||
|
||||
const linkIds = R.compose(
|
||||
R.map(Link.getLinkId),
|
||||
Patch.listLinks,
|
||||
Project.getPatchByPathUnsafe('@/test-unlinked-lowermost-terminal')
|
||||
)(newProject);
|
||||
|
||||
assert.sameMembers(
|
||||
['testNode~formatColorNode', 'colorHslNode', 'watch-node'],
|
||||
nodeIds
|
||||
);
|
||||
assert.sameMembers(
|
||||
['toWatch', 'original1-to-testNode~toFormatColor'],
|
||||
linkIds
|
||||
);
|
||||
}, flatProject);
|
||||
});
|
||||
|
||||
it('should pass bound values to nested castable custom type terminals', () => {
|
||||
const flatProject = flatten(project, '@/test-nested-input-color');
|
||||
Helper.expectEitherRight(newProject => {
|
||||
const nodeIds = R.compose(
|
||||
R.map(Node.getNodeId),
|
||||
Patch.listNodes,
|
||||
Project.getPatchByPathUnsafe('@/test-nested-input-color')
|
||||
)(newProject);
|
||||
|
||||
const links = R.compose(
|
||||
Patch.listLinks,
|
||||
Project.getPatchByPathUnsafe('@/test-nested-input-color')
|
||||
)(newProject);
|
||||
|
||||
assert.sameMembers(
|
||||
[
|
||||
'nested-format-color~format-color-1',
|
||||
'nested-format-color~format-color-2',
|
||||
],
|
||||
nodeIds
|
||||
);
|
||||
assert.isEmpty(links);
|
||||
}, flatProject);
|
||||
});
|
||||
|
||||
it('should return Either.Left if custom type does not have a cast node', () => {
|
||||
const flatProject = flatten(project, '@/test-no-cast-node');
|
||||
Helper.expectEitherError(
|
||||
|
||||
Reference in New Issue
Block a user