Files
Superalgos/DesignerSpace/Workspace/Workspace.js
T

698 lines
21 KiB
JavaScript

function newWorkspace () {
const MODULE_NAME = 'Workspace'
const ERROR_LOG = true
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
let thisObject = {
workspaceNode: undefined,
tradingSystem: undefined,
container: undefined,
enabled: false,
nodeChildren: undefined,
getNodeThatIsOnFocus: getNodeThatIsOnFocus,
getNodeByShortcutKey: getNodeByShortcutKey,
getAllTradingBotInstances: getAllTradingBotInstances,
stopAllRunningTasks: stopAllRunningTasks,
onMenuItemClick: onMenuItemClick,
physics: physics,
draw: draw,
spawn: spawn,
chainDetachNode: chainDetachNode,
chainAttachNode: chainAttachNode,
referenceDetachNode: referenceDetachNode,
referenceAttachNode: referenceAttachNode,
initialize: initialize,
finalize: finalize
}
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
thisObject.container.isClickeable = false
thisObject.container.isDraggeable = false
thisObject.container.isWheelable = false
thisObject.container.detectMouseOver = false
thisObject.container.frame.radius = 0
thisObject.container.frame.position.x = 0
thisObject.container.frame.position.y = 0
thisObject.container.frame.width = 0
thisObject.container.frame.height = 0
spawnPosition = {
x: canvas.floatingSpace.container.frame.width / 2,
y: canvas.floatingSpace.container.frame.height / 2
}
thisObject.workspaceNode = {}
thisObject.workspaceNode.rootNodes = []
let functionLibraryReferenceAttachDetach = newReferenceAttachDetach()
let functionLibraryChainAttachDetach = newChainAttachDetach()
let functionLibraryNodeDeleter = newNodeDeleter()
let functionLibraryUiObjectsFromNodes = newUiObjectsFromNodes()
let functionLibraryProtocolNode = newProtocolNode()
let functionLibraryNodeCloning = newNodeCloning()
let functionLibraryTaskFunctions = newTaskFunctions()
let functionLibrarySessionFunctions = newSessionFunctions()
let functionLibraryShortcutKeys = newShortcutKeys()
let functionLibraryOnFocus = newOnFocus()
thisObject.nodeChildren = newNodeChildren()
let workingAtTask = 0
let circularProgressBar = newBusyProgressBar()
circularProgressBar.fitFunction = canvas.floatingSpace.fitIntoVisibleArea
let droppedNode
return thisObject
function finalize () {
thisObject.definition = undefined
thisObject.container.finalize()
thisObject.container = undefined
thisObject.workspaceNode = undefined
circularProgressBar.finalize()
circularProgressBar = undefined
}
function initialize () {
try {
let savedWorkspace = window.localStorage.getItem(CANVAS_APP_NAME + '.' + 'Workspace')
if (savedWorkspace === null) {
thisObject.workspaceNode.type = 'Workspace'
thisObject.workspaceNode.name = 'My Workspace'
} else {
thisObject.workspaceNode = JSON.parse(savedWorkspace)
}
functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode)
thisObject.enabled = true
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> err = ' + err.stack) }
}
}
function chainDetachNode (node) {
functionLibraryChainAttachDetach.chainDetachNode(node, thisObject.workspaceNode.rootNodes)
}
function chainAttachNode (node, attachToNode) {
functionLibraryChainAttachDetach.chainAttachNode(node, attachToNode, thisObject.workspaceNode.rootNodes)
}
function referenceDetachNode (node) {
functionLibraryReferenceAttachDetach.referenceDetachNode(node)
}
function referenceAttachNode (node, attachToNode) {
functionLibraryReferenceAttachDetach.referenceAttachNode(node, attachToNode, thisObject.workspaceNode.rootNodes)
}
function physics () {
if (thisObject.enabled !== true) { return }
let textToSave = stringifyWorkspace()
window.localStorage.setItem(CANVAS_APP_NAME + '.' + 'Workspace', textToSave)
if (workingAtTask > 0) {
circularProgressBar.physics()
switch (workingAtTask) {
case 1:
stopAllRunningTasks()
workingAtTask++
break
case 2:
functionLibraryNodeDeleter.deleteWorkspace(thisObject.workspaceNode, thisObject.workspaceNode.rootNodes)
workingAtTask++
break
case 3:
thisObject.workspaceNode = droppedNode
droppedNode = undefined
workingAtTask++
break
case 4:
functionLibraryUiObjectsFromNodes.recreateWorkspace(thisObject.workspaceNode)
workingAtTask++
break
case 5:
canvas.chartSpace.finalize()
workingAtTask++
break
case 6:
canvas.chartSpace.initialize()
workingAtTask = 0
circularProgressBar.visible = false
break
}
}
}
function draw () {
if (circularProgressBar !== undefined) {
circularProgressBar.draw()
}
}
function stringifyWorkspace (removePersonalData) {
let stringifyReadyNodes = []
for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) {
let rootNode = thisObject.workspaceNode.rootNodes[i]
let node = functionLibraryProtocolNode.getProtocolNode(rootNode, removePersonalData, false, true, true, true)
if (node) {
stringifyReadyNodes.push(node)
}
}
let workspace = {
type: 'Workspace',
name: thisObject.workspaceNode.name,
rootNodes: stringifyReadyNodes
}
return JSON.stringify(workspace)
}
function stopAllRunningTasks () {
for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) {
let rootNode = thisObject.workspaceNode.rootNodes[i]
if (rootNode.type === 'Network') {
if (rootNode.networkNodes !== undefined) {
for (let j = 0; j < rootNode.networkNodes.length; j++) {
let networkNode = rootNode.networkNodes[j]
for (let i = 0; i < networkNode.taskManagers.length; i++) {
let taskManager = networkNode.taskManagers[i]
taskManager.payload.uiObject.menu.internalClick('Stop All Tasks')
}
}
}
}
}
}
function getAllTradingBotInstances () {
let tradingBotInstances = []
for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) {
let rootNode = thisObject.workspaceNode.rootNodes[i]
if (rootNode.type === 'Network') {
if (rootNode.networkNodes !== undefined) {
for (let j = 0; j < rootNode.networkNodes.length; j++) {
let networkNode = rootNode.networkNodes[j]
for (let i = 0; i < networkNode.taskManagers.length; i++) {
let taskManager = networkNode.taskManagers[i]
for (let k = 0; k < taskManager.tasks.length; k++) {
let task = taskManager.tasks[k]
if (task.bot !== undefined) {
if (task.bot.type === 'Trading Bot Instance') {
if (task.bot.payload.floatingObject.isCollapsed !== true) {
tradingBotInstances.push(task.bot)
}
}
}
}
}
}
}
}
}
return tradingBotInstances
}
function getNodeByShortcutKey (searchingKey) {
for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) {
let rootNode = thisObject.workspaceNode.rootNodes[i]
let node = functionLibraryShortcutKeys.getNodeByShortcutKey(rootNode, searchingKey)
if (node !== undefined) { return node }
}
}
function getNodeThatIsOnFocus () {
for (let i = 0; i < thisObject.workspaceNode.rootNodes.length; i++) {
let rootNode = thisObject.workspaceNode.rootNodes[i]
let node = functionLibraryOnFocus.getNodeThatIsOnFocus(rootNode)
if (node !== undefined) { return node }
}
}
function spawn (nodeText, mousePointer) {
try {
let point = {
x: mousePointer.x,
y: mousePointer.y
}
point = canvas.floatingSpace.container.frame.unframeThisPoint(point)
spawnPosition.x = point.x
spawnPosition.y = point.y
droppedNode = JSON.parse(nodeText)
if (droppedNode.type === 'Workspace') {
circularProgressBar.initialize(mousePointer)
circularProgressBar.visible = true
workingAtTask = 1
return
}
/* It does not exist, so we recreeate it respecting the inner state of each object. */
let positionOffset = {
x: spawnPosition.x - droppedNode.savedPayload.targetPosition.x,
y: spawnPosition.y - droppedNode.savedPayload.targetPosition.y
}
thisObject.workspaceNode.rootNodes.push(droppedNode)
functionLibraryUiObjectsFromNodes.createUiObjectFromNode(droppedNode, undefined, undefined, positionOffset)
functionLibraryUiObjectsFromNodes.tryToConnectChildrenWithReferenceParents()
droppedNode = undefined
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] spawn -> err = ' + err.stack) }
}
}
async function onMenuItemClick (payload, action, relatedUiObject, callBackFunction) {
switch (action) {
case 'Add UI Object':
{
functionLibraryUiObjectsFromNodes.addUIObject(payload.node, relatedUiObject)
}
break
case 'Delete UI Object':
{
functionLibraryNodeDeleter.deleteUIObject(payload.node, thisObject.workspaceNode.rootNodes)
}
break
case 'Share Workspace':
{
let text = stringifyWorkspace(true)
let fileName = 'Share - ' + payload.node.type + ' - ' + payload.node.name + '.json'
download(fileName, text)
}
break
case 'Backup Workspace':
{
let text = stringifyWorkspace(false)
let fileName = 'Backup - ' + payload.node.type + ' - ' + payload.node.name + '.json'
download(fileName, text)
}
break
case 'Edit Code':
break
case 'Share':
{
let text = JSON.stringify(functionLibraryProtocolNode.getProtocolNode(payload.node, true, false, true, true, true))
let nodeName = payload.node.name
if (nodeName === undefined) {
nodeName = ''
} else {
nodeName = '.' + nodeName
}
let fileName = 'Share - ' + payload.node.type + ' - ' + nodeName + '.json'
download(fileName, text)
}
break
case 'Backup':
{
let text = JSON.stringify(functionLibraryProtocolNode.getProtocolNode(payload.node, false, false, true, true, true))
let nodeName = payload.node.name
if (nodeName === undefined) {
nodeName = ''
} else {
nodeName = ' ' + nodeName
}
let fileName = 'Backup - ' + payload.node.type + ' - ' + nodeName + '.json'
download(fileName, text)
}
break
case 'Clone':
{
let text = JSON.stringify(functionLibraryNodeCloning.getNodeClone(payload.node))
let nodeName = payload.node.name
if (nodeName === undefined) {
nodeName = ''
} else {
nodeName = ' ' + nodeName
}
let fileName = 'Clone - ' + payload.node.type + ' - ' + nodeName + '.json'
download(fileName, text)
}
break
case 'Run Task':
{
functionLibraryTaskFunctions.runTask(payload.node, functionLibraryProtocolNode, callBackFunction)
}
break
case 'Stop Task':
{
functionLibraryTaskFunctions.stopTask(payload.node, functionLibraryProtocolNode, callBackFunction)
}
break
case 'Run All Tasks':
{
functionLibraryTaskFunctions.runAllTasks(payload.node, functionLibraryProtocolNode)
}
break
case 'Stop All Tasks':
{
functionLibraryTaskFunctions.stopAllTasks(payload.node, functionLibraryProtocolNode)
}
break
case 'Run Session':
{
functionLibrarySessionFunctions.runSession(payload.node, functionLibraryProtocolNode, callBackFunction)
}
break
case 'Stop Session':
{
functionLibrarySessionFunctions.stopSession(payload.node, functionLibraryProtocolNode, callBackFunction)
}
break
case 'Add Definition':
{
functionLibraryUiObjectsFromNodes.addDefinition(payload.node)
}
break
case 'Add Team':
{
functionLibraryUiObjectsFromNodes.addTeam(payload.node)
}
break
case 'Add Sensor Bot':
{
functionLibraryUiObjectsFromNodes.addSensorBot(payload.node)
}
break
case 'Add Indicator Bot':
{
functionLibraryUiObjectsFromNodes.addIndicatorBot(payload.node)
}
break
case 'Add Trading Bot':
{
functionLibraryUiObjectsFromNodes.addTradingBot(payload.node)
}
break
case 'Add Process Definition':
{
functionLibraryUiObjectsFromNodes.addProcessDefinition(payload.node)
}
break
case 'Add Missing Process Definition Items':
{
functionLibraryUiObjectsFromNodes.addMissingProcessDefinitionItems(payload.node)
}
break
case 'Add Missing Product Definition Items':
{
functionLibraryUiObjectsFromNodes.addMissingProductDefinitionItems(payload.node)
}
break
case 'Add Process Output':
{
functionLibraryUiObjectsFromNodes.addProcessOutput(payload.node)
}
break
case 'Add Process Dependencies':
{
functionLibraryUiObjectsFromNodes.addProcessDependencies(payload.node)
}
break
case 'Add Status Report':
{
functionLibraryUiObjectsFromNodes.addStatusReport(payload.node)
}
break
case 'Add Execution Started Event':
{
functionLibraryUiObjectsFromNodes.addExecutionStartedEvent(payload.node)
}
break
case 'Add Execution Finished Event':
{
functionLibraryUiObjectsFromNodes.addExecutionFinishedEvent(payload.node)
}
break
case 'Add Calculations Procedure':
{
functionLibraryUiObjectsFromNodes.addCalculationsProcedure(payload.node)
}
break
case 'Add Data Building Procedure':
{
functionLibraryUiObjectsFromNodes.addDataBuildingProcedure(payload.node)
}
break
case 'Add Procedure Initialization':
{
functionLibraryUiObjectsFromNodes.addProcedureInitialization(payload.node)
}
break
case 'Add Procedure Loop':
{
functionLibraryUiObjectsFromNodes.addProcedureLoop(payload.node)
}
break
case 'Add Output Dataset':
{
functionLibraryUiObjectsFromNodes.addOutputDataset(payload.node)
}
break
case 'Add Status Dependency':
{
functionLibraryUiObjectsFromNodes.addStatusDependency(payload.node)
}
break
case 'Add Data Dependency':
{
functionLibraryUiObjectsFromNodes.addDataDependency(payload.node)
}
break
case 'Add Product Definition':
{
functionLibraryUiObjectsFromNodes.addProductDefinition(payload.node)
}
break
case 'Add Record Definition':
{
functionLibraryUiObjectsFromNodes.addRecordDefinition(payload.node)
}
break
case 'Add Record Property':
{
functionLibraryUiObjectsFromNodes.addRecordProperty(payload.node)
}
break
case 'Add Dataset Definition':
{
functionLibraryUiObjectsFromNodes.addDatasetDefinition(payload.node)
}
break
case 'Add Plotter':
{
functionLibraryUiObjectsFromNodes.addPlotter(payload.node)
}
break
case 'Add Plotter Module':
{
functionLibraryUiObjectsFromNodes.addPlotterModule(payload.node)
}
break
case 'Add Network':
{
functionLibraryUiObjectsFromNodes.addNetwork(payload.node)
}
break
case 'Add Network Node':
{
functionLibraryUiObjectsFromNodes.addNetworkNode(payload.node)
}
break
case 'Add Social Bots':
{
functionLibraryUiObjectsFromNodes.addSocialBots(payload.node)
}
break
case 'Add Telegram Bot':
{
functionLibraryUiObjectsFromNodes.addTelegramBot(payload.node)
}
break
case 'Add Announcement':
{
functionLibraryUiObjectsFromNodes.addAnnouncement(payload.node)
}
break
case 'Add Layer Manager':
{
functionLibraryUiObjectsFromNodes.addLayerManager(payload.node)
}
break
case 'Add Layer':
{
functionLibraryUiObjectsFromNodes.addLayer(payload.node)
}
break
case 'Add Task Manager':
{
functionLibraryUiObjectsFromNodes.addTaskManager(payload.node)
}
break
case 'Add Task':
{
functionLibraryUiObjectsFromNodes.addTask(payload.node)
}
break
case 'Add Sensor Bot Instance':
{
functionLibraryUiObjectsFromNodes.addSensorBotInstance(payload.node)
}
break
case 'Add Indicator Bot Instance':
{
functionLibraryUiObjectsFromNodes.addIndicatorBotInstance(payload.node)
}
break
case 'Add Trading Bot Instance':
{
functionLibraryUiObjectsFromNodes.addTradingBotInstance(payload.node)
}
break
case 'Add Process Instance':
{
functionLibraryUiObjectsFromNodes.addProcessInstance(payload.node)
}
break
case 'Add Backtesting Session':
{
functionLibraryUiObjectsFromNodes.addBacktestingSession(payload.node)
}
break
case 'Add Live Trading Session':
{
functionLibraryUiObjectsFromNodes.addLiveTradingSession(payload.node)
}
break
case 'Add Fordward Testing Session':
{
functionLibraryUiObjectsFromNodes.addFordwardTestingSession(payload.node)
}
break
case 'Add Paper Trading Session':
{
functionLibraryUiObjectsFromNodes.addPaperTradingSession(payload.node)
}
break
case 'Add Strategy':
{
functionLibraryUiObjectsFromNodes.addStrategy(payload.node)
}
break
case 'Add Parameters':
{
functionLibraryUiObjectsFromNodes.addParameters(payload.node)
}
break
case 'Add Missing Parameters':
{
functionLibraryUiObjectsFromNodes.addMissingParameters(payload.node)
}
break
case 'Add Missing Stages':
{
functionLibraryUiObjectsFromNodes.addMissingStages(payload.node)
}
break
case 'Add Missing Events':
{
functionLibraryUiObjectsFromNodes.addMissingEvents(payload.node)
}
break
case 'Add Missing Items':
{
functionLibraryUiObjectsFromNodes.addMissingItems(payload.node)
}
break
case 'Add Initial Definition':
{
functionLibraryUiObjectsFromNodes.addInitialDefinition(payload.node)
}
break
case 'Add Open Execution':
{
functionLibraryUiObjectsFromNodes.addOpenExecution(payload.node)
}
break
case 'Add Close Execution':
{
functionLibraryUiObjectsFromNodes.addCloseExecution(payload.node)
}
break
case 'Add Phase':
{
functionLibraryUiObjectsFromNodes.addPhase(payload.node)
}
break
case 'Add Formula':
{
functionLibraryUiObjectsFromNodes.addFormula(payload.node)
}
break
case 'Add Next Phase Event':
{
functionLibraryUiObjectsFromNodes.addNextPhaseEvent(payload.node)
}
break
case 'Add Situation':
{
functionLibraryUiObjectsFromNodes.addSituation(payload.node)
}
break
case 'Add Condition':
{
functionLibraryUiObjectsFromNodes.addCondition(payload.node)
}
break
case 'Add Code':
{
functionLibraryUiObjectsFromNodes.addJavascriptCode(payload.node)
}
break
case 'Add Exchange Account':
{
functionLibraryUiObjectsFromNodes.addExchangeAccount(payload.node)
}
break
case 'Add Exchange Account Asset':
{
functionLibraryUiObjectsFromNodes.addExchangeAccountAsset(payload.node)
}
break
case 'Add Exchange Account Key':
{
functionLibraryUiObjectsFromNodes.addExchangeAccountKey(payload.node)
}
break
case 'Add Trading System':
{
functionLibraryUiObjectsFromNodes.addTradingSystem(payload.node)
}
break
case 'Add Personal Data':
{
functionLibraryUiObjectsFromNodes.addPersonalData(payload.node)
}
break
default:
}
}
}