diff --git a/ChartingSpace/TimeMachine.js b/ChartingSpace/TimeMachine.js index 9257df6a8..b9fa5471f 100644 --- a/ChartingSpace/TimeMachine.js +++ b/ChartingSpace/TimeMachine.js @@ -672,8 +672,9 @@ function newTimeMachine() { for (let i = 0; i < thisObject.timelineCharts.length; i++) { let timelinechart = thisObject.timelineCharts[i] if (timelinechart.layersManager !== undefined) { - for (let j = 0; j < timelinechart.layersManager.layers.length; j++) { - let layer = timelinechart.layersManager.layers[j] + let layers = timelinechart.layersManager.layers + for (let j = 0; j < layers.length; j++) { + let layer = layers[j] exchangeMarket = { exchangeName: layer.exchange.name, diff --git a/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js b/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js index 7284030f1..d339a10e8 100644 --- a/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js +++ b/DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js @@ -78,6 +78,8 @@ function newProtocolNode() { let newLightingPath = getNewLightingPath(lightingPath, node.type, node.payload.parentNode.type) if (newLightingPath !== undefined) { object.parentNode = getProtocolNode(node.payload.parentNode, removePersonalData, parseConfig, includeIds, includePayload, includeReferencesInSavedPayload, newLightingPath) + } else { + let newLightingPath = getNewLightingPath(lightingPath, node.type, node.payload.parentNode.type) } } if (node.payload.referenceParent !== undefined) { @@ -121,6 +123,16 @@ function newProtocolNode() { let currentNodePosition = lightingPath.indexOf('->' + currentNodeType + '->') let nextNodePosition = lightingPath.indexOf('->' + nextNodeType + '->') + /* + In some situations, the current and next node are of the same type. + When that happens, we need to search for the second instance of that type + at the lighting path. + */ + if (currentNodeType === nextNodeType) { + let tempLightingPath = lightingPath.substring(currentNodePosition + currentNodeType.length, lightingPath.length + 1) + nextNodePosition = tempLightingPath.indexOf('->' + nextNodeType + '->') + } + let newLightingPath = lightingPath.substring(nextNodePosition, lightingPath.length + 1) if (nextNodePosition > currentNodePosition) { diff --git a/Panels/Layer.js b/Panels/Layer.js index eb04637e3..f054d6a62 100644 --- a/Panels/Layer.js +++ b/Panels/Layer.js @@ -153,7 +153,11 @@ function newLayer() { let functionLibraryProtocolNode = newProtocolNode() let lightingPath = '->Layer->' + - 'Data Product->Single Market Data->Exchange Data Products->' + + 'Data Product->' + + 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + + 'Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->Data Product Folder->' + + 'Bot Products->Data Mine Products->' + + 'Single Market Data->Exchange Data Products->' + 'Session Reference->Session Independent Data->Session Based Data->Exchange Sessions->Session Based Data->Data Storage->Network Node->' + 'Data Storage->Network Node->' + 'Backtesting Session->Paper Trading Session->Fordward Testing Session->Live Trading Session->' + @@ -162,6 +166,8 @@ function newLayer() { 'Market Quoted Asset->Asset->' + 'Exchange Markets->Crypto Exchange->' + 'Product Definition->' + + 'Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->' + + 'Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->Product Definition Folder->' + 'Sensor Bot->Indicator Bot->Trading Bot->' + 'Data Mine->' + 'Dataset Definition->' + @@ -180,51 +186,80 @@ function newLayer() { 'Nodes Highlights->Nodes Values->Nodes Errors->Nodes Warnings->Nodes Infos->Nodes Status->Nodes Progress->Nodes Running->Nodes Announcements->Record Values->' thisObject.definition = functionLibraryProtocolNode.getProtocolNode(thisObject.payload.node, false, true, true, false, false, lightingPath) + /* Without this I can not continue, because I can not even show error. */ + if (thisObject.payload === undefined) { + console.log(MODULE_NAME + ' ' + 'thisObject.payload === undefined') + return + } + if (thisObject.payload.uiObject === undefined) { + console.log(MODULE_NAME + ' ' + 'thisObject.payload.uiObject === undefined') + return + } + if (thisObject.payload.node === undefined) { + console.log(MODULE_NAME + ' ' + 'thisObject.payload.node === undefined') + return + } + /* Here we validate that we have all the needed information */ - if (thisObject.definition.referenceParent === undefined) { return } // Data Product - if (thisObject.definition.referenceParent.parentNode === undefined) { return } // Single Market Data - if (thisObject.definition.referenceParent.parentNode.referenceParent === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent === undefined) { return } - if (thisObject.definition.referenceParent.referenceParent === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode === undefined) { return } - if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode === undefined) { return } + if (findNodeInNodeBranch(thisObject.definition, 'Data Product') === undefined) { + thisObject.payload.uiObject.setErrorMessage('Data Product not Found') + return + } + if (findNodeInNodeBranch(thisObject.definition, 'Product Definition') === undefined) { + thisObject.payload.uiObject.setErrorMessage('Product Definition not Found') + return + } + if (findNodeInNodeBranch(thisObject.definition, 'Data Mine') === undefined) { + thisObject.payload.uiObject.setErrorMessage('Data Mine not Found') + return + } + if (findNodeInNodeBranch(thisObject.definition, 'Market') === undefined) { + thisObject.payload.uiObject.setErrorMessage('Market not Found') + return + } + + thisObject.exchange = findNodeInNodeBranch(thisObject.definition, 'Crypto Exchange') + if (thisObject.exchange === undefined) { + thisObject.payload.uiObject.setErrorMessage('Crypto Exchange not Found') + return + } + + thisObject.baseAsset = findNodeInNodeBranch(thisObject.definition, 'Market Base Asset') + if (thisObject.baseAsset !== undefined) { + thisObject.baseAsset = thisObject.baseAsset.referenceParent + } + if (thisObject.baseAsset === undefined) { + thisObject.payload.uiObject.setErrorMessage('Market Base Asset not Found') + return + } + + thisObject.quotedAsset = findNodeInNodeBranch(thisObject.definition, 'Market Quoted Asset') + if (thisObject.quotedAsset !== undefined) { + thisObject.quotedAsset = thisObject.quotedAsset.referenceParent + } + if (thisObject.quotedAsset === undefined) { + thisObject.payload.uiObject.setErrorMessage('Market Quoted Asset not Found') + return + } + + thisObject.plotterModule = findNodeInNodeBranch(thisObject.definition, 'Plotter Module') + if (thisObject.plotterModule === undefined) { + thisObject.payload.uiObject.setErrorMessage('Market Quoted Asset not Found') + return + } + + thisObject.networkNode = findNodeInNodeBranch(thisObject.definition, 'Network Node') + if (thisObject.networkNode === undefined) { + thisObject.payload.uiObject.setErrorMessage('Network Node not Found') + return + } /* Lets listen to our own events to react when we have a Mouse Click */ onMouseClickEventSuscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) /* Get ready to draw this layer */ - thisObject.baseAsset = thisObject.definition.referenceParent.parentNode.referenceParent.baseAsset.referenceParent - thisObject.quotedAsset = thisObject.definition.referenceParent.parentNode.referenceParent.quotedAsset.referenceParent thisObject.market = thisObject.baseAsset.config.codeName + '/' + thisObject.quotedAsset.config.codeName - thisObject.exchange = thisObject.definition.referenceParent.parentNode.referenceParent.parentNode.parentNode - /* Some basic validations. */ - if (thisObject.definition.referenceParent === undefined) { - console.log('[WARN] Could not start plotter because ' + thisObject.definition.type + ' ' + thisObject.definition.name + ' does not have a Reference Parent.') - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - - if (thisObject.definition.referenceParent.referenceParent === undefined) { - console.log('[WARN] Could not start plotter because ' + thisObject.definition.referenceParent.type + ' ' + thisObject.definition.referenceParent.name + ' does not have a Reference Parent.') - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - - if (thisObject.definition.referenceParent.referenceParent.referenceParent === undefined) { - console.log('[WARN] Could not start plotter because ' + thisObject.definition.referenceParent.referenceParent.type + ' ' + thisObject.definition.referenceParent.referenceParent.name + ' does not have a Reference Parent.') - callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) - return - } - - thisObject.plotterModule = thisObject.definition.referenceParent.referenceParent.referenceParent thisObject.exchangeIcon = getIcon(thisObject.exchange) if (thisObject.plotterModule.config.icon !== undefined) { @@ -234,12 +269,6 @@ function newLayer() { thisObject.baseAssetIcon = getIcon(thisObject.baseAsset) thisObject.quotedAssetIcon = getIcon(thisObject.quotedAsset) - if (thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.type === 'Data Storage') { - thisObject.networkNode = thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode - } else { - thisObject.networkNode = thisObject.definition.referenceParent.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode - } - function getIcon(node) { let nodeDefinition = getNodeDefinition(node) let iconName diff --git a/Panels/LayersPanel.js b/Panels/LayersPanel.js index fc8438d73..beb42bad5 100644 --- a/Panels/LayersPanel.js +++ b/Panels/LayersPanel.js @@ -375,8 +375,9 @@ function newLayersPanel() { function syncWithDesignerLayers() { if (thisObject.payload.node === undefined) { return } let layerManager = thisObject.payload.node - for (let p = 0; p < layerManager.layers.length; p++) { - let layerNode = layerManager.layers[p] + let layers = nodeBranchToArray(layerManager, 'Layer') + for (let p = 0; p < layers.length; p++) { + let layerNode = layers[p] let found = removeFromLocalLayers(layerNode.id) if (found !== true) { diff --git a/Utilities/Branches.js b/Utilities/Branches.js new file mode 100644 index 000000000..b82686545 --- /dev/null +++ b/Utilities/Branches.js @@ -0,0 +1,92 @@ +function nodeBranchToArray(node, nodeType) { + /* + This function scans a node branch for a certain node type and + return an array of with all the nodes of that type found. + */ + let resultArray = [] + scanNodeBranch(node, nodeType) + return resultArray + + function scanNodeBranch(startingNode) { + let nodeDefinition = APP_SCHEMA_MAP.get(startingNode.type) + if (nodeDefinition === undefined) { return } + + if (startingNode.type === nodeType) { + resultArray.push(startingNode) + return + } + + if (nodeDefinition.properties === undefined) { return } + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + scanNodeBranch(startingNode[property.name]) + } + break + case 'array': { + let startingNodePropertyArray = startingNode[property.name] + for (let m = 0; m < startingNodePropertyArray.length; m++) { + scanNodeBranch(startingNodePropertyArray[m]) + } + break + } + } + } + } +} + +function findNodeInNodeBranch(node, nodeType) { + /* + This function scans a node branch for a certain node type and + returns the first instance found. + */ + let nodeFound + scanNodeBranch(node, nodeType) + return nodeFound + + function scanNodeBranch(startingNode) { + if (startingNode === undefined) { return } + if (nodeFound !== undefined) { return } + + let nodeDefinition = APP_SCHEMA_MAP.get(startingNode.type) + if (nodeDefinition === undefined) { return } + + if (startingNode.type === nodeType) { + nodeFound = startingNode + return + } + + /* We scan through this node children */ + if (nodeDefinition.properties !== undefined) { + for (let i = 0; i < nodeDefinition.properties.length; i++) { + let property = nodeDefinition.properties[i] + + switch (property.type) { + case 'node': { + scanNodeBranch(startingNode[property.name]) + } + break + case 'array': { + let startingNodePropertyArray = startingNode[property.name] + if (startingNodePropertyArray !== undefined) { + for (let m = 0; m < startingNodePropertyArray.length; m++) { + scanNodeBranch(startingNodePropertyArray[m]) + } + } + break + } + } + } + } + /* We scan parents nodes. */ + if (startingNode.parentNode !== undefined) { + scanNodeBranch(startingNode.parentNode) + } + /* We scan reference parents too. */ + if (startingNode.referenceParent !== undefined) { + scanNodeBranch(startingNode.referenceParent) + } + } +} \ No newline at end of file diff --git a/Utilities/Folders.js b/Utilities/Folders.js index 686f1af77..38cc08666 100644 --- a/Utilities/Folders.js +++ b/Utilities/Folders.js @@ -90,4 +90,4 @@ function asymetricalFolderStructureCloning( } } } -} \ No newline at end of file +}