diff --git a/CloudVM/CloudSupport.js b/CloudVM/CloudSupport.js index 654a21de7..bd9f9cbfe 100644 --- a/CloudVM/CloudSupport.js +++ b/CloudVM/CloudSupport.js @@ -9,7 +9,7 @@ When running at the clode on NodeJS some things work diffently that at the brows -function runBot(pUI_COMMANDS) { +function onBotPlayPressed(pUI_COMMANDS) { window.SHALL_BOT_STOP = false; @@ -17,18 +17,16 @@ function runBot(pUI_COMMANDS) { window.STORAGE_PERMISSIONS = ecosystem.getStoragePermissions(); window.EXCHANGE_KEYS = ecosystem.getExchangeKeys(); - let root = newRoot(); - - root.initialize(pUI_COMMANDS, onInitialized); + cloudVM.initialize(pUI_COMMANDS, onInitialized); function onInitialized() { - root.start(); + cloudVM.start(); } } -function stopBot() { +function onBotStopPressed() { window.SHALL_BOT_STOP = true; diff --git a/Dashboard.js b/Dashboard.js index 82d8e3ab1..c56b6d7ce 100644 --- a/Dashboard.js +++ b/Dashboard.js @@ -89,7 +89,7 @@ function convertTimePeriodToName(pTimePeriod) { } } - +let cloudVM = newRoot(); const DEBUG_START_UP_DELAY = 0 //3000; // This is a waiting time in case there is a need to debug the very first steps of initialization, to be able to hit F12 on time. const INITIAL_DEFAULT_MARKET = 2; // This is the market that will be shown when loading the site for the first time. diff --git a/FloatingSpace/FloatingLayer.js b/FloatingSpace/FloatingLayer.js index 2a3764a9d..3b47bbdf6 100644 --- a/FloatingSpace/FloatingLayer.js +++ b/FloatingSpace/FloatingLayer.js @@ -1,6 +1,19 @@  function newFloatingLayer() { + /* + This module represent one layer of many possible layers that could be at the Floating Space. Objects in the same layer are subject to + the same physics, and by being at the same level, they interact with each other. For example, they can bounce when one hit the other. + This module posesses its own physics engine. There are different types of floating objects, but this layer takes care of each of them. + + Floating Objects Types: + + 1. Profile Balls: These are small balls with a profile picture, and two levels, one above and one below the ball. They are usually used + to specify the location of a bot instance. + + 2. Notes: Notes are a rectangular area where some text is posted. It has a subject and a body. + */ + const MODULE_NAME = "Floating Layer"; const INFO_LOG = false; let INTENSIVE_LOG = false; @@ -19,8 +32,33 @@ function newFloatingLayer() { initialize: initialize }; - let visibleFloatingObjects = []; + /* + When objects are added to this layer they are added to the invisibleFloatingObjects array and they stay there because they are invisible. + Visibility of objects is not decided at this layer, but outside. The ones who decides which object is visible or not are plotters, because + they know the position of objects and the coordinate system which these positions belong to. + + To save resources, the physics engine only apply its calculations to visible floating objects. + */ + let invisibleFloatingObjects = []; + + /* + Floating objects are accesible to plotters because they carry a "payload" object that was creted by them. This object includes the position + and visible property. When visible turns to true, this layer module will move the reference of the floating object from the invisible array + to the visibleFloatingObjects array. If the plotter decides that the object is to far from the what the user is seeing, it can eventually + turn the visible property off again, forcing the layer to remove the object from the visibleFloatingObjects and place it again at the invisible + array. + */ + + let visibleFloatingObjects = []; + + /* + The creator of the floatingObject at any time can decide to get rid of it and kill it. But we dont want the object just to dissapear because + that doesnt look good. What this module does is to remove it from the visible or invisible layer where they are and move them to the + dyingFloatingObjects array. Object in this array have a short animation until they finally graphically dissapear and at thay point they are also + removed from the dying array for good. + */ + let dyingFloatingObjects = []; let maxTargetRepulsionForce = 0.0005; @@ -33,17 +71,25 @@ function newFloatingLayer() { if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); } + /* We dont need to initialize anything right now. */ + if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE); } } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err.message = " + err.message); } if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE); } } } function addFloatingObject(pFloatingObject, callBackFunction) { + /* + As you can see here, even though the floating objects are created outside this layer, its creator it is not supossed to keep + the reference to the object, so that the managment of the objects references can live entirely inside this module. What the + creator keeps, is a handle to the object which it can use to retrieve the floating object when needed. + */ + try { if (INFO_LOG === true) { logger.write("[INFO] addFloatingObject -> Entering function."); } @@ -61,7 +107,7 @@ function newFloatingLayer() { } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] addFloatingObject -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] addFloatingObject -> err.message = " + err.message); } if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE); } } } @@ -70,6 +116,11 @@ function newFloatingLayer() { try { + /* + The floting object to be killed can be either at the visible or the invisible array. What we do here is look for it + at each of the arrays until we find it. Once found, we remove it and is sent to the dying floating objects array. + */ + if (INFO_LOG === true) { logger.write("[INFO] killFloatingObject -> Entering function."); } for (let i = 0; i < invisibleFloatingObjects.length; i++) { @@ -176,20 +227,26 @@ function newFloatingLayer() { } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] killFloatingObject -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] killFloatingObject -> err.message = " + err.message); } if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE); } } } } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] killFloatingObject -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] killFloatingObject -> err.message = " + err.message); } if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE); } } } function getFloatingObject(pFloatingObjectHandle, pFloatingObjectIndex) { + /* + There are two ways to look for a floating object: by handle or by index. The search by handle is done on the visible and invisible array. + The search by index is done only on the visible ones. The search by index is usually needed when mouse events occurs. In those cases + only objects visible to the end usser matters. + */ + try { if (INFO_LOG === true) { logger.write("[INFO] getFloatingObject -> Entering function."); } @@ -231,7 +288,7 @@ function newFloatingLayer() { } } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] getFloatingObject -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] getFloatingObject -> err.message = " + err.message); } } } @@ -244,16 +301,30 @@ function newFloatingLayer() { function physicsLoop() { + /* + The Physics engine is hooked at the animation loop, so it executes very very often. According to this Physics engine, each + floating object has a position and a speed. In fact, each floating object has two positions at the same time: + + 1. The current position: is the position of the ball, floating around. + 2. The anchor position: is the position of where the ball is achored on the plot. This one is inside the payload object controlled by the + plotter. + + The anchor position influences the current position, since the Physics engine will apply a gravity force to the ball's position in order + to make it gravitate towards the anchor position. At the same time there will be a repulsion force that will prevent the ball reaching + the anchor position, so that the anchor point keeps visible to the user. + + */ + try { if (INTENSIVE_LOG === true) { logger.write("[INFO] physicsLoop -> Entering function."); } - /* This function makes all the calculations to apply phisycs on all floatingObjects in this space. */ - applyPhysics(); function applyPhysics() { + /* This function makes all the calculations to apply phisycs on all visible floatingObjects in this layer. */ + try { if (INTENSIVE_LOG === true) { logger.write("[INFO] physicsLoop -> applyPhysics -> Entering function."); } @@ -267,7 +338,7 @@ function newFloatingLayer() { floatingObject.currentPosition.x = floatingObject.currentPosition.x + floatingObject.currentSpeed.x; floatingObject.currentPosition.y = floatingObject.currentPosition.y + floatingObject.currentSpeed.y; - if (INTENSIVE_LOG === true) { logger.write("[INFO] physicsLoop -> Apply some friction to desacelerate."); } + if (INTENSIVE_LOG === true) { logger.write("[INFO] physicsLoop -> Apply some friction to desaccelerate."); } floatingObject.currentSpeed.x = floatingObject.currentSpeed.x * floatingObject.friction; // Desaceleration factor. floatingObject.currentSpeed.y = floatingObject.currentSpeed.y * floatingObject.friction; // Desaceleration factor. @@ -381,7 +452,7 @@ function newFloatingLayer() { catch(err) { - if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> applyPhysics -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> applyPhysics -> err.message = " + err.message); } } } @@ -409,7 +480,7 @@ function newFloatingLayer() { catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> drawVisibleObjects -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> drawVisibleObjects -> err.message = " + err.message); } } } @@ -482,7 +553,7 @@ function newFloatingLayer() { catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> makeVisible -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> makeVisible -> err.message = " + err.message); } } } @@ -548,7 +619,7 @@ function newFloatingLayer() { catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> makeInvisible -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> makeInvisible -> err.message = " + err.message); } } } @@ -585,7 +656,7 @@ function newFloatingLayer() { catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> animateDyingObjects -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> animateDyingObjects -> err.message = " + err.message); } } } @@ -611,13 +682,13 @@ function newFloatingLayer() { catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> drawDyingObjects -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> drawDyingObjects -> err.message = " + err.message); } } } } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] physicsLoop -> err.message = " + err.message); } } } @@ -671,7 +742,7 @@ function newFloatingLayer() { floatingObject.currentSpeed.y = floatingObject.currentSpeed.y + forceVector.y; } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] gravityForce -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] gravityForce -> err.message = " + err.message); } } } @@ -738,7 +809,7 @@ function newFloatingLayer() { } } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] currentRepulsionForce -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] currentRepulsionForce -> err.message = " + err.message); } } } @@ -823,7 +894,7 @@ function newFloatingLayer() { } } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] targetRepulsionForce -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] targetRepulsionForce -> err.message = " + err.message); } } } @@ -851,7 +922,7 @@ function newFloatingLayer() { } } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] changeTargetRepulsion -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] changeTargetRepulsion -> err.message = " + err.message); } } } @@ -883,7 +954,7 @@ function newFloatingLayer() { else return true; } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] colliding -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] colliding -> err.message = " + err.message); } } } @@ -906,7 +977,7 @@ function newFloatingLayer() { return -1; } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] isInside -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] isInside -> err.message = " + err.message); } } } @@ -928,7 +999,7 @@ function newFloatingLayer() { return false; } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] isInsideFloatingObject -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] isInsideFloatingObject -> err.message = " + err.message); } } } @@ -941,7 +1012,7 @@ function newFloatingLayer() { return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] distance -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] distance -> err.message = " + err.message); } } } @@ -1022,7 +1093,7 @@ function newFloatingLayer() { floatingObject2.currentPosition = pos2; } catch (err) { - if (ERROR_LOG === true) { logger.write("[ERROR] resolveCollision -> err = " + err); } + if (ERROR_LOG === true) { logger.write("[ERROR] resolveCollision -> err.message = " + err.message); } } } } diff --git a/FloatingSpace/NoteSets.js b/FloatingSpace/NoteSets.js index 673874e4f..512c297fb 100644 --- a/FloatingSpace/NoteSets.js +++ b/FloatingSpace/NoteSets.js @@ -1,6 +1,19 @@  function newNoteSets() { + /* + Different plotters will identify sets of notes whithin the data they are plotting. They will create with them arrays of Notes data. + On the other hand the floating space, and a floting layer in particular, manages Notes floating objects, which are visible entities + that floats on the screen. These entities are animated at a certain peace, and their life cycle differs from the life cycle of the + arrays of raw data plotters have. + + The purpose of this module, is to provide a mechnism of syncronization between the raw data and the visible floating objects and a + data structure wheere to store these floating objects. + + A NoteSet in this context is an array of Notes floating objects belonging to the same owner, which could be a certain bot for instance. + This module is capable of managing an array of NoteSets. + */ + const MODULE_NAME = "Note Sets"; const INFO_LOG = false; const ERROR_LOG = true; @@ -20,6 +33,10 @@ function newNoteSets() { function initialize(pFloatingLayer, callBackFunction) { + /* + During the initialization process, we receive the floatingLayer where all the floatingObjects we will be creating here will live at. + */ + try { if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); } @@ -37,230 +54,286 @@ function newNoteSets() { function createNoteSet(pPayload, pEventHandler, callBackFunction) { - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> Entering function."); } + try { + /* + During the creating of a NoteSet, no floating objects are created yet. What we do here is to create the data structure which will allocate + the Notes floating objects, once we receive the array of notes raw data from the plotter. This array will come as an event raised by the + plotter everytime it's set of raw data changes. Remember that the plotter is not only filtering out notes based on how far they are from the + position the user gives to the viewport, but also, the plotter can be receiving actually new notes from its datasource. + */ - let noteSet = { - imageId: pPayload.profile.imageId, - floatingNotes: [], - payload: pPayload, - handle: Math.floor((Math.random() * 10000000) + 1) - }; + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> Entering function."); } - noteSets.push(noteSet); + let noteSet = { + imageId: pPayload.profile.imageId, + floatingNotes: [], + payload: pPayload, + handle: Math.floor((Math.random() * 10000000) + 1) + }; - pEventHandler.listenToEvent("Notes Changed", onNotesChanged, noteSets.length - 1) + noteSets.push(noteSet); - callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE, noteSet.handle); + pEventHandler.listenToEvent("Notes Changed", onNotesChanged, noteSets.length - 1) - function onNotesChanged(pNewNotes, pNoteSetIndex) { + callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE, noteSet.handle); - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Entering function."); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> pNewNotes.length = " + pNewNotes.length); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> pNoteSetIndex = " + pNoteSetIndex); } + function onNotesChanged(pNewNotes, pNoteSetIndex) { - let noteSet = noteSets[pNoteSetIndex]; - let found = false; - let newFloatingNotes; + try { - /* First we remove the old notes. */ + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Entering function."); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> pNewNotes.length = " + pNewNotes.length); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> pNoteSetIndex = " + pNoteSetIndex); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes."); } + let noteSet = noteSets[pNoteSetIndex]; + let found = false; + let newFloatingNotes; - newFloatingNotes = []; // We will create a new array of Floating Notes as a result of this operation. + /* + First we remove the old notes. This means that we are going to scan all the floating objects that we have, and see one by one if they + are still present on the raw data sent by the plotter. If it is not there, that means that the floating object must be discarded. + */ - for (let j = 0; j < noteSet.floatingNotes.length; j++) { + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes."); } - found = false; + newFloatingNotes = []; // We will create a new array of Floating Notes as a result of this operation. - let floatingNote = noteSet.floatingNotes[j]; - let floatingNoteKey = floatingNote.date.toString() + floatingNote.rate.toString(); + /* + Here we scan the curren array of floating objects. We use the date + rate to create a unique key for each one, in order to be able to + compare it with the raw data. You will notice that instead of deleting from the current array what we actually do is to add the ones + that are still at the raw data array to a new array, and not adding the ones that are not. + */ - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> j = " + j); } + for (let j = 0; j < noteSet.floatingNotes.length; j++) { - let i; + found = false; - for (i = 0; i < pNewNotes.length; i++) { + let floatingNote = noteSet.floatingNotes[j]; + let floatingNoteKey = floatingNote.date.toString() + floatingNote.rate.toString(); - let plotterNote = pNewNotes[i]; - let plotterNoteKey = plotterNote.date.toString() + plotterNote.rate.toString(); + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> j = " + j); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> i = " + i); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingNoteKey = " + floatingNoteKey); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> plotterNoteKey = " + plotterNoteKey); } + let i; - if (plotterNoteKey === floatingNoteKey) { + for (i = 0; i < pNewNotes.length; i++) { - found = true; + let plotterNote = pNewNotes[i]; + let plotterNoteKey = plotterNote.date.toString() + plotterNote.rate.toString(); - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> found = " + found); } - break; - } - } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> i = " + i); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingNoteKey = " + floatingNoteKey); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> plotterNoteKey = " + plotterNoteKey); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> End of For i."); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> found = " + found); } + if (plotterNoteKey === floatingNoteKey) { - if (found === false) { + found = true; - floatingLayer.killFloatingObject(floatingNote.floatingHandle); - - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingNote.floatingHandle = " + floatingNote.floatingHandle); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> Removed from Layer."); } - - } else { - - newFloatingNotes.push(floatingNote); - - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingNote.floatingHandle = " + floatingNote.floatingHandle); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> Added to newFloatingNotes."); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> newFloatingNotes.length = " + newFloatingNotes.length); } - - let floatingObject = floatingLayer.getFloatingObject(floatingNote.floatingHandle); - floatingObject.payloadNoteIndex = i; - - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingObject index updated."); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingObject.payloadNoteIndex = " + i); } - - } - } - - noteSet.floatingNotes = newFloatingNotes; - - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> noteSet.floatingNotes.length = " + noteSet.floatingNotes.length); } - - /* Second we add the new notes. */ - - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes."); } - - newFloatingNotes = []; // We will create a new array of Floating Notes as a result of this operation. - - for (let i = 0; i < pNewNotes.length; i++) { - - found = false; - - let plotterNote = pNewNotes[i]; - let plotterNoteKey = plotterNote.date.toString() + plotterNote.rate.toString(); - let floatingNote; - let floatingNoteKey; - - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> i = " + i); } - - for (let j = 0; j < noteSet.floatingNotes.length; j++) { - - floatingNote = noteSet.floatingNotes[j]; - floatingNoteKey = floatingNote.date.toString() + floatingNote.rate.toString(); - - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> j = " + j); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> floatingNoteKey = " + floatingNoteKey); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> plotterNoteKey = " + plotterNoteKey); } - - if (plotterNoteKey === floatingNoteKey) { - - found = true; - - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> found = " + found); } - break; - } - } - - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> End of For j."); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> found = " + found); } - - if (found === false) { - - let floatingObject = newFloatingObject(); - floatingObject.initialize("Note", onInitialized); - - function onInitialized(err) { - - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Entering function."); } - - floatingObject.payload = noteSet.payload; - floatingObject.payloadNoteIndex = i; - floatingObject.payloadImageId = noteSet.imageId; - - floatingObject.friction = .995; - - floatingObject.initializeMass(200); - - //let bodyText = pNewNotes[i].body; - let radius; - - /* - if (bodyText.length < 100) { - radius = 100; - } else { - radius = bodyText.length; + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> found = " + found); } + break; + } } - */ - radius = 50; - floatingObject.initializeRadius(radius); - floatingObject.initializeImageSize(15); + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> End of For i."); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> found = " + found); } - floatingObject.fillStyle = 'rgba(255, 255, 255, 0.5)'; - floatingObject.labelStrokeStyle = 'rgba(60, 60, 60, 0.50)'; + if (found === false) { - floatingLayer.addFloatingObject(floatingObject); + /* + Each time we identify a floatingObject that is not at the raw data anymore, we request the floatinglayer to kill it. + */ - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> New Note added to Layer."); } + floatingLayer.killFloatingObject(floatingNote.floatingHandle); - plotterNote.floatingHandle = floatingObject.handle; + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingNote.floatingHandle = " + floatingNote.floatingHandle); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> Removed from Layer."); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> plotterNote.floatingHandle = " + plotterNote.floatingHandle); } + } else { - newFloatingNotes.push(plotterNote); + newFloatingNotes.push(floatingNote); - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Added to newFloatingNotes."); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> newFloatingNotes.length = " + newFloatingNotes.length); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingNote.floatingHandle = " + floatingNote.floatingHandle); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> Added to newFloatingNotes."); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> newFloatingNotes.length = " + newFloatingNotes.length); } + let floatingObject = floatingLayer.getFloatingObject(floatingNote.floatingHandle); + floatingObject.payloadNoteIndex = i; + + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingObject index updated."); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingObject.payloadNoteIndex = " + i); } + + } } - } else { + /* + We replace the current array, with the new one that only contains the surviving floating objects, meaning the ones that are still at the raw data received. + */ - newFloatingNotes.push(floatingNote); + noteSet.floatingNotes = newFloatingNotes; - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Old Note Kept."); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> floatingNote.floatingHandle = " + floatingNote.floatingHandle); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Added to newFloatingNotes."); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> newFloatingNotes.length = " + newFloatingNotes.length); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> noteSet.floatingNotes.length = " + noteSet.floatingNotes.length); } - let floatingObject = floatingLayer.getFloatingObject(floatingNote.floatingHandle); - floatingObject.payloadNoteIndex = i; + /* + Second we add the new notes. There might be new notes at the raw data received that we didnt have before at the NodeSet array. To figure out which + ones are, we need to scan the raw data array and compare each element with the ones of the NodeSet array. Whenever we find one that is not there, + we add it. + */ - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> floatingObject index updated."); } - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> floatingObject.payloadNoteIndex = " + i); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes."); } + newFloatingNotes = []; // We will create a new array of Floating Notes as a result of this operation. + + for (let i = 0; i < pNewNotes.length; i++) { + + found = false; + + let plotterNote = pNewNotes[i]; + let plotterNoteKey = plotterNote.date.toString() + plotterNote.rate.toString(); + let floatingNote; + let floatingNoteKey; + + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> i = " + i); } + + for (let j = 0; j < noteSet.floatingNotes.length; j++) { + + floatingNote = noteSet.floatingNotes[j]; + floatingNoteKey = floatingNote.date.toString() + floatingNote.rate.toString(); + + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> j = " + j); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> floatingNoteKey = " + floatingNoteKey); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> plotterNoteKey = " + plotterNoteKey); } + + if (plotterNoteKey === floatingNoteKey) { + + found = true; + + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> found = " + found); } + break; + } + } + + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> End of For j."); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> found = " + found); } + + if (found === false) { + + /* + Before adding a new item to the array, we need to create a floatingObject of type Note. Once we set its basic parameters + we can it to our array and to the floating layer. + */ + + let floatingObject = newFloatingObject(); + floatingObject.initialize("Note", onInitialized); + + function onInitialized(err) { + + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Entering function."); } + + floatingObject.payload = noteSet.payload; + floatingObject.payloadNoteIndex = i; + floatingObject.payloadImageId = noteSet.imageId; + + floatingObject.friction = .995; + + floatingObject.initializeMass(200); + + //let bodyText = pNewNotes[i].body; + let radius; + + /* + if (bodyText.length < 100) { + radius = 100; + } else { + radius = bodyText.length; + } + */ + radius = 50; + + floatingObject.initializeRadius(radius); + floatingObject.initializeImageSize(15); + + floatingObject.fillStyle = 'rgba(255, 255, 255, 0.5)'; + floatingObject.labelStrokeStyle = 'rgba(60, 60, 60, 0.50)'; + + floatingLayer.addFloatingObject(floatingObject); + + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> New Note added to Layer."); } + + plotterNote.floatingHandle = floatingObject.handle; + + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> plotterNote.floatingHandle = " + plotterNote.floatingHandle); } + + newFloatingNotes.push(plotterNote); + + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Added to newFloatingNotes."); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> newFloatingNotes.length = " + newFloatingNotes.length); } + + } + + } else { + + newFloatingNotes.push(floatingNote); + + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Old Note Kept."); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> floatingNote.floatingHandle = " + floatingNote.floatingHandle); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Added to newFloatingNotes."); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> newFloatingNotes.length = " + newFloatingNotes.length); } + + let floatingObject = floatingLayer.getFloatingObject(floatingNote.floatingHandle); + floatingObject.payloadNoteIndex = i; + + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> floatingObject index updated."); } + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> floatingObject.payloadNoteIndex = " + i); } + + } + } + + noteSet.floatingNotes = newFloatingNotes; + + if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> noteSet.floatingNotes.length = " + noteSet.floatingNotes.length); } + + } catch (err) { + + if (ERROR_LOG === true) { logger.write("[ERROR] createNoteSet -> onNotesChanged -> err = " + err); } } } + } catch (err) { - noteSet.floatingNotes = newFloatingNotes; - - if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> noteSet.floatingNotes.length = " + noteSet.floatingNotes.length); } - + if (ERROR_LOG === true) { logger.write("[ERROR] createNoteSet -> err = " + err); } + callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE); } } function destroyNoteSet(pHandle) { - if (INFO_LOG === true) { logger.write("[INFO] destroyNoteSet -> Entering function."); } + try { + /* + Usually when a bot is disabled by the end user, or the zoom level changes to one where the notes must not be seen, this method + to destroy an entire NoteSet is executed. What we do in this situation is to localize the NoteSet to be destroyed and we need to + kill, one by one the floating objects in it. Finally we remove this NoteSet item from the NoteSets array. + */ - for (let i = 0; i < noteSets.length; i++) { + if (INFO_LOG === true) { logger.write("[INFO] destroyNoteSet -> Entering function."); } - let noteSet = noteSets[i]; + for (let i = 0; i < noteSets.length; i++) { - if (noteSet.handle === pHandle) { + let noteSet = noteSets[i]; - for (let j = 0; j < noteSet.floatingNotes.length; j++) { + if (noteSet.handle === pHandle) { - let floatingNote = noteSet.floatingNotes[j]; + for (let j = 0; j < noteSet.floatingNotes.length; j++) { - floatingLayer.killFloatingObject(floatingNote.floatingHandle); + let floatingNote = noteSet.floatingNotes[j]; + + floatingLayer.killFloatingObject(floatingNote.floatingHandle); + } + + noteSets.splice(i, 1); // Delete item from array. + return; } - - noteSets.splice(i, 1); // Delete item from array. - return; } + } catch (err) { + + if (ERROR_LOG === true) { logger.write("[ERROR] destroyNoteSet -> err = " + err); } } } } diff --git a/Panels/TimeControlPanel.js b/Panels/TimeControlPanel.js index 80441e8e5..ce66a8d7d 100644 --- a/Panels/TimeControlPanel.js +++ b/Panels/TimeControlPanel.js @@ -205,7 +205,7 @@ function newTimeControlPanel() { case "Pause": //pressPause(); - stopBot(); + onBotStopPressed(); break; case "Step Forward": @@ -222,7 +222,7 @@ function newTimeControlPanel() { eventHandler: thisObject.container.eventHandler }; - runBot(UI_COMMANDS); + onBotPlayPressed(UI_COMMANDS); //pressPlayForward(); break;