From b744491dd2b524463a7a318a1635af5dd98510b2 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Wed, 27 Apr 2016 10:31:19 +0100 Subject: [PATCH] Ensure config nodes are instantiated in the right order --- red/runtime/nodes/flows/Flow.js | 33 +++++++++++-- test/red/runtime/nodes/flows/Flow_spec.js | 57 ++++++++++++++++++++++- 2 files changed, 84 insertions(+), 6 deletions(-) diff --git a/red/runtime/nodes/flows/Flow.js b/red/runtime/nodes/flows/Flow.js index edeea1943..72b42eaf3 100644 --- a/red/runtime/nodes/flows/Flow.js +++ b/red/runtime/nodes/flows/Flow.js @@ -36,17 +36,40 @@ function Flow(global,flow) { var id; catchNodeMap = {}; statusNodeMap = {}; - for (id in flow.configs) { - if (flow.configs.hasOwnProperty(id)) { - node = flow.configs[id]; - if (!activeNodes[id]) { + + var configNodes = Object.keys(flow.configs); + var configNodeAttempts = {}; + while(configNodes.length > 0) { + id = configNodes.shift(); + node = flow.configs[id]; + if (!activeNodes[id]) { + var readyToCreate = true; + // This node doesn't exist. + // Check it doesn't reference another non-existent config node + for (var prop in node) { + if (node.hasOwnProperty(prop) && prop !== 'id' && prop !== 'wires' && prop !== '_users' && flow.configs[node[prop]]) { + if (!activeNodes[node[prop]]) { + // References a non-existent config node + // Add it to the back of the list to try again later + configNodes.push(id); + configNodeAttempts[id] = (configNodeAttempts[id]||0)+1; + if (configNodeAttempts[id] === 100) { + throw new Error("Circular config node dependency detected: "+id); + } + readyToCreate = false; + break; + } + } + } + if (readyToCreate) { newNode = createNode(node.type,node); if (newNode) { activeNodes[id] = newNode; } } } - } + }; + if (diff && diff.rewired) { for (var j=0;j