feat(xod-project): support binding input pulses to ‘ON_BOOT’ and ‘CONTINUOUSLY’

This commit is contained in:
Evgeny Kochetkov
2017-07-11 14:56:04 +03:00
parent 4a24f925df
commit 1e643ea741
6 changed files with 237 additions and 218 deletions

View File

@@ -7,17 +7,26 @@ import * as Node from './node';
import * as Link from './link';
import * as Patch from './patch';
import * as Project from './project';
import { PIN_TYPE, INPUT_PULSE_PIN_BINDING_OPTIONS } from './constants';
import { def } from './types';
const CONST_NODETYPES = {
number: 'xod/core/constant-number',
boolean: 'xod/core/constant-boolean',
// TODO: it will be either 'xod/core/boot'
// or 'xod/core/continuously'
pulse: 'xod/core/constant-boolean',
string: 'xod/core/constant-string',
};
const PULSE_CONST_NODETYPES = {
[INPUT_PULSE_PIN_BINDING_OPTIONS.ON_BOOT]: 'xod/core/boot',
[INPUT_PULSE_PIN_BINDING_OPTIONS.CONTINUOUSLY]: 'xod/core/continuously',
};
const CONST_PATCH_PATHS = R.compose(
R.uniq,
R.values,
R.merge
)(CONST_NODETYPES, PULSE_CONST_NODETYPES);
const isNodeWithCurriedPins = def(
'isNodeWithCurriedPins :: Node -> Boolean',
R.compose(
@@ -92,54 +101,65 @@ const getMapOfNodePinTypes = def(
)
);
// :: { NodeId: { PinKey: PinType } } -> { NodeId: { PinKey: PatchPath } }
const convertMapOfPinTypesIntoMapOfPinPaths = def(
'convertMapOfPinTypesIntoMapOfPinPaths :: Map NodeId (Map PinKey DataType) -> Map NodeId (Map PinKey PatchPath)',
R.map(R.map(R.prop(R.__, CONST_NODETYPES)))
);
const getMapOfPinPaths = def(
'getMapOfPinPaths :: Map NodeId (Map PinKey DataValue) -> [Node] -> Project -> Map NodeId (Map PinKey PatchPath)',
const getMapOfExtractablePinPaths = def(
'getMapOfExtractablePinPaths :: Map NodeId (Map PinKey DataValue) -> [Node] -> Project -> Map NodeId (Map PinKey PatchPath)',
R.compose(
convertMapOfPinTypesIntoMapOfPinPaths,
getMapOfNodePinTypes
R.map(R.reject(R.isNil)),
R.map(R.map(
([pinType, pinValue]) => (
pinType === PIN_TYPE.PULSE
? PULSE_CONST_NODETYPES[pinValue]
: CONST_NODETYPES[pinType]
)
)),
R.converge(
R.mergeWith(R.mergeWith(Array.of)),
[
getMapOfNodePinTypes,
R.identity,
]
)
)
);
const getMapOfPathsToPinKeys = def(
'getMapOfPathsToPinKeys :: Map DataType PatchPath -> Project -> Map PatchPath PinKey',
'getMapOfPathsToPinKeys :: [PatchPath] -> Project -> Map PatchPath PinKey',
(constantPaths, project) => R.compose(
R.fromPairs,
R.map(constPath => R.compose(
constPinKey => [constPath, constPinKey],
Pin.getPinKey,
R.head,
Patch.listOutputPins,
Project.getPatchByPathUnsafe(R.__, project)
R.map(
constPath => R.compose(
constPinKey => [constPath, constPinKey],
Pin.getPinKey,
R.head,
Patch.listOutputPins,
Project.getPatchByPathUnsafe(R.__, project)
)(constPath)
),
R.uniq,
R.values
)
)(constantPaths)
);
const createNodesWithBoundValues = def(
'createNodesWithBoundValues :: Map NodeId (Map PinKey DataValue) -> Map NodeId (Map PinKey PatchPath) -> Map PatchPath PinKey -> Map NodeId (Map PinKey Node)',
(mapOfPinValues, mapOfPinPaths, mapOfPinKeys) => R.mapObjIndexed(
(pinsData, nodeId) => R.mapObjIndexed(
(pinValue, pinKey) => {
const type = R.path([nodeId, pinKey], mapOfPinPaths);
const constPinKey = R.prop(type, mapOfPinKeys);
(allInputPinValues, extractablePinPaths, mapOfPinKeys) =>
R.mapObjIndexed(
(pinsData, nodeId) => R.compose(
R.mapObjIndexed((pinValue, pinKey) => {
const type = R.path([nodeId, pinKey], extractablePinPaths);
const constPinKey = R.prop(type, mapOfPinKeys);
return R.compose(
Node.setBoundValue(constPinKey, pinValue),
Node.createNode({ x: 0, y: 0 })
)(type);
},
pinsData
),
mapOfPinValues
)
return R.compose(
R.unless(
R.always(R.equals(PIN_TYPE.PULSE, type)),
// do not transfer bound values to 'pulse constants'
Node.setBoundValue(constPinKey, pinValue)
),
Node.createNode({ x: 0, y: 0 })
)(type);
}),
R.pickBy((pinValue, pinKey) => R.path([nodeId, pinKey], extractablePinPaths))
)(pinsData),
allInputPinValues
)
);
const nestedValues = def(
@@ -292,7 +312,7 @@ const extractBoundInputsToConstNodes = def(
const occupiedNodePins = getMapOfNodePinsWithLinks(entryPointNodes, entryPointLinks);
const outputNodePins = getMapOfNodeOutputPins(entryPointNodes, origProject);
const pinsToOmit = R.mergeWith(R.concat, occupiedNodePins, outputNodePins);
const nodePinValues = R.compose(
const allInputPinValues = R.compose(
R.mapObjIndexed(
(pins, nodeId) => R.omit(
R.propOr([], nodeId, pinsToOmit),
@@ -302,17 +322,25 @@ const extractBoundInputsToConstNodes = def(
getMapOfNodePinValues
)(entryPointNodes);
const pinPaths = getMapOfPinPaths(nodePinValues, nodesWithCurriedPins, flatProject);
const constPinKeys = getMapOfPathsToPinKeys(CONST_NODETYPES, origProject);
const extractablePinPaths = getMapOfExtractablePinPaths(
allInputPinValues,
nodesWithCurriedPins,
flatProject
);
const constPinKeys = getMapOfPathsToPinKeys(CONST_PATCH_PATHS, origProject);
const newConstNodes = createNodesWithBoundValues(nodePinValues, pinPaths, constPinKeys);
const newConstNodes = createNodesWithBoundValues(
allInputPinValues,
extractablePinPaths,
constPinKeys
);
const newLinks = createLinksFromCurriedPins(newConstNodes, constPinKeys);
const newPatch = updatePatch(newLinks, newConstNodes, nodePinValues, entryPointPatch);
const newPatch = updatePatch(newLinks, newConstNodes, allInputPinValues, entryPointPatch);
return R.compose(
explodeEither,
Project.assocPatch(path, newPatch),
copyConstPatches(pinPaths, origProject)
copyConstPatches(extractablePinPaths, origProject)
)(flatProject);
}
);

View File

@@ -131,6 +131,8 @@ export const getCastPatchPath = (typeIn, typeOut) => `xod/core/cast-${typeIn}-to
// utils for constant patches
//
// TODO: these are no longer correct
const constantTypeRegExp =
new RegExp(`xod/core/constant-(${dataTypes.join('|')})$`);

View File

@@ -108,6 +108,75 @@ const constantPatches = {
cpp: 'struct State {};\n\n{{ GENERATED_CODE }}\n\nvoid evaluate(NodeId nid, State* state) {\n reemitValue<Outputs::VAL>(nid);\n}\n',
},
},
'xod/core/boot': {
description: 'Outputs a single pulse when the program starts',
links: {},
nodes: {
noNativeImpl: {
boundValues: {},
description: '',
id: 'noNativeImpl',
label: '',
position: {
x: 100,
y: 100,
},
type: 'xod/patch-nodes/not-implemented-in-xod',
},
ryVmUAOrvkb: {
boundValues: {
__in__: false,
},
description: '',
id: 'ryVmUAOrvkb',
label: 'BOOT',
position: {
x: 10,
y: 224,
},
type: 'xod/patch-nodes/output-pulse',
},
},
path: 'xod/core/boot',
impls: {
cpp: 'struct State {\n};\n\n{{ GENERATED_CODE }}\n\nvoid evaluate(NodeId nid, State* state) {\n emitValue<Outputs::BOOT>(nid, 1);\n}\n',
js: 'module.exports.evaluate = function(e) {\n e.fire({ BOOT: PULSE });\n};\n',
},
},
'xod/core/continuously': {
description: 'Continuously outputs pulses',
links: {},
nodes: {
BLKANE3xW: {
boundValues: {},
description: '',
id: 'BLKANE3xW',
label: '',
position: {
x: 138,
y: 120,
},
type: 'xod/patch-nodes/not-implemented-in-xod',
},
C0nt1n10Wl: {
boundValues: {
__in__: 'false',
},
description: 'Continuous pulses',
id: 'C0nt1n10Wl',
label: 'TICK',
position: {
x: 138,
y: 224,
},
type: 'xod/patch-nodes/output-pulse',
},
},
path: 'xod/core/continuously',
impls: {
cpp: 'struct State {\n};\n\n{{ GENERATED_CODE }}\n\nvoid evaluate(NodeId nid, State* state) {\n emitValue<Outputs::TICK>(nid, 1);\n setTimeout(nid, 0);\n}\n',
},
},
};
describe('extractBoundInputsToConstNodes', () => {
@@ -165,9 +234,10 @@ describe('extractBoundInputsToConstNodes', () => {
const testBoundPin = (
dataType,
boundValue,
expectedConstNodeType
expectedConstNodeType,
checkConstNodeBoundValue = true // TODO: this flag is a bit hacky
) =>
it(`should 'extract' bound ${dataType} pin to ${expectedConstNodeType} node`, () => {
it(`should extract bound '${dataType}' pin value '${boundValue}' to '${expectedConstNodeType}' node`, () => {
const boundPinKey = getInputPinKey(dataType);
const testNodeId = 'test-node';
@@ -241,22 +311,73 @@ describe('extractBoundInputsToConstNodes', () => {
`link must be to test node's ${boundPinKey} pin`
);
const maybeBoundValue = XP.getBoundValue(constantNodeOutputPinKey, constantNode);
assert(maybeBoundValue.isJust);
assert.equal(
maybeBoundValue.getOrElse(undefined),
boundValue,
`value from test node's pin must be bound to ${expectedConstNodeType}'s output`
);
if (checkConstNodeBoundValue) {
const maybeBoundValue = XP.getBoundValue(constantNodeOutputPinKey, constantNode);
assert(maybeBoundValue.isJust);
assert.equal(
maybeBoundValue.getOrElse(undefined),
boundValue,
`value from test node's pin must be bound to ${expectedConstNodeType}'s output`
);
}
});
testBoundPin(XP.PIN_TYPE.BOOLEAN, true, XP.getConstantPatchPath(XP.PIN_TYPE.BOOLEAN));
testBoundPin(XP.PIN_TYPE.NUMBER, 42, XP.getConstantPatchPath(XP.PIN_TYPE.NUMBER));
testBoundPin(XP.PIN_TYPE.STRING, 'hello', XP.getConstantPatchPath(XP.PIN_TYPE.STRING));
testBoundPin( // current behaviour. it is wrong.
testBoundPin(
XP.PIN_TYPE.PULSE,
XP.INPUT_PULSE_PIN_BINDING_OPTIONS.ON_BOOT,
XP.getConstantPatchPath(XP.PIN_TYPE.BOOLEAN)
'xod/core/boot',
false
);
testBoundPin(
XP.PIN_TYPE.PULSE,
XP.INPUT_PULSE_PIN_BINDING_OPTIONS.CONTINUOUSLY,
'xod/core/continuously',
false
);
it('discards any other values bound to pulse pins', () => {
const dataType = XP.PIN_TYPE.PULSE;
const boundValue = XP.INPUT_PULSE_PIN_BINDING_OPTIONS.NEVER;
const boundPinKey = getInputPinKey(dataType);
const testNodeId = 'test-node';
const project = Helper.defaultizeProject({
patches: R.merge(constantPatches, {
[mainPatchPath]: {
nodes: {
[testNodeId]: {
type: testPatchPath,
boundValues: {
[boundPinKey]: boundValue,
},
},
},
},
[testPatchPath]: testPatch,
}),
});
const transformedProject = XP.extractBoundInputsToConstNodes(project, mainPatchPath, project);
const patch = XP.getPatchByPathUnsafe(mainPatchPath, transformedProject);
const nodesByNodeType = R.compose(
R.indexBy(XP.getNodeType),
XP.listNodes
)(patch);
assert.lengthOf(R.values(nodesByNodeType), 1, 'no new nodes must be created');
const testNode = nodesByNodeType[testPatchPath];
assert.isTrue(
XP.getBoundValue(boundPinKey, testNode).isNothing,
`bound value for ${boundPinKey} must be deleted from test node`
);
const links = XP.listLinks(patch);
assert.lengthOf(links, 0, 'no links must be created');
});
});

View File

@@ -631,7 +631,7 @@ template <typename T> class List {
*
=============================================================================*/
#define NODE_COUNT 8
#define NODE_COUNT 5
#define MAX_OUTPUT_COUNT 1
// Uncomment to trace the program in the Serial Monitor
@@ -1069,32 +1069,6 @@ void evaluate(NodeId nid, State* state) {
} // namespace xod__core__constant_number
//-----------------------------------------------------------------------------
// xod/core/constant_boolean implementation
//-----------------------------------------------------------------------------
namespace xod__core__constant_boolean {
struct State {
};
struct Storage {
State state;
OutputPin<Logic> output_VAL;
};
namespace Inputs {
}
namespace Outputs {
using VAL = OutputDescriptor<Logic, offsetof(Storage, output_VAL), 0>;
}
void evaluate(NodeId nid, State* state) {
reemitValue<Outputs::VAL>(nid);
}
} // namespace xod__core__constant_boolean
} // namespace _program
/*=============================================================================
@@ -1111,22 +1085,22 @@ namespace _program {
xod__core__clock::Storage storage_0 = {
{ }, // state
{ NodeId(3), xod__core__constant_number::Outputs::VAL::KEY }, // input_IVAL
{ NodeId(4), xod__core__constant_boolean::Outputs::VAL::KEY }, // input_RST
{ NO_NODE, 0 }, // input_RST
{ false, links_0_TICK } // output_TICK
};
xod__core__digital_output::Storage storage_1 = {
{ }, // state
{ NodeId(5), xod__core__constant_number::Outputs::VAL::KEY }, // input_PORT
{ NodeId(4), xod__core__constant_number::Outputs::VAL::KEY }, // input_PORT
{ NodeId(2), xod__core__flip_flop::Outputs::MEM::KEY }, // input_SIG
};
NodeId links_2_MEM[] = { 1, NO_NODE };
xod__core__flip_flop::Storage storage_2 = {
{ }, // state
{ NodeId(7), xod__core__constant_boolean::Outputs::VAL::KEY }, // input_SET
{ NO_NODE, 0 }, // input_SET
{ NodeId(0), xod__core__clock::Outputs::TICK::KEY }, // input_TGL
{ NodeId(6), xod__core__constant_boolean::Outputs::VAL::KEY }, // input_RST
{ NO_NODE, 0 }, // input_RST
{ false, links_2_MEM } // output_MEM
};
@@ -1136,28 +1110,10 @@ namespace _program {
{ 0.25, links_3_VAL } // output_VAL
};
NodeId links_4_VAL[] = { 0, NO_NODE };
xod__core__constant_boolean::Storage storage_4 = {
NodeId links_4_VAL[] = { 1, NO_NODE };
xod__core__constant_number::Storage storage_4 = {
{ }, // state
{ false, links_4_VAL } // output_VAL
};
NodeId links_5_VAL[] = { 1, NO_NODE };
xod__core__constant_number::Storage storage_5 = {
{ }, // state
{ 13, links_5_VAL } // output_VAL
};
NodeId links_6_VAL[] = { 2, NO_NODE };
xod__core__constant_boolean::Storage storage_6 = {
{ }, // state
{ false, links_6_VAL } // output_VAL
};
NodeId links_7_VAL[] = { 2, NO_NODE };
xod__core__constant_boolean::Storage storage_7 = {
{ }, // state
{ false, links_7_VAL } // output_VAL
{ 13, links_4_VAL } // output_VAL
};
void* storages[NODE_COUNT] = {
@@ -1165,10 +1121,7 @@ namespace _program {
&storage_1,
&storage_2,
&storage_3,
&storage_4,
&storage_5,
&storage_6,
&storage_7
&storage_4
};
EvalFuncPtr evaluationFuncs[NODE_COUNT] = {
@@ -1176,16 +1129,10 @@ namespace _program {
(EvalFuncPtr)&xod__core__digital_output::evaluate,
(EvalFuncPtr)&xod__core__flip_flop::evaluate,
(EvalFuncPtr)&xod__core__constant_number::evaluate,
(EvalFuncPtr)&xod__core__constant_boolean::evaluate,
(EvalFuncPtr)&xod__core__constant_number::evaluate,
(EvalFuncPtr)&xod__core__constant_boolean::evaluate,
(EvalFuncPtr)&xod__core__constant_boolean::evaluate
(EvalFuncPtr)&xod__core__constant_number::evaluate
};
DirtyFlags dirtyFlags[NODE_COUNT] = {
DirtyFlags(-1),
DirtyFlags(-1),
DirtyFlags(-1),
DirtyFlags(-1),
DirtyFlags(-1),
DirtyFlags(-1),
@@ -1194,7 +1141,7 @@ namespace _program {
};
NodeId topology[NODE_COUNT] = {
3, 4, 5, 6, 7, 0, 2, 1
3, 4, 0, 2, 1
};
TimeMs schedule[NODE_COUNT] = { 0 };

View File

@@ -631,7 +631,7 @@ template <typename T> class List {
*
=============================================================================*/
#define NODE_COUNT 13
#define NODE_COUNT 12
#define MAX_OUTPUT_COUNT 1
// Uncomment to trace the program in the Serial Monitor
@@ -1141,32 +1141,6 @@ void evaluate(NodeId nid, State* state) {
} // namespace xod__core__constant_string
//-----------------------------------------------------------------------------
// xod/core/constant_boolean implementation
//-----------------------------------------------------------------------------
namespace xod__core__constant_boolean {
struct State {
};
struct Storage {
State state;
OutputPin<Logic> output_VAL;
};
namespace Inputs {
}
namespace Outputs {
using VAL = OutputDescriptor<Logic, offsetof(Storage, output_VAL), 0>;
}
void evaluate(NodeId nid, State* state) {
reemitValue<Outputs::VAL>(nid);
}
} // namespace xod__core__constant_boolean
} // namespace _program
/*=============================================================================
@@ -1202,7 +1176,7 @@ namespace _program {
xod__core__clock::Storage storage_2 = {
{ }, // state
{ NodeId(11), xod__core__constant_number::Outputs::VAL::KEY }, // input_IVAL
{ NodeId(12), xod__core__constant_boolean::Outputs::VAL::KEY }, // input_RST
{ NO_NODE, 0 }, // input_RST
{ false, links_2_TICK } // output_TICK
};
@@ -1261,12 +1235,6 @@ namespace _program {
{ 0.01, links_11_VAL } // output_VAL
};
NodeId links_12_VAL[] = { 2, NO_NODE };
xod__core__constant_boolean::Storage storage_12 = {
{ }, // state
{ false, links_12_VAL } // output_VAL
};
void* storages[NODE_COUNT] = {
&storage_0,
&storage_1,
@@ -1279,8 +1247,7 @@ namespace _program {
&storage_8,
&storage_9,
&storage_10,
&storage_11,
&storage_12
&storage_11
};
EvalFuncPtr evaluationFuncs[NODE_COUNT] = {
@@ -1295,8 +1262,7 @@ namespace _program {
(EvalFuncPtr)&xod__core__constant_number::evaluate,
(EvalFuncPtr)&xod__core__constant_number::evaluate,
(EvalFuncPtr)&xod__core__constant_number::evaluate,
(EvalFuncPtr)&xod__core__constant_number::evaluate,
(EvalFuncPtr)&xod__core__constant_boolean::evaluate
(EvalFuncPtr)&xod__core__constant_number::evaluate
};
DirtyFlags dirtyFlags[NODE_COUNT] = {
@@ -1311,12 +1277,11 @@ namespace _program {
DirtyFlags(-1),
DirtyFlags(-1),
DirtyFlags(-1),
DirtyFlags(-1),
DirtyFlags(-1)
};
NodeId topology[NODE_COUNT] = {
4, 5, 6, 7, 8, 9, 10, 11, 12, 2, 0, 3, 1
4, 5, 6, 7, 8, 9, 10, 11, 2, 0, 3, 1
};
TimeMs schedule[NODE_COUNT] = { 0 };

View File

@@ -631,7 +631,7 @@ template <typename T> class List {
*
=============================================================================*/
#define NODE_COUNT 13
#define NODE_COUNT 11
#define MAX_OUTPUT_COUNT 2
// Uncomment to trace the program in the Serial Monitor
@@ -1150,32 +1150,6 @@ void evaluate(NodeId nid, State* state) {
} // namespace xod__core__constant_number
//-----------------------------------------------------------------------------
// xod/core/constant_boolean implementation
//-----------------------------------------------------------------------------
namespace xod__core__constant_boolean {
struct State {
};
struct Storage {
State state;
OutputPin<Logic> output_VAL;
};
namespace Inputs {
}
namespace Outputs {
using VAL = OutputDescriptor<Logic, offsetof(Storage, output_VAL), 0>;
}
void evaluate(NodeId nid, State* state) {
reemitValue<Outputs::VAL>(nid);
}
} // namespace xod__core__constant_boolean
} // namespace _program
/*=============================================================================
@@ -1192,7 +1166,7 @@ namespace _program {
xod__core__clock::Storage storage_0 = {
{ }, // state
{ NodeId(7), xod__core__constant_number::Outputs::VAL::KEY }, // input_IVAL
{ NodeId(8), xod__core__constant_boolean::Outputs::VAL::KEY }, // input_RST
{ NO_NODE, 0 }, // input_RST
{ false, links_0_TICK } // output_TICK
};
@@ -1209,7 +1183,7 @@ namespace _program {
NodeId links_2_SIG[] = { 1, NO_NODE };
xod__core__digital_input::Storage storage_2 = {
{ }, // state
{ NodeId(9), xod__core__constant_number::Outputs::VAL::KEY }, // input_PORT
{ NodeId(8), xod__core__constant_number::Outputs::VAL::KEY }, // input_PORT
{ NodeId(0), xod__core__clock::Outputs::TICK::KEY }, // input_UPD
{ false, links_2_SIG } // output_SIG
};
@@ -1218,7 +1192,7 @@ namespace _program {
xod__core__flip_flop::Storage storage_3 = {
{ }, // state
{ NodeId(4), xod__core__gate::Outputs::F::KEY }, // input_SET
{ NodeId(10), xod__core__constant_boolean::Outputs::VAL::KEY }, // input_TGL
{ NO_NODE, 0 }, // input_TGL
{ NodeId(1), xod__core__gate::Outputs::F::KEY }, // input_RST
{ false, links_3_MEM } // output_MEM
};
@@ -1236,14 +1210,14 @@ namespace _program {
NodeId links_5_SIG[] = { 4, NO_NODE };
xod__core__digital_input::Storage storage_5 = {
{ }, // state
{ NodeId(11), xod__core__constant_number::Outputs::VAL::KEY }, // input_PORT
{ NodeId(9), xod__core__constant_number::Outputs::VAL::KEY }, // input_PORT
{ NodeId(0), xod__core__clock::Outputs::TICK::KEY }, // input_UPD
{ false, links_5_SIG } // output_SIG
};
xod__core__digital_output::Storage storage_6 = {
{ }, // state
{ NodeId(12), xod__core__constant_number::Outputs::VAL::KEY }, // input_PORT
{ NodeId(10), xod__core__constant_number::Outputs::VAL::KEY }, // input_PORT
{ NodeId(3), xod__core__flip_flop::Outputs::MEM::KEY }, // input_SIG
};
@@ -1253,34 +1227,22 @@ namespace _program {
{ 0.02, links_7_VAL } // output_VAL
};
NodeId links_8_VAL[] = { 0, NO_NODE };
xod__core__constant_boolean::Storage storage_8 = {
NodeId links_8_VAL[] = { 2, NO_NODE };
xod__core__constant_number::Storage storage_8 = {
{ }, // state
{ false, links_8_VAL } // output_VAL
{ 12, links_8_VAL } // output_VAL
};
NodeId links_9_VAL[] = { 2, NO_NODE };
NodeId links_9_VAL[] = { 5, NO_NODE };
xod__core__constant_number::Storage storage_9 = {
{ }, // state
{ 12, links_9_VAL } // output_VAL
{ 11, links_9_VAL } // output_VAL
};
NodeId links_10_VAL[] = { 3, NO_NODE };
xod__core__constant_boolean::Storage storage_10 = {
NodeId links_10_VAL[] = { 6, NO_NODE };
xod__core__constant_number::Storage storage_10 = {
{ }, // state
{ false, links_10_VAL } // output_VAL
};
NodeId links_11_VAL[] = { 5, NO_NODE };
xod__core__constant_number::Storage storage_11 = {
{ }, // state
{ 11, links_11_VAL } // output_VAL
};
NodeId links_12_VAL[] = { 6, NO_NODE };
xod__core__constant_number::Storage storage_12 = {
{ }, // state
{ 13, links_12_VAL } // output_VAL
{ 13, links_10_VAL } // output_VAL
};
void* storages[NODE_COUNT] = {
@@ -1294,9 +1256,7 @@ namespace _program {
&storage_7,
&storage_8,
&storage_9,
&storage_10,
&storage_11,
&storage_12
&storage_10
};
EvalFuncPtr evaluationFuncs[NODE_COUNT] = {
@@ -1308,9 +1268,7 @@ namespace _program {
(EvalFuncPtr)&xod__core__digital_input::evaluate,
(EvalFuncPtr)&xod__core__digital_output::evaluate,
(EvalFuncPtr)&xod__core__constant_number::evaluate,
(EvalFuncPtr)&xod__core__constant_boolean::evaluate,
(EvalFuncPtr)&xod__core__constant_number::evaluate,
(EvalFuncPtr)&xod__core__constant_boolean::evaluate,
(EvalFuncPtr)&xod__core__constant_number::evaluate,
(EvalFuncPtr)&xod__core__constant_number::evaluate
};
@@ -1326,13 +1284,11 @@ namespace _program {
DirtyFlags(-1),
DirtyFlags(-1),
DirtyFlags(-1),
DirtyFlags(-1),
DirtyFlags(-1),
DirtyFlags(-1)
};
NodeId topology[NODE_COUNT] = {
7, 8, 9, 10, 11, 12, 0, 2, 5, 1, 4, 3, 6
7, 8, 9, 10, 0, 2, 5, 1, 4, 3, 6
};
TimeMs schedule[NODE_COUNT] = { 0 };