diff --git a/Container.js b/Container.js index b5d2872df..b6ef7eace 100644 --- a/Container.js +++ b/Container.js @@ -45,6 +45,9 @@ function newContainer () { thisObject.parentContainer.eventHandler.stopListening(onMouseNotOverEventSubscriptionId) thisObject.parentContainer.eventHandler.stopListening(onFocusEventSubscriptionId) thisObject.parentContainer.eventHandler.stopListening(onNotFocusEventSubscriptionId) + + thisObject.parentContainer = undefined + thisObject.eventHandler.finalize() } } diff --git a/EventHandler.js b/EventHandler.js index ad843afeb..da29745a9 100644 --- a/EventHandler.js +++ b/EventHandler.js @@ -4,13 +4,18 @@ function newEventHandler () { name: undefined, // This is for debugging purposes only. listenToEvent: listenToEvent, stopListening: stopListening, - raiseEvent: raiseEvent + raiseEvent: raiseEvent, + finalize: finalize } - var eventHandlers = [] // Here we store all the functions we will call when an event is raiseed. + let eventHandlers = [] // Here we store all the functions we will call when an event is raiseed. return thisObject + function finalize () { + eventHandlers = [] + } + function listenToEvent (eventType, handler, extraData) { let eventSubscriptionId = Math.trunc(Math.random() * 1000000) eventHandlers.push([eventType, handler, extraData, eventSubscriptionId]) diff --git a/FloatingSpace/CircularMenu.js b/FloatingSpace/CircularMenu.js index 6c2af8b94..8e286884b 100644 --- a/FloatingSpace/CircularMenu.js +++ b/FloatingSpace/CircularMenu.js @@ -9,6 +9,7 @@ function newCircularMenu () { drawBackground: drawBackground, drawForeground: drawForeground, getContainer: getContainer, + finalize: finalize, initialize: initialize } @@ -20,14 +21,29 @@ function newCircularMenu () { thisObject.container.frame.position.x = 0 thisObject.container.frame.position.y = 0 - let menuItemsInitialValues = [] let menuItems = [] - let payload + + let selfFocusEventSubscriptionId + let selfNotFocuskEventSubscriptionId return thisObject - function initialize (menuItemsInitialValues, pPayload) { - payload = pPayload + function finalize () { + thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfNotFocuskEventSubscriptionId) + + thisObject.container.finalize() + thisObject.container = undefined + + for (let i = 0; i < menuItems.length; i++) { + let menuItem = menuItems[i] + menuItem.finalize() + } + + menuItems = undefined + } + + function initialize (menuItemsInitialValues, payload) { /* Create the array of Menu Items */ for (let i = 0; i < menuItemsInitialValues.length; i++) { @@ -49,8 +65,8 @@ function newCircularMenu () { menuItems.push(menuItem) } - thisObject.container.eventHandler.listenToEvent('onFocus', onFocus) - thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus) + selfFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onFocus', onFocus) + selfNotFocuskEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus) } function getContainer (point) { diff --git a/FloatingSpace/CircularMenuItem.js b/FloatingSpace/CircularMenuItem.js index 4be819d05..cb8a25ea4 100644 --- a/FloatingSpace/CircularMenuItem.js +++ b/FloatingSpace/CircularMenuItem.js @@ -16,10 +16,12 @@ function newCircularMenuItem () { currentRadius: undefined, angle: undefined, container: undefined, + payload: undefined, physics: physics, drawBackground: drawBackground, drawForeground: drawForeground, getContainer: getContainer, + finalize: finalize, initialize: initialize } @@ -35,12 +37,26 @@ function newCircularMenuItem () { thisObject.container.frame.height = 30 let isMouseOver = false - let payload + let selfMouseOverEventSubscriptionId + let selfMouseClickEventSubscriptionId + let selfMouseNotOverEventSubscriptionId return thisObject + function finalize () { + thisObject.container.eventHandler.stopListening(selfMouseOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfMouseNotOverEventSubscriptionId) + + thisObject.container.finalize() + thisObject.container = undefined + thisObject.iconOn = undefined + thisObject.iconOff = undefined + thisObject.payload = undefined + } + function initialize (pPayload) { - payload = pPayload + thisObject.payload = pPayload /* Load Menu Images */ thisObject.iconOn = new Image() @@ -58,9 +74,9 @@ function newCircularMenuItem () { thisObject.iconOn.src = window.canvasApp.urlPrefix + thisObject.imagePathOn thisObject.icon = thisObject.iconOn // The default value is ON. - thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) - thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) + selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + selfMouseNotOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseNotOver', onMouseNotOver) } function getContainer (point) { @@ -100,7 +116,7 @@ function newCircularMenuItem () { } function onMouseClick (event) { - payload.onMenuItemClick(payload, thisObject.action) + thisObject.payload.onMenuItemClick(thisObject.payload, thisObject.action) } function drawBackground () { @@ -157,4 +173,3 @@ function newCircularMenuItem () { } } } - diff --git a/FloatingSpace/FloatingLayer.js b/FloatingSpace/FloatingLayer.js index 9f3cab8a1..c74b7f9ba 100644 --- a/FloatingSpace/FloatingLayer.js +++ b/FloatingSpace/FloatingLayer.js @@ -52,30 +52,14 @@ function newFloatingLayer () { 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.001 let currentHandle = 0 return thisObject function finalize () { - try { - if (INFO_LOG === true) { logger.write('[INFO] finalize -> Entering function.') } - - invisibleFloatingObjects = [] - visibleFloatingObjects = [] - dyingFloatingObjects = [] - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) } - } + invisibleFloatingObjects = [] + visibleFloatingObjects = [] } function initialize () { @@ -95,35 +79,19 @@ function newFloatingLayer () { return container } - function addFloatingObject (pFloatingObject, callBackFunction) { + function addFloatingObject (pFloatingObject) { /* 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.') } - - invisibleFloatingObjects.push(pFloatingObject) - - if (INFO_LOG === true) { logger.write('[INFO] addFloatingObject -> invisibleFloatingObjects.length = ' + invisibleFloatingObjects.length) } - - currentHandle++ - - pFloatingObject.handle = currentHandle // Math.floor((Math.random() * 10000000) + 1); - - if (INFO_LOG === true) { logger.write('[INFO] addFloatingObject -> pFloatingObject.handle = ' + pFloatingObject.handle) } - if (INFO_LOG === true) { logger.write('[INFO] addFloatingObject -> pFloatingObject.type = ' + pFloatingObject.type) } - - if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] addFloatingObject -> err= ' + err.stack) } - if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) } - } + invisibleFloatingObjects.push(pFloatingObject) + currentHandle++ + pFloatingObject.handle = currentHandle // Math.floor((Math.random() * 10000000) + 1); } - function killFloatingObject (pFloatingObjectHandle, callBackFunction) { + function killFloatingObject (pFloatingObjectHandle) { 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 @@ -136,7 +104,7 @@ function newFloatingLayer () { if (floatingObject.handle === pFloatingObjectHandle) { invisibleFloatingObjects.splice(i, 1) // Delete item from array. - sendToDie(floatingObject) + floatingObject.finalize() return } } @@ -147,7 +115,7 @@ function newFloatingLayer () { if (floatingObject.handle === pFloatingObjectHandle) { visibleFloatingObjects.splice(i, 1) // Delete item from array. - sendToDie(floatingObject) + floatingObject.finalize() return } } @@ -155,97 +123,8 @@ function newFloatingLayer () { if (ERROR_LOG === true) { logger.write('[ERROR] killFloatingObject -> Floating Object Not Found.') } if (ERROR_LOG === true) { logger.write('[ERROR] killFloatingObject -> Floating Object cannot be killed.') } if (ERROR_LOG === true) { logger.write('[ERROR] killFloatingObject -> pFloatingObjectHandle = ' + pFloatingObjectHandle) } - - if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) } - - function sendToDie (pFloatingObject) { - try { - if (INFO_LOG === true) { logger.write('[INFO] killFloatingObject -> sendToDie -> Entering function.') } - - /* Lets mofigy the targerRadius */ - - pFloatingObject.targetRadius = 0 - - /* Lets transfer the payload to a new payload structure. */ - - let payload = {} - - switch (pFloatingObject.type) { - - case 'Profile Ball': { - if (INFO_LOG === true) { logger.write('[INFO] killFloatingObject -> sendToDie -> Profile Ball -> Entering function.') } - - if (pFloatingObject.payload.profile.visible === false) { return } - - payload.profile = { - position: { - x: pFloatingObject.payload.profile.position.x, - y: pFloatingObject.payload.profile.position.y - }, - visible: pFloatingObject.payload.profile.visible, - botAvatar: pFloatingObject.payload.profile.botAvatar - } - - pFloatingObject.payload = payload - break - } - case 'Note': { - if (INFO_LOG === true) { logger.write('[INFO] killFloatingObject -> sendToDie -> Note -> Entering function.') } - - if (pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].visible === false) { return } - - payload.notes = [] - let note = { - title: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].title, - body: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].body, - date: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].date, - rate: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].rate, - position: { - x: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].position.x, - y: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].position.y - }, - visible: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].visible - } - payload.notes.push(note) - pFloatingObject.payloadNoteIndex = 0 - - pFloatingObject.payload = payload - break - } - case 'Strategy Part': { - if (pFloatingObject.payload.visible === false) { return } - - payload.profile = { - position: { - x: pFloatingObject.payload.position.x, - y: pFloatingObject.payload.position.y - }, - visible: pFloatingObject.payload.visible, - botAvatar: pFloatingObject.payload.botAvatar - } - - pFloatingObject.payload = payload - break - } - default: { - break - } - } - - dyingFloatingObjects.push(pFloatingObject) - - if (INFO_LOG === true) { logger.write('[INFO] killFloatingObject -> sendToDie -> Adding floatingObject to dyingFloatingObjects.') } - if (INFO_LOG === true) { logger.write('[INFO] killFloatingObject -> sendToDie -> dyingFloatingObjects.length = ' + dyingFloatingObjects.length) } - - if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE) } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] killFloatingObject -> err= ' + err.stack) } - if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) } - } - } } catch (err) { if (ERROR_LOG === true) { logger.write('[ERROR] killFloatingObject -> err= ' + err.stack) } - if (callBackFunction !== undefined) { callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE) } } } @@ -408,30 +287,10 @@ function newFloatingLayer () { return // Only one at the time. } } - - drawDyingObjects() } catch (err) { if (ERROR_LOG === true) { logger.write('[ERROR] physics -> makeInvisible -> err= ' + err.stack) } } } - - function drawDyingObjects () { - try { - /* We also draw all the dyingFloatingObjects */ - - for (let i = 0; i < dyingFloatingObjects.length; i++) { - let floatingObject = dyingFloatingObjects[i] - floatingObject.drawBackground() - } - - for (let i = 0; i < dyingFloatingObjects.length; i++) { - let floatingObject = dyingFloatingObjects[dyingFloatingObjects.length - i - 1] - floatingObject.drawForeground() - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] physics -> drawDyingObjects -> err= ' + err.stack) } - } - } } /******************************************/ @@ -551,35 +410,10 @@ function newFloatingLayer () { gravityForce(floatingObject, payload) } - - animateDyingObjects() } catch (err) { if (ERROR_LOG === true) { logger.write('[ERROR] physics -> applyPhysics -> err= ' + err.stack) } } } - - function animateDyingObjects () { - try { - /* We animate some parts of the dying objects */ - - for (let i = 0; i < dyingFloatingObjects.length; i++) { - let floatingObject = dyingFloatingObjects[i] - - if (Math.abs(floatingObject.container.frame.radius - floatingObject.targetRadius) >= 5) { - let speed = Math.random() - - floatingObject.container.frame.radius = floatingObject.container.frame.radius - speed * 3 - } else { - /* Here is when the floatingObjects are definetelly killed. */ - - dyingFloatingObjects.splice(i, 1) // Delete item from array. - break // only one at the time. - } - } - } catch (err) { - if (ERROR_LOG === true) { logger.write('[ERROR] physics -> animateDyingObjects -> err= ' + err.stack) } - } - } } catch (err) { if (ERROR_LOG === true) { logger.write('[ERROR] physics -> err= ' + err.stack) } } diff --git a/FloatingSpace/FloatingObject.js b/FloatingSpace/FloatingObject.js index ccff86ceb..6fcc5236c 100644 --- a/FloatingSpace/FloatingObject.js +++ b/FloatingSpace/FloatingObject.js @@ -7,6 +7,7 @@ function newFloatingObject () { logger.fileName = MODULE_NAME let thisObject = { + container: undefined, positionLocked: false, isOnFocus: false, payload: undefined, // This is a reference to an object controlled by a Plotter. The plotter can change its internal value and we will see them from here. @@ -30,7 +31,7 @@ function newFloatingObject () { updateMass: updateMass, // Function to update the mass when the zoom level changed. updateRadius: updateRadius, // Function to update the radius when the zoom level changed. getContainer: getContainer, - container: undefined, + finalize: finalize, initialize: initialize } @@ -43,8 +44,26 @@ function newFloatingObject () { thisObject.container.frame.position.x = 0 thisObject.container.frame.position.y = 0 + let selfMouseOverEventSubscriptionId + let selfMouseClickEventSubscriptionId + let spaceMouseOverEventSubscriptionId + let spaceFocusAquiredEventSubscriptionId + return thisObject + function finalize () { + thisObject.container.eventHandler.stopListening(selfMouseOverEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) + canvas.floatingSpace.container.eventHandler.stopListening(spaceMouseOverEventSubscriptionId) + canvas.floatingSpace.container.eventHandler.stopListening(spaceFocusAquiredEventSubscriptionId) + + thisObject.container.finalize() + thisObject.container = undefined + thisObject.payload = undefined + thisObject.underlayingObject.finalize() + thisObject.underlayingObject = undefined + } + function initialize (pType, pSubType, floatingLayer) { switch (pType) { @@ -74,12 +93,12 @@ function newFloatingObject () { thisObject.type = pType - thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) - thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + selfMouseOverEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseOver', onMouseOver) + selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) /* To consider that this object lost the focus, we monitor the space for 2 key events */ - canvas.floatingSpace.container.eventHandler.listenToEvent('onMouseOver', mouseOverFlotingSpace) - canvas.floatingSpace.container.eventHandler.listenToEvent('onFocusAquired', someoneAquiredFocus) + spaceMouseOverEventSubscriptionId = canvas.floatingSpace.container.eventHandler.listenToEvent('onMouseOver', mouseOverFlotingSpace) + spaceFocusAquiredEventSubscriptionId = canvas.floatingSpace.container.eventHandler.listenToEvent('onFocusAquired', someoneAquiredFocus) } function getContainer (point) { diff --git a/FloatingSpace/NoteSets.js b/FloatingSpace/NoteSets.js index 50a2f7c3b..e0a5d8093 100644 --- a/FloatingSpace/NoteSets.js +++ b/FloatingSpace/NoteSets.js @@ -124,19 +124,7 @@ function newNoteSets () { Each time we identify a floatingObject that is not at the raw data anymore, we request the floatinglayer to kill it. */ - floatingLayer.killFloatingObject(floatingNote.floatingHandle, onObjectKilled) - - function onObjectKilled (err) { - if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) { - if (ERROR_LOG === true) { logger.write('[ERROR] createNoteSet -> onNotesChanged -> Remove old Notes -> Floating Object Not Found.') } - if (ERROR_LOG === true) { logger.write('[ERROR] createNoteSet -> onNotesChanged -> Remove old Notes -> Floating Object cannot be killed.') } - if (ERROR_LOG === true) { logger.write('[ERROR] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingNote.floatingHandle = ' + floatingNote.floatingHandle) } - return - } - - 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.') } - } + floatingLayer.killFloatingObject(floatingNote.floatingHandle) } else { newFloatingNotes.push(floatingNote) diff --git a/FloatingSpace/StrategyPart.js b/FloatingSpace/StrategyPart.js index cda32802d..d0f0ccd63 100644 --- a/FloatingSpace/StrategyPart.js +++ b/FloatingSpace/StrategyPart.js @@ -7,10 +7,12 @@ function newStrategyPart () { menu: undefined, isOnFocus: false, container: undefined, + payload: undefined, physics: physics, drawBackground: drawBackground, drawForeground: drawForeground, getContainer: getContainer, + finalize: finalize, initialize: initialize } @@ -25,12 +27,31 @@ function newStrategyPart () { let floatingLayer let image let imagePath - let payload + + let selfFocusEventSubscriptionId + let selfNotFocuskEventSubscriptionId + let selfMouseClickEventSubscriptionId return thisObject + function finalize () { + thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfNotFocuskEventSubscriptionId) + thisObject.container.eventHandler.stopListening(selfMouseClickEventSubscriptionId) + + thisObject.container.finalize() + thisObject.container = undefined + thisObject.payload = undefined + thisObject.menu.finalize() + thisObject.menu = undefined + + floatingLayer = undefined + image = undefined + imagePath = undefined + } + function initialize (pFloatingLayer, pType, pPayload) { - payload = pPayload + thisObject.payload = pPayload floatingLayer = pFloatingLayer let menuItemsInitialValues = [] @@ -240,7 +261,7 @@ function newStrategyPart () { } thisObject.menu = newCircularMenu() - thisObject.menu.initialize(menuItemsInitialValues, payload) + thisObject.menu.initialize(menuItemsInitialValues, thisObject.payload) thisObject.menu.container.connectToParent(thisObject.container, false, false, true, true, false, false, true, true) /* Load Part Image */ @@ -255,9 +276,9 @@ function newStrategyPart () { image.src = window.canvasApp.urlPrefix + imagePath } - thisObject.container.eventHandler.listenToEvent('onFocus', onFocus) - thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus) - thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) + selfFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onFocus', onFocus) + selfNotFocuskEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus) + selfMouseClickEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onMouseClick', onMouseClick) } function getContainer (point) { @@ -427,4 +448,3 @@ function newStrategyPart () { } } } - diff --git a/FloatingSpace/StrategyParts.js b/FloatingSpace/StrategyParts.js index 9f08b849a..1f0e31869 100644 --- a/FloatingSpace/StrategyParts.js +++ b/FloatingSpace/StrategyParts.js @@ -19,7 +19,6 @@ function newStrategyParts () { return thisObject function finalize () { - floatingLayer.finalize() floatingLayer = undefined }