Visual Scripting Modules moved in from Foundations
This commit is contained in:
1 parent
cd44cc0d72
commit
1f4fee8904
19 files changed
+109
-100
No files matched your search
@@ -0,0 +1,222 @@
|
||||
function newVisualScriptingFunctionLibraryChainAttachDetach() {
|
||||
let thisObject = {
|
||||
chainDetachNode: chainDetachNode,
|
||||
chainAttachNode: chainAttachNode
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function chainDetachNode(node, rootNodes) {
|
||||
if (node.payload.parentNode === undefined) { return }
|
||||
switch (node.type) {
|
||||
case 'Phase': {
|
||||
let payload = node.payload
|
||||
for (let i = 0; i < payload.parentNode.phases.length; i++) {
|
||||
let phase = payload.parentNode.phases[i]
|
||||
if (phase.id === node.id) {
|
||||
if (i < payload.parentNode.phases.length - 1) {
|
||||
let nextPhase = payload.parentNode.phases[i + 1]
|
||||
if (i > 0) {
|
||||
let previousPhase = payload.parentNode.phases[i - 1]
|
||||
nextPhase.payload.chainParent = previousPhase
|
||||
} else {
|
||||
nextPhase.payload.chainParent = payload.parentNode
|
||||
}
|
||||
}
|
||||
payload.parentNode.phases.splice(i, 1)
|
||||
completeDetachment(node, rootNodes)
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
default: {
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument !== undefined) {
|
||||
/* Detach from parent */
|
||||
if (node.payload.parentNode !== undefined) {
|
||||
let parentSchemaDocument = getSchemaDocument(node.payload.parentNode)
|
||||
if (parentSchemaDocument !== undefined) {
|
||||
if (parentSchemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < parentSchemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = parentSchemaDocument.childrenNodesProperties[i]
|
||||
if (schemaDocument.propertyNameAtParent === property.name) {
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
node.payload.parentNode[property.name] = undefined
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let nodePropertyArray = node.payload.parentNode[property.name]
|
||||
if (nodePropertyArray !== undefined) {
|
||||
for (let j = 0; j < nodePropertyArray.length; j++) {
|
||||
let arrayItem = nodePropertyArray[j]
|
||||
if (arrayItem.id === node.id) {
|
||||
nodePropertyArray.splice(j, 1)
|
||||
j--
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
completeDetachment(node, rootNodes)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function chainAttachNode(node, attachToNode, rootNodes) {
|
||||
switch (node.type) {
|
||||
|
||||
case 'Exchange Account Key': {
|
||||
node.payload.parentNode = attachToNode
|
||||
node.payload.chainParent = attachToNode
|
||||
if (node.payload.parentNode.keys !== undefined) {
|
||||
node.payload.parentNode.keys.push(node)
|
||||
} else {
|
||||
node.payload.parentNode.key = node
|
||||
}
|
||||
completeAttachment(node, rootNodes)
|
||||
}
|
||||
break
|
||||
|
||||
case 'Phase': {
|
||||
switch (attachToNode.type) {
|
||||
case 'Stop': {
|
||||
node.payload.parentNode = attachToNode
|
||||
if (attachToNode.phases.length > 0) {
|
||||
let phase = attachToNode.phases[attachToNode.phases.length - 1]
|
||||
node.payload.chainParent = phase
|
||||
} else {
|
||||
node.payload.chainParent = attachToNode
|
||||
}
|
||||
attachToNode.phases.push(node)
|
||||
completeAttachment(node, rootNodes)
|
||||
}
|
||||
break
|
||||
case 'Take Profit': {
|
||||
node.payload.parentNode = attachToNode
|
||||
if (attachToNode.phases.length > 0) {
|
||||
let phase = attachToNode.phases[attachToNode.phases.length - 1]
|
||||
node.payload.chainParent = phase
|
||||
} else {
|
||||
node.payload.chainParent = attachToNode
|
||||
}
|
||||
attachToNode.phases.push(node)
|
||||
completeAttachment(node, rootNodes)
|
||||
}
|
||||
break
|
||||
case 'Initial Stop': {
|
||||
if (attachToNode.phases.length >= 1) {
|
||||
return
|
||||
}
|
||||
|
||||
node.payload.parentNode = attachToNode
|
||||
if (attachToNode.phases.length > 0) {
|
||||
let phase = attachToNode.phases[attachToNode.phases.length - 1]
|
||||
node.payload.chainParent = phase
|
||||
} else {
|
||||
node.payload.chainParent = attachToNode
|
||||
}
|
||||
attachToNode.phases.push(node)
|
||||
completeAttachment(node, rootNodes)
|
||||
}
|
||||
break
|
||||
case 'Initial Take Profit': {
|
||||
if (attachToNode.phases.length >= 1) {
|
||||
return
|
||||
}
|
||||
node.payload.parentNode = attachToNode
|
||||
if (attachToNode.phases.length > 0) {
|
||||
let phase = attachToNode.phases[attachToNode.phases.length - 1]
|
||||
node.payload.chainParent = phase
|
||||
} else {
|
||||
node.payload.chainParent = attachToNode
|
||||
}
|
||||
attachToNode.phases.push(node)
|
||||
completeAttachment(node, rootNodes)
|
||||
}
|
||||
break
|
||||
case 'Phase': {
|
||||
node.payload.parentNode = attachToNode.payload.parentNode
|
||||
for (let i = 0; i < node.payload.parentNode.phases.length; i++) {
|
||||
let phase = node.payload.parentNode.phases[i]
|
||||
if (attachToNode.id === phase.id) {
|
||||
if (i === node.payload.parentNode.phases.length - 1) {
|
||||
node.payload.chainParent = attachToNode
|
||||
node.payload.parentNode.phases.push(node)
|
||||
completeAttachment(node, rootNodes)
|
||||
} else {
|
||||
node.payload.chainParent = attachToNode
|
||||
let nextPhase = node.payload.parentNode.phases[i + 1]
|
||||
nextPhase.payload.chainParent = node
|
||||
node.payload.parentNode.phases.splice(i + 1, 0, node)
|
||||
completeAttachment(node, rootNodes)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
default: {
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument !== undefined) {
|
||||
node.payload.parentNode = attachToNode
|
||||
node.payload.chainParent = attachToNode
|
||||
/* Attach to new parent */
|
||||
if (node.payload.parentNode !== undefined) {
|
||||
let parentSchemaDocument = getSchemaDocument(node.payload.parentNode)
|
||||
if (parentSchemaDocument !== undefined) {
|
||||
if (parentSchemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < parentSchemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = parentSchemaDocument.childrenNodesProperties[i]
|
||||
if (schemaDocument.propertyNameAtParent === property.name) {
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
node.payload.parentNode[property.name] = node
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
if (node.payload.parentNode[property.name] === undefined) {
|
||||
node.payload.parentNode[property.name] = []
|
||||
}
|
||||
let nodePropertyArray = node.payload.parentNode[property.name]
|
||||
nodePropertyArray.push(node)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
completeAttachment(node, rootNodes)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function completeDetachment(node, rootNodes) {
|
||||
node.payload.parentNode = undefined
|
||||
node.payload.chainParent = undefined
|
||||
rootNodes.push(node)
|
||||
}
|
||||
|
||||
function completeAttachment(node, rootNodes) {
|
||||
for (let i = 0; i < rootNodes.length; i++) {
|
||||
let rootNode = rootNodes[i]
|
||||
if (rootNode.id === node.id) {
|
||||
rootNodes.splice(i, 1)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
function newVisualScriptingFunctionLibraryNodeChildren() {
|
||||
let thisObject = {
|
||||
childrenCount: childrenCount
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function childrenCount(parentNode, childNode) {
|
||||
return countChildrenUiObject(parentNode, childNode)
|
||||
}
|
||||
|
||||
function countChildrenUiObject(parentNode, childNode) {
|
||||
let response = {
|
||||
childrenCount: 0,
|
||||
childIndex: undefined
|
||||
}
|
||||
let parentSchemaDocument = getSchemaDocument(parentNode)
|
||||
if (parentSchemaDocument !== undefined) {
|
||||
if (parentSchemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
|
||||
for (let i = 0; i < parentSchemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = parentSchemaDocument.childrenNodesProperties[i]
|
||||
if (parentNode[property.name] !== undefined) {
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (property.name !== previousPropertyName) {
|
||||
response.childrenCount++
|
||||
if (parentNode[property.name].id === childNode.id) {
|
||||
response.childIndex = response.childrenCount
|
||||
}
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let schemaDocument = getSchemaDocument(childNode)
|
||||
if (schemaDocument !== undefined) {
|
||||
let nodePropertyArray = parentNode[property.name]
|
||||
for (let j = 0; j < nodePropertyArray.length; j++) {
|
||||
let child = nodePropertyArray[j]
|
||||
if (schemaDocument.chainedToSameType === true) {
|
||||
if (j < 1) {
|
||||
response.childrenCount++
|
||||
if (child.id === childNode.id) {
|
||||
response.childIndex = response.childrenCount
|
||||
}
|
||||
}
|
||||
} else {
|
||||
response.childrenCount++
|
||||
if (child.id === childNode.id) {
|
||||
response.childIndex = response.childrenCount
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
function newVisualScriptingFunctionLibraryNodeCloning() {
|
||||
const MODULE_NAME = 'Node Cloning'
|
||||
const ERROR_LOG = true
|
||||
const logger = newWebDebugLog()
|
||||
|
||||
|
||||
let thisObject = {
|
||||
getNodeClone: getNodeClone
|
||||
}
|
||||
return thisObject
|
||||
|
||||
function getNodeClone(node) {
|
||||
let idConversionMap = new Map()
|
||||
|
||||
let inmatureClone = cloneNode(node)
|
||||
let matureClone = redirectReferenceParents(inmatureClone)
|
||||
|
||||
return matureClone
|
||||
|
||||
function cloneNode(node) {
|
||||
if (node === undefined) { return }
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument !== undefined) {
|
||||
let object = {
|
||||
type: node.type,
|
||||
name: node.name,
|
||||
code: node.code,
|
||||
config: node.config,
|
||||
project: node.project
|
||||
}
|
||||
|
||||
/* Children Nodes */
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (property.name !== previousPropertyName) {
|
||||
if (node[property.name] !== undefined) {
|
||||
object[property.name] = cloneNode(node[property.name])
|
||||
}
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'array': {
|
||||
if (node[property.name] !== undefined) {
|
||||
let nodePropertyArray = node[property.name]
|
||||
object[property.name] = []
|
||||
for (let m = 0; m < nodePropertyArray.length; m++) {
|
||||
let protocolNode = cloneNode(nodePropertyArray[m])
|
||||
if (protocolNode !== undefined) {
|
||||
object[property.name].push(protocolNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object.id = newUniqueId()
|
||||
idConversionMap.set(node.id, object.id)
|
||||
|
||||
object.savedPayload = getSavedPayload(node)
|
||||
|
||||
return object
|
||||
}
|
||||
}
|
||||
|
||||
function redirectReferenceParents(node) {
|
||||
if (node === undefined) { return }
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument !== undefined) {
|
||||
let object = {
|
||||
type: node.type,
|
||||
name: node.name,
|
||||
code: node.code,
|
||||
config: node.config,
|
||||
project: node.project
|
||||
}
|
||||
|
||||
/* Children Nodes */
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (property.name !== previousPropertyName) {
|
||||
if (node[property.name] !== undefined) {
|
||||
object[property.name] = redirectReferenceParents(node[property.name])
|
||||
}
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'array': {
|
||||
if (node[property.name] !== undefined) {
|
||||
let nodePropertyArray = node[property.name]
|
||||
object[property.name] = []
|
||||
for (let m = 0; m < nodePropertyArray.length; m++) {
|
||||
let protocolNode = redirectReferenceParents(nodePropertyArray[m])
|
||||
if (protocolNode !== undefined) {
|
||||
object[property.name].push(protocolNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object.id = node.id
|
||||
|
||||
object.savedPayload = node.savedPayload
|
||||
|
||||
if (object.savedPayload !== undefined) {
|
||||
if (object.savedPayload.referenceParent !== undefined) {
|
||||
let newId = idConversionMap.get(object.savedPayload.referenceParent.id)
|
||||
if (newId !== undefined) {
|
||||
object.savedPayload.referenceParent.id = newId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return object
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getSavedPayload(node) {
|
||||
if (node.payload === undefined) { return }
|
||||
let savedPayload = {
|
||||
position: {
|
||||
x: node.payload.position.x,
|
||||
y: node.payload.position.y
|
||||
},
|
||||
targetPosition: {
|
||||
x: node.payload.targetPosition.x,
|
||||
y: node.payload.targetPosition.y
|
||||
},
|
||||
floatingObject: {
|
||||
isPinned: node.payload.floatingObject.isPinned,
|
||||
isFrozen: (node.payload.floatingObject.isFrozen && node.payload.floatingObject.frozenManually),
|
||||
isCollapsed: (node.payload.floatingObject.isCollapsed && node.payload.floatingObject.collapsedManually),
|
||||
angleToParent: (node.payload.floatingObject.angleToParent),
|
||||
distanceToParent: (node.payload.floatingObject.distanceToParent),
|
||||
arrangementStyle: (node.payload.floatingObject.arrangementStyle)
|
||||
},
|
||||
uiObject: {
|
||||
isPlaying: node.payload.uiObject.isPlaying,
|
||||
isRunning: node.payload.uiObject.isRunning,
|
||||
shortcutKey: node.payload.uiObject.shortcutKey
|
||||
}
|
||||
}
|
||||
|
||||
/* Next for the ones that have a reference parent, we include it */
|
||||
if (node.payload.referenceParent !== undefined) {
|
||||
savedPayload.referenceParent = {
|
||||
type: node.payload.referenceParent.type,
|
||||
name: node.payload.referenceParent.name,
|
||||
id: node.payload.referenceParent.id
|
||||
}
|
||||
// If the path has not been saved save it now
|
||||
if (node.payload.referenceParentCombinedNodePath === undefined) {
|
||||
let attachNodePath = UI.projects.foundations.utilities.hierarchy.getNodeNameTypePath(node.payload.referenceParent)
|
||||
// Save path to reference parent for auto restore
|
||||
savedPayload.referenceParentCombinedNodePath = attachNodePath
|
||||
} else {
|
||||
// Save path to reference parent for auto restore
|
||||
savedPayload.referenceParentCombinedNodePath = node.payload.referenceParentCombinedNodePath
|
||||
}
|
||||
} else {
|
||||
/* The referenceParent property can be inherited from the previous saved payload. */
|
||||
if (node.savedPayload !== undefined) {
|
||||
savedPayload.referenceParent = node.savedPayload.referenceParent
|
||||
// Save path to reference parent for auto restore
|
||||
savedPayload.referenceParentCombinedNodePath = node.savedPayload.referenceParentCombinedNodePath
|
||||
}
|
||||
}
|
||||
|
||||
return savedPayload
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
function newVisualScriptingFunctionLibraryNodeDeleter() {
|
||||
let thisObject = {
|
||||
deleteWorkspace: deleteWorkspace,
|
||||
deleteUIObject: deleteUIObject
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function destroyUiObject(node) {
|
||||
UI.projects.foundations.spaces.floatingSpace.uiObjectConstructor.destroyUiObject(node.payload)
|
||||
}
|
||||
|
||||
function deleteWorkspace(node, rootNodes, callBackFuntion) {
|
||||
if (node.rootNodes !== undefined) {
|
||||
|
||||
let totalDeleted = 0
|
||||
let totalToBeDeleted = node.rootNodes.length
|
||||
|
||||
for (let i = 0; i < node.rootNodes.length; i++) {
|
||||
let rootNode = node.rootNodes[i]
|
||||
setTimeout(deleteRootNode, 100, rootNode)
|
||||
}
|
||||
|
||||
function deleteRootNode(rootNode) {
|
||||
let result = deleteUIObject(rootNode, rootNodes)
|
||||
if (result === false) {
|
||||
return false
|
||||
} else {
|
||||
totalDeleted++
|
||||
if (totalDeleted === totalToBeDeleted) {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function finish() {
|
||||
completeDeletion(node, rootNodes)
|
||||
destroyUiObject(node)
|
||||
cleanNode(node)
|
||||
callBackFuntion()
|
||||
}
|
||||
}
|
||||
|
||||
function deleteUIObject(node, rootNodes) {
|
||||
|
||||
/* First we restore the reference parent to its default state */
|
||||
if (node.payload !== undefined && node.payload.referenceParent !== undefined && node.payload.referenceParent.payload !== undefined && node.payload.referenceParent.payload.uiObject !== undefined) {
|
||||
node.payload.referenceParent.payload.uiObject.isShowing = false
|
||||
}
|
||||
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument !== undefined) {
|
||||
/* Remove all of its own children nodes. */
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (property.name !== previousPropertyName) {
|
||||
if (node[property.name] !== undefined) {
|
||||
let result = deleteUIObject(node[property.name], rootNodes)
|
||||
if (result === false) { return false }
|
||||
}
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let nodePropertyArray = node[property.name]
|
||||
if (nodePropertyArray !== undefined) {
|
||||
while (nodePropertyArray.length > 0) {
|
||||
let result = deleteUIObject(nodePropertyArray[0], rootNodes)
|
||||
if (result === false) { return false }
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove node from parent */
|
||||
if (schemaDocument.propertyNameAtParent !== undefined) {
|
||||
let removedFromParent = false
|
||||
if (node.payload !== undefined) {
|
||||
if (node.payload.parentNode !== undefined) {
|
||||
let parentSchemaDocument = getSchemaDocument(node.payload.parentNode)
|
||||
if (parentSchemaDocument !== undefined) {
|
||||
if (parentSchemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < parentSchemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = parentSchemaDocument.childrenNodesProperties[i]
|
||||
if (schemaDocument.propertyNameAtParent === property.name) {
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
node.payload.parentNode[property.name] = undefined
|
||||
removedFromParent = true
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let nodePropertyArray = node.payload.parentNode[property.name]
|
||||
if (nodePropertyArray !== undefined) {
|
||||
for (let j = 0; j < nodePropertyArray.length; j++) {
|
||||
let arrayItem = nodePropertyArray[j]
|
||||
if (arrayItem.id === node.id) {
|
||||
/* If this object is chained to the ones of the same type we need to give the next in the chain the reference to the current chain parent */
|
||||
if (schemaDocument.chainedToSameType === true) {
|
||||
if (j < nodePropertyArray.length - 1) {
|
||||
let nextArrayItem = nodePropertyArray[j + 1]
|
||||
nextArrayItem.payload.chainParent = node.payload.chainParent
|
||||
}
|
||||
}
|
||||
|
||||
nodePropertyArray.splice(j, 1)
|
||||
removedFromParent = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removedFromParent === false) {
|
||||
console.log('[ERROR] Deleting Node: ' + node.type + ' ' + node.name + '. This node could not be deleted from its parent node (' + node.payload.parentNode.type + ') because its configured propertyNameAtParent (' + schemaDocument.propertyNameAtParent + ') does not match any of the properties of its parent.')
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
completeDeletion(node, rootNodes)
|
||||
destroyUiObject(node)
|
||||
cleanNode(node)
|
||||
}
|
||||
}
|
||||
|
||||
function completeDeletion(node, rootNodes) {
|
||||
for (let i = 0; i < rootNodes.length; i++) {
|
||||
let rootNode = rootNodes[i]
|
||||
if (rootNode.id === node.id) {
|
||||
rootNodes.splice(i, 1)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cleanNode(node) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
|
||||
node.payload.targetPosition.x = undefined
|
||||
node.payload.targetPosition.y = undefined
|
||||
node.payload.visible = undefined
|
||||
node.payload.title = undefined
|
||||
node.payload.node = undefined
|
||||
node.payload.parentNode = undefined
|
||||
node.payload.chainParent = undefined
|
||||
node.payload.executeAction = undefined
|
||||
node.handle = undefined
|
||||
node.payload = undefined
|
||||
node.cleaned = true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
function newVisualScriptingFunctionLibraryNodePath() {
|
||||
let thisObject = {
|
||||
getNodePath: getNodePath
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function getNodePath(node) {
|
||||
|
||||
let nodePath = 'value'
|
||||
|
||||
recursiveGet(node)
|
||||
|
||||
return 'tradingEngine.' + nodePath
|
||||
|
||||
function recursiveGet(node) {
|
||||
|
||||
if (node.payload === undefined) { return }
|
||||
if (node.payload.parentNode === undefined) { return }
|
||||
|
||||
let schemaDocument = getSchemaDocument(node.payload.parentNode)
|
||||
if (schemaDocument === undefined) { return }
|
||||
if (schemaDocument.childrenNodesProperties === undefined) { return }
|
||||
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
let parentProperty = node.payload.parentNode[property.name]
|
||||
if (parentProperty === undefined) { continue }
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (parentProperty.id === node.id) {
|
||||
/* We found it */
|
||||
nodePath = property.name + '.' + nodePath
|
||||
recursiveGet(node.payload.parentNode)
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
for (let j = 0; j < parentProperty.length; j++) {
|
||||
let arrayProperty = parentProperty[j]
|
||||
if (arrayProperty === undefined) {continue}
|
||||
if (arrayProperty.id === node.id) {
|
||||
/* We found it */
|
||||
nodePath = property.name + '[' + j + ']' + '.' + nodePath
|
||||
recursiveGet(node.payload.parentNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
function newVisualScriptingFunctionLibraryOnFocus() {
|
||||
let thisObject = {
|
||||
getNodeThatIsOnFocus: getNodeThatIsOnFocus
|
||||
}
|
||||
return thisObject
|
||||
|
||||
function getNodeThatIsOnFocus(node) {
|
||||
if (node === undefined || node === null) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument !== undefined) {
|
||||
/* First we ask the question to ourself */
|
||||
if (node.payload.uiObject.isOnFocus === true) {
|
||||
return node
|
||||
}
|
||||
|
||||
/* Then we check all of its own children nodes. */
|
||||
if (node.payload.floatingObject.isCollapsed !== true) {
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (property.name !== previousPropertyName) {
|
||||
if (node[property.name] !== undefined) {
|
||||
let child = getNodeThatIsOnFocus(node[property.name])
|
||||
if (child !== undefined) {
|
||||
return child
|
||||
}
|
||||
}
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let nodePropertyArray = node[property.name]
|
||||
if (nodePropertyArray !== undefined) {
|
||||
for (let m = 0; m < nodePropertyArray.length; m++) {
|
||||
let child = getNodeThatIsOnFocus(nodePropertyArray[m])
|
||||
if (child !== undefined) {
|
||||
return child
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
function newVisualScriptingFunctionLibraryProtocolNode() {
|
||||
const MODULE_NAME = 'Protocol Node'
|
||||
const ERROR_LOG = true
|
||||
const logger = newWebDebugLog()
|
||||
|
||||
|
||||
let thisObject = {
|
||||
getProtocolNode: getProtocolNode
|
||||
}
|
||||
return thisObject
|
||||
|
||||
function getProtocolNode(
|
||||
node,
|
||||
removePersonalData,
|
||||
parseConfig,
|
||||
includeIds,
|
||||
includePayload,
|
||||
includeReferencesInSavedPayload,
|
||||
lightingPath,
|
||||
excludeChildrenOfType
|
||||
) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument !== undefined) {
|
||||
if (removePersonalData === true && schemaDocument.isPersonalData === true) { return }
|
||||
let object = {
|
||||
type: node.type,
|
||||
name: node.name,
|
||||
code: node.code,
|
||||
config: node.config,
|
||||
project: node.project
|
||||
}
|
||||
|
||||
/* Children Nodes */
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
if (property.childType === excludeChildrenOfType) {
|
||||
continue
|
||||
}
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (node[property.name] !== undefined) {
|
||||
if (lightingPath === undefined) {
|
||||
object[property.name] = getProtocolNode(
|
||||
node[property.name],
|
||||
removePersonalData,
|
||||
parseConfig,
|
||||
includeIds,
|
||||
includeReferencesInSavedPayload,
|
||||
includePayload
|
||||
)
|
||||
} else {
|
||||
let newLightingPath = getNewLightingPath(lightingPath, node.type, property.childType)
|
||||
if (newLightingPath !== undefined) {
|
||||
object[property.name] = getProtocolNode(
|
||||
node[property.name],
|
||||
removePersonalData,
|
||||
parseConfig,
|
||||
includeIds,
|
||||
includePayload,
|
||||
includeReferencesInSavedPayload,
|
||||
newLightingPath
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'array': {
|
||||
if (node[property.name] !== undefined) {
|
||||
if (lightingPath === undefined) {
|
||||
let nodePropertyArray = node[property.name]
|
||||
object[property.name] = []
|
||||
for (let m = 0; m < nodePropertyArray.length; m++) {
|
||||
let protocolNode = getProtocolNode(
|
||||
nodePropertyArray[m],
|
||||
removePersonalData,
|
||||
parseConfig,
|
||||
includeIds,
|
||||
includeReferencesInSavedPayload,
|
||||
includePayload
|
||||
)
|
||||
if (protocolNode !== undefined) {
|
||||
object[property.name].push(protocolNode)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let newLightingPath = getNewLightingPath(lightingPath, node.type, property.childType)
|
||||
if (newLightingPath !== undefined) {
|
||||
let nodePropertyArray = node[property.name]
|
||||
object[property.name] = []
|
||||
for (let m = 0; m < nodePropertyArray.length; m++) {
|
||||
let protocolNode = getProtocolNode(
|
||||
nodePropertyArray[m],
|
||||
removePersonalData,
|
||||
parseConfig,
|
||||
includeIds,
|
||||
includePayload,
|
||||
includeReferencesInSavedPayload,
|
||||
newLightingPath
|
||||
)
|
||||
if (protocolNode !== undefined) {
|
||||
object[property.name].push(protocolNode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Parent Nodes */
|
||||
if (node.payload.parentNode !== undefined) {
|
||||
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,
|
||||
node.type
|
||||
)
|
||||
} else {
|
||||
let newLightingPath = getNewLightingPath(lightingPath, node.type, node.payload.parentNode.type)
|
||||
}
|
||||
}
|
||||
if (node.payload.referenceParent !== undefined) {
|
||||
let newLightingPath = getNewLightingPath(lightingPath, node.type, node.payload.referenceParent.type)
|
||||
if (newLightingPath !== undefined) {
|
||||
object.referenceParent = getProtocolNode(
|
||||
node.payload.referenceParent,
|
||||
removePersonalData,
|
||||
parseConfig,
|
||||
includeIds,
|
||||
includePayload,
|
||||
includeReferencesInSavedPayload,
|
||||
newLightingPath
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (parseConfig && object.config !== undefined && schemaDocument.editors !== undefined) {
|
||||
if (schemaDocument.editors.config === true) {
|
||||
try {
|
||||
object.config = JSON.parse(node.config)
|
||||
} catch (err) {
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> err = ' + err.stack) }
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> node.type = ' + node.type) }
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> node.name = ' + node.name) }
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> node.config = ' + node.config) }
|
||||
if (ERROR_LOG === true) { logger.write('[ERROR] getProtocolNode -> default -> node.id = ' + node.id) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (includeIds) {
|
||||
object.id = node.id
|
||||
}
|
||||
if (includePayload) {
|
||||
object.savedPayload = getSavedPayload(node, includeReferencesInSavedPayload)
|
||||
}
|
||||
|
||||
return object
|
||||
}
|
||||
}
|
||||
|
||||
function getNewLightingPath(lightingPath, currentNodeType, nextNodeType) {
|
||||
if (lightingPath === undefined) { return }
|
||||
|
||||
if (currentNodeType === undefined) { return }
|
||||
if (nextNodeType === undefined) { return }
|
||||
|
||||
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, and then remove one of the strings for the returning path.
|
||||
*/
|
||||
if (currentNodeType === nextNodeType) {
|
||||
let tempLightingPath = lightingPath.substring(currentNodePosition + currentNodeType.length + 2, lightingPath.length + 1)
|
||||
nextNodePosition = tempLightingPath.indexOf('->' + nextNodeType + '->')
|
||||
|
||||
let newLightingPath = lightingPath.substring(nextNodePosition, lightingPath.length + 1)
|
||||
|
||||
if (nextNodePosition >= currentNodePosition) {
|
||||
return newLightingPath
|
||||
}
|
||||
} else {
|
||||
let newLightingPath = lightingPath.substring(nextNodePosition, lightingPath.length + 1)
|
||||
|
||||
if (nextNodePosition > currentNodePosition) {
|
||||
return newLightingPath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getSavedPayload(node, includeReferencesInSavedPayload) {
|
||||
if (node.payload === undefined) { return }
|
||||
let savedPayload = {
|
||||
position: {
|
||||
x: node.payload.position.x,
|
||||
y: node.payload.position.y
|
||||
},
|
||||
targetPosition: {
|
||||
x: node.payload.targetPosition.x,
|
||||
y: node.payload.targetPosition.y
|
||||
},
|
||||
floatingObject: {
|
||||
isPinned: node.payload.floatingObject.isPinned,
|
||||
isFrozen: (node.payload.floatingObject.isFrozen && node.payload.floatingObject.frozenManually),
|
||||
isCollapsed: (node.payload.floatingObject.isCollapsed && node.payload.floatingObject.collapsedManually),
|
||||
angleToParent: (node.payload.floatingObject.angleToParent),
|
||||
distanceToParent: (node.payload.floatingObject.distanceToParent),
|
||||
arrangementStyle: (node.payload.floatingObject.arrangementStyle)
|
||||
},
|
||||
uiObject: {
|
||||
isPlaying: node.payload.uiObject.isPlaying,
|
||||
isRunning: node.payload.uiObject.isRunning,
|
||||
shortcutKey: node.payload.uiObject.shortcutKey
|
||||
}
|
||||
}
|
||||
|
||||
if (node.payload.frame !== undefined) {
|
||||
savedPayload.frame = {
|
||||
position: {
|
||||
x: node.payload.frame.position.x,
|
||||
y: node.payload.frame.position.y
|
||||
},
|
||||
width: node.payload.frame.width,
|
||||
height: node.payload.frame.height,
|
||||
radius: node.payload.frame.radius
|
||||
}
|
||||
}
|
||||
|
||||
if (node.payload.tutorial !== undefined) {
|
||||
savedPayload.tutorial = {
|
||||
status: node.payload.tutorial.status
|
||||
}
|
||||
}
|
||||
|
||||
if (includeReferencesInSavedPayload) {
|
||||
/* Next for the ones that have a reference parent, we include it */
|
||||
if (node.payload.referenceParent !== undefined) {
|
||||
savedPayload.referenceParent = {
|
||||
type: node.payload.referenceParent.type,
|
||||
name: node.payload.referenceParent.name,
|
||||
id: node.payload.referenceParent.id
|
||||
}
|
||||
// If the path has not been saved save it now
|
||||
if (node.payload.referenceParentCombinedNodePath === undefined) {
|
||||
let attachNodePath = UI.projects.foundations.utilities.hierarchy.getNodeNameTypePath(node.payload.referenceParent)
|
||||
// Save path to reference parent for auto restore
|
||||
savedPayload.referenceParentCombinedNodePath = attachNodePath
|
||||
} else {
|
||||
// Save path to reference parent for auto restore
|
||||
savedPayload.referenceParentCombinedNodePath = node.payload.referenceParentCombinedNodePath
|
||||
}
|
||||
} else {
|
||||
/* The referenceParent property can be inherited from the previous saved payload. */
|
||||
if (node.savedPayload !== undefined) {
|
||||
savedPayload.referenceParent = node.savedPayload.referenceParent
|
||||
// Save path to reference parent for auto restore
|
||||
savedPayload.referenceParentCombinedNodePath = node.savedPayload.referenceParentCombinedNodePath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return savedPayload
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
// These function are used across the system to establish and remove references between nodes
|
||||
function newVisualScriptingFunctionLibraryReferenceAttachDetach() {
|
||||
let thisObject = {
|
||||
referenceDetachNode: referenceDetachNode,
|
||||
referenceAttachNode: referenceAttachNode
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function referenceDetachNode(node) {
|
||||
cleanAttachNodePath(node)
|
||||
completeDetachment(node)
|
||||
|
||||
}
|
||||
|
||||
function referenceAttachNode(node, attachToNode) {
|
||||
storeAttachNodePath(node, attachToNode)
|
||||
completeAttachment(node, attachToNode)
|
||||
}
|
||||
|
||||
// Store the path to the reference parent to make restoring it possible if the reference parent is updated and given a new id
|
||||
function storeAttachNodePath(node, attachToNode) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
let attachNodePath = UI.projects.foundations.utilities.hierarchy.getNodeNameTypePath(attachToNode)
|
||||
// Remove unused node id, and project tag from stored path
|
||||
for (let i = 0; i < attachNodePath.length; i++) {
|
||||
attachNodePath[i].splice(2, 2)
|
||||
}
|
||||
|
||||
// Save attach path to active payload
|
||||
node.payload.referenceParentCombinedNodePath = attachNodePath
|
||||
}
|
||||
|
||||
// Clear the path to reference parent when the reference is cleared
|
||||
function cleanAttachNodePath(node) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
|
||||
node.payload.referenceParentCombinedNodePath = undefined
|
||||
if (node.savedPayload !== undefined) {
|
||||
node.savedPayload.referenceParentCombinedNodePath = undefined
|
||||
}
|
||||
}
|
||||
|
||||
// Establish the reference between node and it's reference parent
|
||||
function completeAttachment(node, attachToNode) {
|
||||
node.payload.referenceParent = attachToNode
|
||||
}
|
||||
|
||||
// Detach the reference between node and it's reference parent
|
||||
function completeDetachment(node) {
|
||||
if (node.payload !== undefined) {
|
||||
if (node.payload.referenceParent !== undefined) {
|
||||
if (node.payload.referenceParent.payload !== undefined) {
|
||||
if (node.payload.referenceParent.payload.uiObject !== undefined) {
|
||||
node.payload.referenceParent.payload.uiObject.isShowing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
node.payload.referenceParent = undefined
|
||||
if (node.savedPayload !== undefined) {
|
||||
node.savedPayload.referenceParent = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,957 @@
|
||||
function newVisualScritingFunctionLibraryUiObjectsFromNodes() {
|
||||
let thisObject = {
|
||||
syncronizeTasksFoundAtWorkspaceWithBackEnd: syncronizeTasksFoundAtWorkspaceWithBackEnd,
|
||||
syncronizeTradingSessionsFoundAtWorkspaceWithBackEnd: syncronizeTradingSessionsFoundAtWorkspaceWithBackEnd,
|
||||
syncronizeLearningSessionsFoundAtWorkspaceWithBackEnd: syncronizeLearningSessionsFoundAtWorkspaceWithBackEnd,
|
||||
playTutorials: playTutorials,
|
||||
recreateWorkspace: recreateWorkspace,
|
||||
getNodeById: getNodeById,
|
||||
tryToConnectChildrenWithReferenceParents: tryToConnectChildrenWithReferenceParents,
|
||||
createUiObjectFromNode: createUiObjectFromNode,
|
||||
addUIObject: addUIObject,
|
||||
addMissingChildren: addMissingChildren
|
||||
}
|
||||
|
||||
let mapOfReferenceChildren = new Map()
|
||||
let mapOfNodes
|
||||
let tasksFoundAtWorkspace
|
||||
let tradingSessionsFoundAtWorkspace
|
||||
let learningSessionsFoundAtWorkspace
|
||||
let tutorialsToPlay
|
||||
|
||||
return thisObject
|
||||
|
||||
function getNodeById(nodeId) {
|
||||
return mapOfNodes.get(nodeId)
|
||||
}
|
||||
|
||||
function recreateWorkspace(node, callBackFunction) {
|
||||
mapOfNodes = new Map()
|
||||
tasksFoundAtWorkspace = []
|
||||
tradingSessionsFoundAtWorkspace = []
|
||||
learningSessionsFoundAtWorkspace = []
|
||||
tutorialsToPlay = []
|
||||
|
||||
/* Initializing the workspace config */
|
||||
if (node.config === undefined || node.config === 'undefined') { node.config = '{}' }
|
||||
|
||||
removeNullRootNodes()
|
||||
|
||||
function removeNullRootNodes() {
|
||||
for (let i = 0; i < node.rootNodes.length; i++) {
|
||||
let rootNode = node.rootNodes[i]
|
||||
if (rootNode === null) {
|
||||
node.rootNodes.splice(i, 1)
|
||||
removeNullRootNodes()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addPluginNodes()
|
||||
|
||||
function addPluginNodes(pluginNames) {
|
||||
UI.projects.foundations.utilities.statusBar.changeStatus("Loading Plugins...")
|
||||
|
||||
let blobService = newFileStorage()
|
||||
let totalPlugin = 0
|
||||
let totalRead = 0
|
||||
|
||||
for (let i = 0; i < node.rootNodes.length; i++) {
|
||||
let rootNode = node.rootNodes[i]
|
||||
if (rootNode.type === 'Plugins') {
|
||||
let plugins = rootNode
|
||||
|
||||
if (plugins.pluginProjects === undefined) { continue }
|
||||
for (let j = 0; j < plugins.pluginProjects.length; j++) {
|
||||
let project = plugins.pluginProjects[j]
|
||||
/*
|
||||
Miscelaneours Plugin Types
|
||||
*/
|
||||
if (project.pluginDataMines !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginDataMines.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginDataMines.pluginFiles, 'Data-Mines')
|
||||
}
|
||||
if (project.pluginTradingMines !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginTradingMines.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginTradingMines.pluginFiles, 'Trading-Mines')
|
||||
}
|
||||
if (project.pluginTradingSystems !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginTradingSystems.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginTradingSystems.pluginFiles, 'Trading-Systems')
|
||||
}
|
||||
if (project.pluginTradingEngines !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginTradingEngines.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginTradingEngines.pluginFiles, 'Trading-Engines')
|
||||
}
|
||||
if (project.pluginLearningMines !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginLearningMines.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginLearningMines.pluginFiles, 'Learning-Mines')
|
||||
}
|
||||
if (project.pluginLearningSystems !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginLearningSystems.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginLearningSystems.pluginFiles, 'Learning-Systems')
|
||||
}
|
||||
if (project.pluginLearningEngines !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginLearningEngines.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginLearningEngines.pluginFiles, 'Learning-Engines')
|
||||
}
|
||||
/*
|
||||
Foundations Plugin Types
|
||||
*/
|
||||
if (project.pluginTutorials !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginTutorials.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginTutorials.pluginFiles, 'Tutorials')
|
||||
}
|
||||
if (project.pluginApiMaps !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginApiMaps.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginApiMaps.pluginFiles, 'API-Maps')
|
||||
}
|
||||
/*
|
||||
Governance Plugin Types
|
||||
*/
|
||||
if (project.pluginUserProfiles !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginUserProfiles.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginUserProfiles.pluginFiles, 'User-Profiles')
|
||||
}
|
||||
if (project.pluginPools !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginPools.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginPools.pluginFiles, 'Pools')
|
||||
}
|
||||
if (project.pluginFeatures !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginFeatures.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginFeatures.pluginFiles, 'Features')
|
||||
}
|
||||
if (project.pluginAssets !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginAssets.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginAssets.pluginFiles, 'Assets')
|
||||
}
|
||||
if (project.pluginPositions !== undefined) {
|
||||
totalPlugin = totalPlugin + project.pluginPositions.pluginFiles.length
|
||||
pluginAllTheseFiles(project.pluginPositions.pluginFiles, 'Positions')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
If there is no Plugins node at the workspace, we load it anyways here.
|
||||
*/
|
||||
if (totalPlugin === 0) {
|
||||
addUserDefinedNodes()
|
||||
}
|
||||
|
||||
function pluginAllTheseFiles(pluginFiles, pluginFolder) {
|
||||
for (let i = 0; i < pluginFiles.length; i++) {
|
||||
let pluginFile = pluginFiles[i]
|
||||
let name = pluginFile.name
|
||||
let folder = pluginFolder
|
||||
let project = "Foundations"
|
||||
try {
|
||||
let config = JSON.parse(pluginFile.config)
|
||||
if (config.project !== undefined) {
|
||||
project = config.project
|
||||
}
|
||||
if (config.fileName !== undefined) {
|
||||
name = config.fileName
|
||||
}
|
||||
if (config.folderName !== undefined) {
|
||||
folder = config.folderName
|
||||
}
|
||||
} catch (err) { }
|
||||
|
||||
httpRequest(undefined, 'LoadPlugin' + '/' + project + '/' + folder + '/' + name + '.json', onFileReceived)
|
||||
|
||||
function onFileReceived(err, text, response) {
|
||||
|
||||
if (err && err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
|
||||
console.log('[WARN] Cannot load plugin ' + pluginFolder + ' ' + name + '. The Workspace will be loaded with this plugin file missing.')
|
||||
} else {
|
||||
|
||||
let receivedNode
|
||||
|
||||
try {
|
||||
receivedNode = JSON.parse(text)
|
||||
} catch (err) {
|
||||
console.log('[ERROR] pluginAllTheseFiles -> Cannot load plugin ' + pluginFolder + ' ' + name + '. Received an invalid JSON object from the client.')
|
||||
console.log('[ERROR] pluginAllTheseFiles -> text = ' + text)
|
||||
console.log('[ERROR] pluginAllTheseFiles -> err.stack = ' + err.stack)
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
If the workspace already contains a root node with the id of the head of the hirierchy
|
||||
we are loading, we remove it because the plugin file has precedende.
|
||||
*/
|
||||
for (let i = 0; i < node.rootNodes.length; i++) {
|
||||
let rootNode = node.rootNodes[i]
|
||||
if (rootNode.id === receivedNode.id) {
|
||||
console.log('[WARN] The node with name "' + rootNode.name + '" and type "' + rootNode.type + '" will be replaced by the node with name "' + receivedNode.name + '" and type "' + receivedNode.type +'" because they both have the same node.id')
|
||||
node.rootNodes.splice(i, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
receivedNode.isPlugin = true
|
||||
/*
|
||||
We will force the Plugin codeName to the same to the fileName.
|
||||
*/
|
||||
let config
|
||||
try {
|
||||
config = JSON.parse(receivedNode.config)
|
||||
} catch (err) {
|
||||
config = {}
|
||||
}
|
||||
|
||||
config.codeName = name
|
||||
receivedNode.config = JSON.stringify(config)
|
||||
|
||||
if (pluginFile.pluginFilePosition !== undefined && receivedNode.savedPayload !== undefined) {
|
||||
let positionOffset = {
|
||||
x: pluginFile.pluginFilePosition.savedPayload.position.x - receivedNode.savedPayload.position.x,
|
||||
y: pluginFile.pluginFilePosition.savedPayload.position.y - receivedNode.savedPayload.position.y
|
||||
}
|
||||
receivedNode.positionOffset = positionOffset
|
||||
}
|
||||
|
||||
node.rootNodes.unshift(receivedNode)
|
||||
}
|
||||
|
||||
totalRead++
|
||||
if (totalPlugin === totalRead) {
|
||||
addUserDefinedNodes()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addUserDefinedNodes() {
|
||||
/* Create the workspace UI OBject and then continue with the root nodes. */
|
||||
createUiObject(false, 'Workspace', node.name, node, undefined, undefined, 'Workspace')
|
||||
if (node.rootNodes !== undefined) {
|
||||
UI.projects.foundations.utilities.statusBar.changeStatus("Setting up Rootnodes...")
|
||||
|
||||
let rootNode
|
||||
let i = -1
|
||||
controlLoop()
|
||||
|
||||
function loopBody() {
|
||||
createUiObjectFromNode(rootNode, undefined, undefined)
|
||||
controlLoop()
|
||||
}
|
||||
|
||||
function controlLoop() {
|
||||
i++
|
||||
if (i < node.rootNodes.length) {
|
||||
rootNode = node.rootNodes[i]
|
||||
UI.projects.foundations.utilities.statusBar.changeStatus("Connecting children nodes from " + rootNode.name + " - " + rootNode.type + "...")
|
||||
setTimeout(loopBody, 100)
|
||||
} else {
|
||||
UI.projects.foundations.utilities.statusBar.changeStatus("Finished connecting all nodes.")
|
||||
setTimeout(endLoop, 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
function endLoop() {
|
||||
tryToConnectChildrenWithReferenceParents()
|
||||
|
||||
if (callBackFunction !== undefined) {
|
||||
callBackFunction() // The recreation of the workspace is complete
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function syncronizeTasksFoundAtWorkspaceWithBackEnd() {
|
||||
for (let i = 0; i < tasksFoundAtWorkspace.length; i++) {
|
||||
let node = tasksFoundAtWorkspace[i]
|
||||
UI.projects.foundations.functionLibraries.taskFunctions.syncronizeTaskWithBackEnd(node)
|
||||
}
|
||||
tasksFoundAtWorkspace = undefined
|
||||
}
|
||||
|
||||
function syncronizeTradingSessionsFoundAtWorkspaceWithBackEnd() {
|
||||
for (let i = 0; i < tradingSessionsFoundAtWorkspace.length; i++) {
|
||||
let node = tradingSessionsFoundAtWorkspace[i]
|
||||
UI.projects.algorithmicTrading.functionLibraries.tradingSessionFunctions.syncronizeSessionWithBackEnd(node)
|
||||
}
|
||||
tradingSessionsFoundAtWorkspace = undefined
|
||||
}
|
||||
|
||||
function syncronizeLearningSessionsFoundAtWorkspaceWithBackEnd() {
|
||||
for (let i = 0; i < learningSessionsFoundAtWorkspace.length; i++) {
|
||||
let node = learningSessionsFoundAtWorkspace[i]
|
||||
UI.projects.machineLearning.functionLibraries.learningSessionFunctions.syncronizeSessionWithBackEnd(node)
|
||||
}
|
||||
learningSessionsFoundAtWorkspace = undefined
|
||||
}
|
||||
|
||||
function playTutorials() {
|
||||
for (let i = 0; i < tutorialsToPlay.length; i++) {
|
||||
let node = tutorialsToPlay[i]
|
||||
node.payload.uiObject.menu.internalClick('Play Tutorial')
|
||||
}
|
||||
tutorialsToPlay = undefined
|
||||
}
|
||||
|
||||
function tryToConnectChildrenWithReferenceParents() {
|
||||
/* We reconstruct here the reference relationships. */
|
||||
for (const [key, node] of mapOfNodes) {
|
||||
|
||||
if (node.payload === undefined) { continue }
|
||||
|
||||
if (node.payload.referenceParent !== undefined) {
|
||||
if (node.payload.referenceParent.cleaned === true) {
|
||||
node.payload.referenceParent = mapOfNodes.get(node.payload.referenceParent.id)
|
||||
if (node.payload.referenceParent === undefined) {
|
||||
//console.log('[WARN]' + node.type + ' ' + node.name + ' reference parent lost during re-binding phase.')
|
||||
}
|
||||
continue // We were referencing a deleted node, so we replace it potentially with a newly created one.
|
||||
} else {
|
||||
continue // In this case the reference is already good.
|
||||
}
|
||||
}
|
||||
|
||||
if (node.savedPayload !== undefined) {
|
||||
if (node.savedPayload.referenceParent !== undefined) { // these are children recreated
|
||||
// Reestablish based on Id
|
||||
node.payload.referenceParent = mapOfNodes.get(node.savedPayload.referenceParent.id)
|
||||
|
||||
// if Reestablishment failed now reestablish reference based on saved path
|
||||
if (node.payload.referenceParent === undefined) {
|
||||
// Gather saved path
|
||||
let rawPath = node.savedPayload.referenceParentCombinedNodePath
|
||||
if (rawPath !== undefined) {
|
||||
// Step down node hierarchy to find missing referenceParent
|
||||
let pathNode
|
||||
let pathName
|
||||
let pathType
|
||||
for (let i = 0; i < rawPath.length; i++) {
|
||||
|
||||
// Get Hierarchy head node
|
||||
if (i === 0) {
|
||||
pathName = rawPath[i][0]
|
||||
pathType = rawPath[i][1]
|
||||
pathNode = UI.projects.foundations.spaces.designSpace.workspace.getHierarchyHeadsByCodeNameAndNodeType(pathName, pathType)
|
||||
|
||||
// If reference parent is workspace node grab node
|
||||
if (pathType === "Workspace") {
|
||||
pathNode = UI.projects.foundations.spaces.designSpace.workspace.workspaceNode
|
||||
}
|
||||
// If Hierarchy Head is not located within the workspace abort reconnection
|
||||
if (pathNode === undefined) {
|
||||
// LUIS : console.log("[WARN] Abort reconnection saved path head node not found in current workspace", node)
|
||||
// I removed this warning because at the Governance System is common to reference nodes that are not present at the workspace.
|
||||
}
|
||||
continue
|
||||
} else { // Walk through children nodes and find the next node from saved path
|
||||
if (pathNode !== undefined) { // LUIS: I added this check because it was blowing up further down the line. See why sometimes this is undefined.
|
||||
pathName = rawPath[i][0]
|
||||
pathType = rawPath[i][1]
|
||||
pathNode = getNextNodeFromPath(pathNode, pathName, pathType)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pathNode !== undefined) {
|
||||
UI.projects.foundations.functionLibraries.attachDetach.referenceAttachNode(node, pathNode)
|
||||
} else {
|
||||
//console.log("[WARN] ", node.name, ' ', node.type, "failed to fix reference. Unable to find reference parent ", pathName, ' ', pathType )
|
||||
}
|
||||
|
||||
function getNextNodeFromPath(node, pathName, pathType) {
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument === undefined) { return }
|
||||
let nextNode = undefined
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
switch (property.type) {
|
||||
// If child node is directly withing parent node look for it
|
||||
case 'node': {
|
||||
if (node[property.name] !== undefined) {
|
||||
if (node[property.name].name === pathName && node[property.name].type === pathType) {
|
||||
nextNode = node[property.name]
|
||||
return nextNode
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
// If child node is in an array look for it
|
||||
case 'array': {
|
||||
if (node[property.name] !== undefined) {
|
||||
let nodePropertyArray = node[property.name]
|
||||
for (let m = 0; m < nodePropertyArray.length; m++) {
|
||||
if (nodePropertyArray[m].name === pathName && nodePropertyArray[m].type === pathType) {
|
||||
|
||||
nextNode = nodePropertyArray[m]
|
||||
return nextNode
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function migrateCodeToConfig(node, schemaDocument) {
|
||||
/* Code needed to Migrante from Beta 5 to Beta a Workspace */
|
||||
if (schemaDocument.editors !== undefined) {
|
||||
if (schemaDocument.editors.config === true) {
|
||||
if (node.code !== undefined) {
|
||||
node.config = node.code
|
||||
node.code = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createUiObjectFromNode(node, parentNode, chainParent, positionOffset) {
|
||||
|
||||
/* Migration code from beta 10 to beta 11 */
|
||||
if (
|
||||
node.type === 'Tutorial' ||
|
||||
node.type === 'Tutorial Topic' ||
|
||||
node.type === 'Tutorial Step'
|
||||
) {
|
||||
node.project = "Education"
|
||||
}
|
||||
|
||||
if (
|
||||
node.project === undefined ||
|
||||
node.project === 'Superalgos'
|
||||
) {
|
||||
node.project = 'Foundations'
|
||||
}
|
||||
/* Migration code from beta 11 to beta 12 */
|
||||
if (
|
||||
node.type === 'Network'
|
||||
) {
|
||||
node.type = "LAN Network"
|
||||
if (node.lanNetworkNodes === undefined && node.networkNodes !== undefined) {
|
||||
node.lanNetworkNodes = node.networkNodes
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
node.type === 'Network Node'
|
||||
) {
|
||||
node.type = "LAN Network Node"
|
||||
}
|
||||
|
||||
if (
|
||||
node.type === 'Data Mine' ||
|
||||
node.type === 'API Data Fetcher Bot' ||
|
||||
node.type === 'Indicator Bot' ||
|
||||
node.type === 'Sensor Bot'
|
||||
) {
|
||||
node.project = "Data-Mining"
|
||||
}
|
||||
|
||||
if (
|
||||
node.type === 'Trading Engine' ||
|
||||
node.type === 'Trading Mine' ||
|
||||
node.type === 'Trading System' ||
|
||||
node.type === 'Trading Bot'
|
||||
) {
|
||||
node.project = "Algorithmic-Trading"
|
||||
}
|
||||
|
||||
if (
|
||||
node.type === 'Learning Engine' ||
|
||||
node.type === 'Learning Mine' ||
|
||||
node.type === 'Learning System' ||
|
||||
node.type === 'Learning Bot'
|
||||
) {
|
||||
node.project = "Machine-Learning"
|
||||
}
|
||||
|
||||
if (
|
||||
node.type === 'Plugins' ||
|
||||
node.type === 'Plugin Tutorials' ||
|
||||
node.type === 'Plugin Trading Systems' ||
|
||||
node.type === 'Plugin Trading Mines' ||
|
||||
node.type === 'Plugin Trading Engines' ||
|
||||
node.type === 'Plugin Project' ||
|
||||
node.type === 'Plugin Learning Systems' ||
|
||||
node.type === 'Plugin Learning Mines' ||
|
||||
node.type === 'Plugin Learning Engines' ||
|
||||
node.type === 'Plugin File' ||
|
||||
node.type === 'Plugin File Position' ||
|
||||
node.type === 'Plugin Data Mines' ||
|
||||
node.type === 'Plugin API Maps'
|
||||
) {
|
||||
node.project = "Community-Plugins"
|
||||
}
|
||||
|
||||
/*
|
||||
This function can be called with a positionOffset to change the node
|
||||
saved position and all of its descendants positions as well with an
|
||||
offset. It can also happen that the positionOffset is defined as a property
|
||||
of the node, in which case it will produce exactly the same effect.
|
||||
*/
|
||||
if (node.positionOffset !== undefined) {
|
||||
positionOffset = node.positionOffset
|
||||
}
|
||||
|
||||
|
||||
/* Get schema document */
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument !== undefined) {
|
||||
migrateCodeToConfig(node, schemaDocument)
|
||||
|
||||
/* Resolve Initial Values */
|
||||
if (schemaDocument.initialValues !== undefined) {
|
||||
if (schemaDocument.initialValues.code !== undefined) {
|
||||
if (node.code === undefined) {
|
||||
node.code = schemaDocument.initialValues.code
|
||||
}
|
||||
}
|
||||
if (schemaDocument.initialValues.config !== undefined) {
|
||||
if (node.config === undefined) {
|
||||
node.config = schemaDocument.initialValues.config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* For the cases where an node is not chained to its parent but to the one at the parent before it at its collection */
|
||||
if (schemaDocument.chainedToSameType === true) {
|
||||
if (parentNode !== undefined) {
|
||||
let parentSchemaDocument = getSchemaDocument(parentNode)
|
||||
if (parentSchemaDocument !== undefined) {
|
||||
if (parentSchemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < parentSchemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = parentSchemaDocument.childrenNodesProperties[i]
|
||||
if (property.childType === node.type) {
|
||||
if (property.type === 'array') {
|
||||
if (parentNode[property.name] !== undefined) {
|
||||
if (parentNode[property.name].length > 1) {
|
||||
let nodeChildren = parentNode[property.name]
|
||||
for (let j = 0; j < nodeChildren.length; j++) {
|
||||
if (node.id === nodeChildren[j].id) {
|
||||
if (j > 0) {
|
||||
chainParent = nodeChildren[j - 1]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Create Self */
|
||||
createUiObject(false, node.type, node.name, node, parentNode, chainParent, node.type, positionOffset)
|
||||
|
||||
/* Create Children */
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
if (node[property.name] !== undefined) {
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (property.name !== previousPropertyName) {
|
||||
createUiObjectFromNode(node[property.name], node, node, positionOffset)
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let nodePropertyArray = node[property.name]
|
||||
for (let m = 0; m < nodePropertyArray.length; m++) {
|
||||
let arrayItem = nodePropertyArray[m]
|
||||
createUiObjectFromNode(arrayItem, node, node, positionOffset)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
} else {
|
||||
if (property.type === 'array') {
|
||||
node[property.name] = []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addUIObject(parentNode, type, rootNodes, project) {
|
||||
if (project === undefined) { project = parentNode.project }
|
||||
|
||||
let object = {
|
||||
name: 'New ' + type,
|
||||
type: type,
|
||||
project: project
|
||||
}
|
||||
|
||||
let parentSchemaDocument
|
||||
/* Resolve Initial Values */
|
||||
let schemaDocument = getSchemaDocument(object, project)
|
||||
|
||||
if (schemaDocument === undefined) {
|
||||
console.log('Cannot addUIOBject of type "' + type + '" and project "' + project + '" because that type it is not defined at the APP_SCHEMA.')
|
||||
return
|
||||
}
|
||||
|
||||
if (schemaDocument.initialValues !== undefined) {
|
||||
if (schemaDocument.initialValues.code !== undefined) {
|
||||
object.code = schemaDocument.initialValues.code
|
||||
}
|
||||
}
|
||||
if (schemaDocument.initialValues !== undefined) {
|
||||
if (schemaDocument.initialValues.config !== undefined) {
|
||||
object.config = schemaDocument.initialValues.config
|
||||
}
|
||||
}
|
||||
|
||||
let chainParent = parentNode
|
||||
if (schemaDocument.isHierarchyHead === true || schemaDocument.isProjectHead) {
|
||||
rootNodes.push(object)
|
||||
initializeArrayProperties()
|
||||
applyInitialValues()
|
||||
createUiObject(true, object.type, object.name, object, parentNode, undefined)
|
||||
autoAddChildren()
|
||||
return object
|
||||
|
||||
} else {
|
||||
|
||||
parentSchemaDocument = getSchemaDocument(parentNode, parentNode.project)
|
||||
if (parentSchemaDocument === undefined) {
|
||||
console.log('Cannot addUIOBject from parent of type "' + type + '" and project "' + parentNode.project + '" because that type it is not defined at the APP_SCHEMA.')
|
||||
return
|
||||
}
|
||||
checkChainToSelfTypeCollection()
|
||||
initializeArrayProperties()
|
||||
applyInitialValues()
|
||||
connectToParent()
|
||||
createUiObject(true, object.type, object.name, object, parentNode, chainParent)
|
||||
autoAddChildren()
|
||||
return object
|
||||
}
|
||||
|
||||
function checkChainToSelfTypeCollection() {
|
||||
/* For the cases where a node is not chained to its parent but to the one at the parent before it at its own collection */
|
||||
|
||||
if (schemaDocument.chainedToSameType === true) {
|
||||
if (parentSchemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < parentSchemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = parentSchemaDocument.childrenNodesProperties[i]
|
||||
if (property.childType === type) {
|
||||
if (property.type === 'array') {
|
||||
if (parentNode[property.name] !== undefined) {
|
||||
if (parentNode[property.name].length > 0) {
|
||||
let nodeChildren = parentNode[property.name]
|
||||
chainParent = nodeChildren[nodeChildren.length - 1]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function initializeArrayProperties() {
|
||||
/* Create Empty Arrays for properties of type Array */
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
if (property.type === 'array') {
|
||||
object[property.name] = []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function applyInitialValues() {
|
||||
if (schemaDocument.initialValues !== undefined) {
|
||||
if (schemaDocument.initialValues.code !== undefined) {
|
||||
object.code = schemaDocument.initialValues.code
|
||||
}
|
||||
if (schemaDocument.initialValues.config !== undefined) {
|
||||
object.config = schemaDocument.initialValues.config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function connectToParent() {
|
||||
/* Connect to Parent */
|
||||
if (parentSchemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < parentSchemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = parentSchemaDocument.childrenNodesProperties[i]
|
||||
if (property.childType === type) {
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (property.name !== previousPropertyName) {
|
||||
parentNode[property.name] = object
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
if (parentNode[property.name] === undefined) {
|
||||
parentNode[property.name] = []
|
||||
}
|
||||
if (property.maxItems !== undefined) {
|
||||
if (parentNode[property.name].length < property.maxItems) {
|
||||
parentNode[property.name].push(object)
|
||||
} else {
|
||||
return // Object can not be created.
|
||||
}
|
||||
} else {
|
||||
parentNode[property.name].push(object)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function autoAddChildren() {
|
||||
/* Auto Add more Children */
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (property.name !== previousPropertyName) {
|
||||
if (property.autoAdd === true) {
|
||||
let project = property.project
|
||||
addUIObject(object, property.childType, undefined, project)
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
if (property.autoAdd === true) {
|
||||
if (object[property.name] === undefined) {
|
||||
object[property.name] = []
|
||||
}
|
||||
let project = property.project
|
||||
addUIObject(object, property.childType, undefined, project)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addMissingChildren(node, rootNodes) {
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
|
||||
/* Connect to Parent */
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
let previousPropertyName // Since there are cases where there are many properties with the same name,because they can hold nodes of different types but only one at the time, we have to avoind counting each property of those as individual children.
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
if (property.type === 'node') {
|
||||
if (property.name !== previousPropertyName) {
|
||||
if (node[property.name] === undefined) {
|
||||
let currenAngleToParent = node.payload.floatingObject.angleToParent
|
||||
node.payload.floatingObject.angleToParent = ANGLE_TO_PARENT.RANGE_180
|
||||
let uiObject = addUIObject(node, property.childType, rootNodes, property.project)
|
||||
node.payload.floatingObject.angleToParent = currenAngleToParent
|
||||
//uiObject.payload.floatingObject.angleToParent = currenAngleToParent
|
||||
previousPropertyName = property.name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createUiObject(userAddingNew, uiObjectType, name, node, parentNode, chainParent, title, positionOffset) {
|
||||
let payload = {}
|
||||
|
||||
/* Mechanism related to keeping references when cloning */
|
||||
if (node.id === undefined) {
|
||||
node.id = newUniqueId()
|
||||
} else {
|
||||
/*
|
||||
We need to avoid nodes having the same id. If we add nodes to a workspace that already exist with the same Id,
|
||||
the nodes being added will get a new id at this moment.
|
||||
*/
|
||||
let testNode = mapOfNodes.get(node.id)
|
||||
if (testNode !== undefined && testNode.cleaned !== true) {
|
||||
node.id = newUniqueId()
|
||||
console.log(testNode.name + ' already have the id of the node ' + node.name + ' being added. Creating a new id for it: ' + node.id)
|
||||
}
|
||||
}
|
||||
|
||||
/* Default Naming */
|
||||
if (name === '' || name === undefined) { name = 'My ' + uiObjectType }
|
||||
|
||||
/* If we are creating this object as the result of restoring a backup, share or clone, we will bring some of the saved properties to the new running instance. */
|
||||
if (userAddingNew === false && uiObjectType !== 'Workspace') {
|
||||
/* This following info can not be missing. */
|
||||
if (node.savedPayload === undefined) {
|
||||
console.log('Node ' + node.type + ' without savedPayload.', node)
|
||||
return
|
||||
}
|
||||
if (node.savedPayload.position === undefined) {
|
||||
console.log('Node ' + node.type + ' without savedPayload.position.', node)
|
||||
return
|
||||
}
|
||||
if (node.savedPayload.targetPosition === undefined) {
|
||||
console.log('Node ' + node.type + ' without savedPayload.targetPosition.', node)
|
||||
return
|
||||
}
|
||||
|
||||
/* If there is not a position offset, which happens when we are dropping a node into the designer, we create a cero vector then. */
|
||||
if (positionOffset === undefined) {
|
||||
positionOffset = {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
}
|
||||
|
||||
/* Adding the offset to the saved positions. */
|
||||
node.savedPayload.targetPosition.x = node.savedPayload.targetPosition.x + positionOffset.x
|
||||
node.savedPayload.targetPosition.y = node.savedPayload.targetPosition.y + positionOffset.y
|
||||
node.savedPayload.position.x = node.savedPayload.position.x + positionOffset.x
|
||||
node.savedPayload.position.y = node.savedPayload.position.y + positionOffset.y
|
||||
|
||||
/* Transferring the saved payload properties into the running instance being created. */
|
||||
payload.targetPosition = {
|
||||
x: node.savedPayload.targetPosition.x,
|
||||
y: node.savedPayload.targetPosition.y
|
||||
}
|
||||
node.savedPayload.targetPosition = undefined
|
||||
|
||||
/* Reference children connection to parents */
|
||||
if (node.savedPayload.referenceParent !== undefined) {
|
||||
payload.referenceParent = mapOfNodes.get(node.savedPayload.referenceParent.id)
|
||||
|
||||
if (payload.referenceParent !== undefined) {
|
||||
mapOfReferenceChildren.set(node.id, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are adding a new object, then we set the initial values for position and targetPosition */
|
||||
if (userAddingNew === true || uiObjectType === 'Workspace') {
|
||||
/* Workspace allways to the spawn position */
|
||||
if (uiObjectType === 'Workspace') {
|
||||
payload.position = {
|
||||
x: spawnPosition.x,
|
||||
y: spawnPosition.y
|
||||
}
|
||||
}
|
||||
|
||||
/* Chain parent pointing to the position of the chain parent if defined. */
|
||||
if (chainParent === undefined) {
|
||||
if (parentNode !== undefined) {
|
||||
payload.targetPosition = {
|
||||
x: parentNode.payload.position.x,
|
||||
y: parentNode.payload.position.y
|
||||
}
|
||||
} else {
|
||||
payload.targetPosition = {
|
||||
x: spawnPosition.x,
|
||||
y: spawnPosition.y
|
||||
}
|
||||
}
|
||||
} else {
|
||||
payload.targetPosition = {
|
||||
x: chainParent.payload.position.x,
|
||||
y: chainParent.payload.position.y
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
payload.visible = true
|
||||
payload.title = name
|
||||
payload.node = node
|
||||
payload.parentNode = parentNode
|
||||
payload.chainParent = chainParent
|
||||
payload.executeAction = UI.projects.foundations.spaces.designSpace.workspace.executeAction
|
||||
|
||||
node.payload = payload
|
||||
node.type = uiObjectType
|
||||
|
||||
/*
|
||||
Now we copy the possible frame saved to the payload where it can be used. A saved frame stores the position of a a chartingSpace object related to a node.
|
||||
This will prevent that if those charting space objects never get activated, that the frame information is lost when the workspace is saved.
|
||||
*/
|
||||
if (node.savedPayload !== undefined) {
|
||||
if (node.savedPayload.frame !== undefined) {
|
||||
let frame = {
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
}
|
||||
frame.position.x = node.savedPayload.frame.position.x
|
||||
frame.position.y = node.savedPayload.frame.position.y
|
||||
frame.width = node.savedPayload.frame.width
|
||||
frame.height = node.savedPayload.frame.height
|
||||
frame.radius = node.savedPayload.frame.radius
|
||||
UI.projects.foundations.utilities.loadSaveFrame.saveFrame(payload, frame)
|
||||
}
|
||||
if (node.savedPayload.tutorial !== undefined) {
|
||||
let tutorial = {
|
||||
status: node.savedPayload.tutorial.status
|
||||
}
|
||||
UI.projects.foundations.utilities.tutorial.saveTutorial(payload, tutorial)
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we mount the floating object where the UIOBject will be laying on top of */
|
||||
UI.projects.foundations.spaces.floatingSpace.uiObjectConstructor.createUiObject(userAddingNew, payload)
|
||||
|
||||
/* This is the point where we build a map with all nodes present at the workspace */
|
||||
mapOfNodes.set(node.id, node)
|
||||
|
||||
/* We will collect all tasks at the workspace in order to later syncronize them with the client */
|
||||
if (userAddingNew === false && uiObjectType === 'Task' && node.savedPayload !== undefined) {
|
||||
if (tasksFoundAtWorkspace !== undefined) { // it might be undefined when you are spawning a task that was backed up
|
||||
tasksFoundAtWorkspace.push(node)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if there are sessions to run */
|
||||
if (userAddingNew === false && node.savedPayload !== undefined) {
|
||||
if (uiObjectType === 'Live Trading Session' || uiObjectType === 'Forward Testing Session' || uiObjectType === 'Backtesting Session' || uiObjectType === 'Paper Trading Session') {
|
||||
if (tradingSessionsFoundAtWorkspace !== undefined) { // it might be undefined when you are spawning a session that was running while backed up
|
||||
tradingSessionsFoundAtWorkspace.push(node)
|
||||
}
|
||||
}
|
||||
if (uiObjectType === 'Learning Session') {
|
||||
if (learningSessionsFoundAtWorkspace !== undefined) { // it might be undefined when you are spawning a session that was running while backed up
|
||||
learningSessionsFoundAtWorkspace.push(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if there are tutorials to play */
|
||||
if (userAddingNew === false && node.savedPayload !== undefined) {
|
||||
if (uiObjectType === 'Tutorial') {
|
||||
if (node.savedPayload.uiObject.isPlaying === true) {
|
||||
if (tutorialsToPlay !== undefined) { // it might be undefined when you are spawning a tutorial that was playing while backed up
|
||||
tutorialsToPlay.push(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user