From 1e643ea741ca5d23ea912aab7d2b6370e3ee8052 Mon Sep 17 00:00:00 2001 From: Evgeny Kochetkov Date: Tue, 11 Jul 2017 14:56:04 +0300 Subject: [PATCH] =?UTF-8?q?feat(xod-project):=20support=20binding=20input?= =?UTF-8?q?=20pulses=20to=20=E2=80=98ON=5FBOOT=E2=80=99=20and=20=E2=80=98C?= =?UTF-8?q?ONTINUOUSLY=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/extractBoundInputsToConstNodes.js | 114 ++++++++------ packages/xod-project/src/patchPathUtils.js | 2 + .../extractBoundInputsToConstNodes.spec.js | 143 ++++++++++++++++-- workspace/blink/__fixtures__/arduino.cpp | 75 ++------- workspace/lcd-time/__fixtures__/arduino.cpp | 45 +----- .../__fixtures__/arduino.cpp | 76 ++-------- 6 files changed, 237 insertions(+), 218 deletions(-) diff --git a/packages/xod-project/src/extractBoundInputsToConstNodes.js b/packages/xod-project/src/extractBoundInputsToConstNodes.js index e862e534..7d54d2c1 100644 --- a/packages/xod-project/src/extractBoundInputsToConstNodes.js +++ b/packages/xod-project/src/extractBoundInputsToConstNodes.js @@ -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); } ); diff --git a/packages/xod-project/src/patchPathUtils.js b/packages/xod-project/src/patchPathUtils.js index 60054a77..5c8fe0db 100644 --- a/packages/xod-project/src/patchPathUtils.js +++ b/packages/xod-project/src/patchPathUtils.js @@ -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('|')})$`); diff --git a/packages/xod-project/test/extractBoundInputsToConstNodes.spec.js b/packages/xod-project/test/extractBoundInputsToConstNodes.spec.js index 0e96eeb6..87017477 100644 --- a/packages/xod-project/test/extractBoundInputsToConstNodes.spec.js +++ b/packages/xod-project/test/extractBoundInputsToConstNodes.spec.js @@ -108,6 +108,75 @@ const constantPatches = { cpp: 'struct State {};\n\n{{ GENERATED_CODE }}\n\nvoid evaluate(NodeId nid, State* state) {\n reemitValue(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(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(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'); + }); }); diff --git a/workspace/blink/__fixtures__/arduino.cpp b/workspace/blink/__fixtures__/arduino.cpp index 99a9184a..f2917cec 100644 --- a/workspace/blink/__fixtures__/arduino.cpp +++ b/workspace/blink/__fixtures__/arduino.cpp @@ -631,7 +631,7 @@ template 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 output_VAL; -}; - -namespace Inputs { -} - -namespace Outputs { - using VAL = OutputDescriptor; -} - -void evaluate(NodeId nid, State* state) { - reemitValue(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 }; diff --git a/workspace/lcd-time/__fixtures__/arduino.cpp b/workspace/lcd-time/__fixtures__/arduino.cpp index 45b78460..bd9ef4cd 100644 --- a/workspace/lcd-time/__fixtures__/arduino.cpp +++ b/workspace/lcd-time/__fixtures__/arduino.cpp @@ -631,7 +631,7 @@ template 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 output_VAL; -}; - -namespace Inputs { -} - -namespace Outputs { - using VAL = OutputDescriptor; -} - -void evaluate(NodeId nid, State* state) { - reemitValue(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 }; diff --git a/workspace/two-button-switch/__fixtures__/arduino.cpp b/workspace/two-button-switch/__fixtures__/arduino.cpp index 8bd25b5f..f478e117 100644 --- a/workspace/two-button-switch/__fixtures__/arduino.cpp +++ b/workspace/two-button-switch/__fixtures__/arduino.cpp @@ -631,7 +631,7 @@ template 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 output_VAL; -}; - -namespace Inputs { -} - -namespace Outputs { - using VAL = OutputDescriptor; -} - -void evaluate(NodeId nid, State* state) { - reemitValue(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 };