Merge pull request #60 from AAMasters/develop

Attaching and Detaching Strategy Parts Implemented
This commit is contained in:
benme authored and GitHub committed 2019-05-23 16:25:35 -03:00
commit 1123b2fa77
10 files changed
+865 -221

No files matched your search

+113 -53
View File
@@ -60,16 +60,15 @@ function newCanvas () {
browserCanvas.removeEventListener('click', onMouseClick, false)
browserCanvas.removeEventListener('mouseout', onMouseOut, false)
/* Mouse wheel events. */
if (browserCanvas.removeEventListener) {
// IE9, Chrome, Safari, Opera
browserCanvas.removeEventListener('mousewheel', onMouseWheel, false)
// Firefox
browserCanvas.removeEventListener('DOMMouseScroll', onMouseWheel, false)
}
// IE 6/7/8
else browserCanvas.detachEvent('onmousewheel', onMouseWheel)
browserCanvas.removeEventListener('mousewheel', onMouseWheel, false)// IE9, Chrome, Safari, Opera
browserCanvas.removeEventListener('DOMMouseScroll', onMouseWheel, false) // Firefox
} else browserCanvas.detachEvent('onmousewheel', onMouseWheel) // IE 6/7/8
browserCanvas.removeEventListener('dragenter', onDragEnter, false)
browserCanvas.removeEventListener('dragleave', onDragLeave, false)
browserCanvas.removeEventListener('dragover', onDragOver, false)
browserCanvas.removeEventListener('drop', onDragDrop, false)
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] finalize -> err = ' + err.stack) }
}
@@ -110,9 +109,6 @@ function newCanvas () {
if (ERROR_LOG === true) { logger.write('[ERROR] initialize -> onCharSpaceInitialized -> err = ' + err.stack) }
}
}
/* Splash Screen */
splashScreen = newSplashScreen()
splashScreen.initialize()
@@ -121,8 +117,6 @@ function newCanvas () {
thisObject.animation = animation
/* Here we add all the functions that will be called during the animation cycle. */
animation.addCallBackFunction('Floating Space Draw', thisObject.floatingSpace.draw)
animation.addCallBackFunction('Floating Space Physics', thisObject.floatingSpace.physics)
animation.addCallBackFunction('Chart Space Background', thisObject.chartSpace.drawBackground)
@@ -144,7 +138,6 @@ function newCanvas () {
function initializeBrowserCanvas () {
try {
browserCanvasContext = browserCanvas.getContext('2d')
// browserCanvasContext.font = 'italic small-caps bold 12px Saira'
browserCanvasContext.font = 'Saira'
viewPort.initialize()
@@ -155,24 +148,23 @@ function newCanvas () {
function addCanvasEvents () {
try {
/* Mouse down and up events to control the drag of the canvas. */
browserCanvas.addEventListener('mousedown', onMouseDown, false)
browserCanvas.addEventListener('mouseup', onMouseUp, false)
browserCanvas.addEventListener('mousemove', onMouseMove, false)
browserCanvas.addEventListener('click', onMouseClick, false)
browserCanvas.addEventListener('mouseout', onMouseOut, false)
/* Mouse wheel events. */
if (browserCanvas.addEventListener) {
// IE9, Chrome, Safari, Opera
browserCanvas.addEventListener('mousewheel', onMouseWheel, false)
// Firefox
browserCanvas.addEventListener('DOMMouseScroll', onMouseWheel, false)
}
// IE 6/7/8
else browserCanvas.attachEvent('onmousewheel', onMouseWheel)
browserCanvas.addEventListener('mousewheel', onMouseWheel, false) // IE9, Chrome, Safari, Opera
browserCanvas.addEventListener('DOMMouseScroll', onMouseWheel, false) // Firefox
} else browserCanvas.attachEvent('onmousewheel', onMouseWheel)// IE 6/7/8
/* Dragging Files Over the Canvas */
browserCanvas.addEventListener('dragenter', onDragEnter, false)
browserCanvas.addEventListener('dragleave', onDragLeave, false)
browserCanvas.addEventListener('dragover', onDragOver, false)
browserCanvas.addEventListener('drop', onDragDrop, false)
// Disables the context menu when you right mouse click the canvas.
browserCanvas.oncontextmenu = function (e) {
@@ -183,6 +175,62 @@ function newCanvas () {
}
}
function onDragEnter (event) {
try {
event.preventDefault()
event.stopPropagation()
thisObject.cockpitSpace.toTop()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onDragEnter -> err = ' + err.stack) }
}
}
function onDragLeave (event) {
try {
event.preventDefault()
event.stopPropagation()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onDragLeave -> err = ' + err.stack) }
}
}
function onDragOver (event) {
try {
event.preventDefault()
event.stopPropagation()
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onDragOver -> err = ' + err.stack) }
}
}
function onDragDrop (event) {
try {
event.preventDefault()
event.stopPropagation()
let files = event.dataTransfer.files
handleFiles(files)
function handleFiles (files) {
([...files]).forEach(loadFileData)
}
function loadFileData (file) {
let reader = new FileReader()
reader.readAsText(file)
reader.onloadend = function () {
let mousePosition = {
x: event.x,
y: event.y
}
thisObject.strategySpace.workspace.spawn(reader.result, mousePosition)
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onDragDrop -> err = ' + err.stack) }
}
}
function onMouseDown (event) {
try {
let point = {
@@ -202,6 +250,7 @@ function newCanvas () {
if (container !== undefined && container.isDraggeable === true) {
containerBeingDragged = container
containerDragStarted = true
containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point)
return
}
@@ -216,6 +265,7 @@ function newCanvas () {
if (container !== undefined && container.isDraggeable === true) {
containerBeingDragged = container
containerDragStarted = true
containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point)
return
}
@@ -226,6 +276,7 @@ function newCanvas () {
if (container !== undefined && container.isDraggeable === true) {
containerBeingDragged = container
containerDragStarted = true
containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point)
return
}
@@ -241,6 +292,7 @@ function newCanvas () {
if (container !== undefined && container.isDraggeable === true && event.button === 2) {
containerBeingDragged = container
containerDragStarted = true
containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point)
return
}
@@ -257,6 +309,7 @@ function newCanvas () {
if (container.isDraggeable === true) {
containerBeingDragged = container
containerDragStarted = true
containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point)
return
} else {
viewPortBeingDragged = true
@@ -270,6 +323,7 @@ function newCanvas () {
containerBeingDragged = container
containerDragStarted = true
floatingObjectDragStarted = true
containerBeingDragged.eventHandler.raiseEvent('onDragStarted', point)
return
}
@@ -367,33 +421,6 @@ function newCanvas () {
deactivateDragging(event)
}
function deactivateDragging (event) {
try {
if (containerDragStarted || viewPortBeingDragged || floatingObjectDragStarted) {
thisObject.eventHandler.raiseEvent('Drag Finished', undefined)
}
if (
containerDragStarted ||
floatingObjectDragStarted ||
viewPortBeingDragged
) {
ignoreNextClick = true
}
/* Turn off all the possible things that can be dragged. */
containerDragStarted = false
floatingObjectDragStarted = false
viewPortBeingDragged = false
containerBeingDragged = undefined
browserCanvas.style.cursor = 'auto'
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] onMouseUp -> err = ' + err.stack) }
}
}
function onMouseMove (event) {
try {
let point = {
@@ -409,6 +436,7 @@ function newCanvas () {
let targetContainer = thisObject.floatingSpace.getContainer(point)
if (targetContainer !== undefined) {
if (targetContainer.id !== containerBeingDragged.id) {
containerBeingDragged.eventHandler.raiseEvent('onDragFinished', point)
containerBeingDragged = undefined
containerDragStarted = false
floatingObjectDragStarted = false
@@ -417,6 +445,7 @@ function newCanvas () {
return
}
} else {
containerBeingDragged.eventHandler.raiseEvent('onDragFinished', point)
containerDragStarted = false
containerBeingDragged = undefined
floatingObjectDragStarted = false
@@ -588,6 +617,36 @@ function newCanvas () {
}
}
function deactivateDragging (event) {
try {
if (containerDragStarted || viewPortBeingDragged || floatingObjectDragStarted) {
thisObject.eventHandler.raiseEvent('Drag Finished', undefined)
}
if (
containerDragStarted ||
floatingObjectDragStarted ||
viewPortBeingDragged
) {
ignoreNextClick = true
}
/* Turn off all the possible things that can be dragged. */
containerDragStarted = false
floatingObjectDragStarted = false
viewPortBeingDragged = false
if (containerBeingDragged !== undefined) {
containerBeingDragged.eventHandler.raiseEvent('onDragFinished', event)
containerBeingDragged = undefined
}
browserCanvas.style.cursor = 'auto'
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] deactivateDragging -> err = ' + err.stack) }
}
}
function checkDrag (event) {
try {
if (containerDragStarted === true || floatingObjectDragStarted === true || viewPortBeingDragged === true) {
@@ -646,3 +705,4 @@ function newCanvas () {
}
}
}
+25 -1
View File
@@ -33,6 +33,8 @@ function newContainer () {
let onFocusParentEvent = false
let onNotFocusParentEvent = false
let onDisplaceParentEvent = false
let onDragStartedParentEvent = false
let onDragFinishedParentEvent = false
let isConnectedToParent = false
@@ -42,6 +44,8 @@ function newContainer () {
let onFocusEventSubscriptionId
let onNotFocusEventSubscriptionId
let onDisplaceEventSubscriptionId
let onDragStartedEventSubscriptionId
let onDragFinishedEventSubscriptionId
return thisObject
@@ -53,6 +57,8 @@ function newContainer () {
thisObject.parentContainer.eventHandler.stopListening(onFocusEventSubscriptionId)
thisObject.parentContainer.eventHandler.stopListening(onNotFocusEventSubscriptionId)
thisObject.parentContainer.eventHandler.stopListening(onDisplaceEventSubscriptionId)
thisObject.parentContainer.eventHandler.stopListening(onDragStartedEventSubscriptionId)
thisObject.parentContainer.eventHandler.stopListening(onDragFinishedEventSubscriptionId)
thisObject.parentContainer = undefined
thisObject.eventHandler.finalize()
@@ -86,7 +92,9 @@ function newContainer () {
onMouseNotOverEvent,
onFocusEvent,
onNotFocusEvent,
onDisplaceEvent
onDisplaceEvent,
onDragStartedEvent,
onDragFinishedEvent
) {
connectedToParentWidth = onWidth
connectedToParentHeight = onHeight
@@ -98,6 +106,8 @@ function newContainer () {
onFocusParentEvent = onFocusEvent
onNotFocusParentEvent = onNotFocusEvent
onDisplaceParentEvent = onDisplaceEvent
onDragStartedParentEvent = onDragStartedEvent
onDragFinishedParentEvent = onDragFinishedEvent
isConnectedToParent = true
@@ -123,6 +133,12 @@ function newContainer () {
if (onDisplaceParentEvent === true) {
onDisplaceEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onDisplace', onDisplace)
}
if (onDragStartedParentEvent === true) {
onDragStartedEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onDragStarted', onDragStarted)
}
if (onDragFinishedParentEvent === true) {
onDragFinishedEventSubscriptionId = thisObject.parentContainer.eventHandler.listenToEvent('onDragFinished', onDragFinished)
}
if (connectedToParentWidth) {
thisObject.frame.width = thisObject.parentContainer.frame.width
@@ -175,6 +191,14 @@ function newContainer () {
thisObject.eventHandler.raiseEvent('onDisplace', event)
}
function onDragStarted (event) {
thisObject.eventHandler.raiseEvent('onDragStarted', event)
}
function onDragFinished (event) {
thisObject.eventHandler.raiseEvent('onDragFinished', event)
}
function isForThisPurpose (purpose) {
if (purpose !== undefined) {
switch (purpose) {
+89 -56
View File
@@ -15,7 +15,6 @@
function newFloatingLayer () {
const MODULE_NAME = 'Floating Layer'
const INFO_LOG = false
const ERROR_LOG = true
const logger = newWebDebugLog()
logger.fileName = MODULE_NAME
@@ -121,8 +120,6 @@ function newFloatingLayer () {
*/
try {
if (INFO_LOG === true) { logger.write('[INFO] getFloatingObject -> Entering function.') }
if (pFloatingObjectHandle !== undefined) {
for (let i = 0; i < invisibleFloatingObjects.length; i++) {
let floatingObject = invisibleFloatingObjects[i]
@@ -397,6 +394,8 @@ function newFloatingLayer () {
targetRepulsionForce(i)
gravityForce(floatingObject, payload)
proximityBetweenFloatingObjects(i)
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] physics -> applyPhysics -> err= ' + err.stack) }
@@ -436,36 +435,36 @@ function newFloatingLayer () {
const coulomb = 0.00001
const minForce = 0.01
var d = Math.sqrt(Math.pow(payload.targetPosition.x - floatingObject.container.frame.position.x, 2) + Math.pow(payload.targetPosition.y - floatingObject.container.frame.position.y, 2)) // ... we calculate the distance ...
let d = Math.sqrt(Math.pow(payload.targetPosition.x - floatingObject.container.frame.position.x, 2) + Math.pow(payload.targetPosition.y - floatingObject.container.frame.position.y, 2)) // ... we calculate the distance ...
var force = coulomb * d * d / floatingObject.currentMass // In this case the mass of the floatingObject affects the gravity force that it receives, that gives priority to target position to bigger floatingObjects.
let force = coulomb * d * d / floatingObject.currentMass // In this case the mass of the floatingObject affects the gravity force that it receives, that gives priority to target position to bigger floatingObjects.
if (force < minForce) { // We need this attraction force to overcome the friction we imposed to the system.
force = minForce
}
var pos1 = {
let pos1 = {
x: floatingObject.container.frame.position.x,
y: floatingObject.container.frame.position.y
}
var pos2 = {
let pos2 = {
x: payload.targetPosition.x,
y: payload.targetPosition.y
}
var posDiff = { // Next we need the vector resulting from the 2 positions.
let posDiff = { // Next we need the vector resulting from the 2 positions.
x: pos2.x - pos1.x,
y: pos2.y - pos1.y
}
if (d !== 0) {
var unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector.
let unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector.
x: posDiff.x / d,
y: posDiff.y / d
}
var forceVector = {
let forceVector = {
x: unitVector.x * force,
y: unitVector.y * force
}
@@ -486,19 +485,19 @@ function newFloatingLayer () {
const coulomb = 2
var floatingObject1 = visibleFloatingObjects[currentFloatingObject]
let floatingObject1 = visibleFloatingObjects[currentFloatingObject]
for (var i = 0; i < visibleFloatingObjects.length; i++) {
for (let i = 0; i < visibleFloatingObjects.length; i++) {
// The force to be applied is considering all other floatingObjects...
if (i !== currentFloatingObject) {
// ... except for the current one.
var floatingObject2 = visibleFloatingObjects[i] // So, for each floatingObject...
let floatingObject2 = visibleFloatingObjects[i] // So, for each floatingObject...
var d = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2)) // ... we calculate the distance ...
let d = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2)) // ... we calculate the distance ...
var force = coulomb * floatingObject2.currentMass / (d * d) // ... and with it the repulsion force.
let force = coulomb * floatingObject2.currentMass / (d * d) // ... and with it the repulsion force.
/* We need to put a hard limit to this force, in order to to eject very little floatingObjects to the infinite and beyond. */
@@ -506,27 +505,27 @@ function newFloatingLayer () {
force = 1
}
var pos1 = {
let pos1 = {
x: floatingObject1.container.frame.position.x,
y: floatingObject1.container.frame.position.y
}
var pos2 = {
let pos2 = {
x: floatingObject2.container.frame.position.x,
y: floatingObject2.container.frame.position.y
}
var posDiff = { // Next we need the vector resulting from the 2 positions.
let posDiff = { // Next we need the vector resulting from the 2 positions.
x: pos2.x - pos1.x,
y: pos2.y - pos1.y
}
var unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector.
let unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector.
x: posDiff.x / d,
y: posDiff.y / d
}
var forceVector = {
let forceVector = {
x: unitVector.x * force,
y: unitVector.y * force
}
@@ -542,18 +541,52 @@ function newFloatingLayer () {
}
}
function proximityBetweenFloatingObjects (currentFloatingObject) {
try {
let floatingObject1 = visibleFloatingObjects[currentFloatingObject]
floatingObject1.nearbyFloatingObjects = []
for (let i = 0; i < visibleFloatingObjects.length; i++) {
if (i !== currentFloatingObject) {
let floatingObject2 = visibleFloatingObjects[i] // So, for each floatingObject...
let d = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2)) // ... we calculate the distance ...
if (floatingObject1.nearbyFloatingObjects.length === 0) {
floatingObject1.nearbyFloatingObjects.push([d, floatingObject2])
} else {
let recordAdded = false
for (let j = 0; j < floatingObject1.nearbyFloatingObjects.length; j++) {
let recordedDistance = floatingObject1.nearbyFloatingObjects[j][0]
if (d < recordedDistance) {
floatingObject1.nearbyFloatingObjects.splice(j, 0, [d, floatingObject2])
recordAdded = true
break
}
}
if (recordAdded === false) {
floatingObject1.nearbyFloatingObjects.push([d, floatingObject2])
}
}
floatingObject1.nearbyFloatingObjects.splice(10, floatingObject1.nearbyFloatingObjects.length)
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] proximityBetweenFloatingObjects -> err= ' + err.stack) }
}
}
function targetRepulsionForce (currentFloatingObject) {
try {
/* We generate a repulsion force between floatingObjects, that prevents them to be collisioning so often. */
const coulomb = 2
var floatingObject1 = visibleFloatingObjects[currentFloatingObject]
let floatingObject1 = visibleFloatingObjects[currentFloatingObject]
for (var i = 0; i < visibleFloatingObjects.length; i++) {
for (let i = 0; i < visibleFloatingObjects.length; i++) {
// The force to be applied is considering all other floatingObjects...
var floatingObject2 = visibleFloatingObjects[i] // So, for each floatingObject...
let floatingObject2 = visibleFloatingObjects[i] // So, for each floatingObject...
let payload = {
position: undefined
@@ -578,9 +611,9 @@ function newFloatingLayer () {
}
}
var d = Math.sqrt(Math.pow(payload.targetPosition.x - floatingObject1.container.frame.position.x, 2) + Math.pow(payload.targetPosition.y - floatingObject1.container.frame.position.y, 2)) // ... we calculate the distance ...
let d = Math.sqrt(Math.pow(payload.targetPosition.x - floatingObject1.container.frame.position.x, 2) + Math.pow(payload.targetPosition.y - floatingObject1.container.frame.position.y, 2)) // ... we calculate the distance ...
var force = coulomb * floatingObject2.currentMass / (d * d) // ... and with it the repulsion force.
let force = coulomb * floatingObject2.currentMass / (d * d) // ... and with it the repulsion force.
/* We need to put a hard limit to this force, in order to to eject very little floatingObjects to the infinite and beyond. */
@@ -588,28 +621,28 @@ function newFloatingLayer () {
force = maxTargetRepulsionForce
}
var pos1 = {
let pos1 = {
x: floatingObject1.container.frame.position.x,
y: floatingObject1.container.frame.position.y
}
var pos2 = {
let pos2 = {
x: payload.targetPosition.x,
y: payload.targetPosition.y
}
var posDiff = { // Next we need the vector resulting from the 2 positions.
let posDiff = { // Next we need the vector resulting from the 2 positions.
x: pos2.x - pos1.x,
y: pos2.y - pos1.y
}
if (d !== 0) {
var unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector.
let unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector.
x: posDiff.x / d,
y: posDiff.y / d
}
var forceVector = {
let forceVector = {
x: unitVector.x * force,
y: unitVector.y * force
}
@@ -647,10 +680,10 @@ function newFloatingLayer () {
try {
/* This function detects weather 2 floatingObjects collide with each other. */
var r1 = floatingObject1.container.frame.radius
var r2 = floatingObject2.container.frame.radius
let r1 = floatingObject1.container.frame.radius
let r2 = floatingObject2.container.frame.radius
var distance = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2))
let distance = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2))
if (distance > (r1 + r2)) {
// No solutions, the circles are too far apart.
@@ -675,26 +708,26 @@ function newFloatingLayer () {
try {
/* This function changes speed and position of floatingObjects that are in collision */
var collisionision_angle = Math.atan2((floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y), (floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x))
let collisionision_angle = Math.atan2((floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y), (floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x))
var speed1 = Math.sqrt(floatingObject1.currentSpeed.x * floatingObject1.currentSpeed.x + floatingObject1.currentSpeed.y * floatingObject1.currentSpeed.y) // Magnitude of Speed Vector for floatingObject 1
var speed2 = Math.sqrt(floatingObject2.currentSpeed.x * floatingObject2.currentSpeed.x + floatingObject2.currentSpeed.y * floatingObject2.currentSpeed.y) // Magnitude of Speed Vector for floatingObject 2
let speed1 = Math.sqrt(floatingObject1.currentSpeed.x * floatingObject1.currentSpeed.x + floatingObject1.currentSpeed.y * floatingObject1.currentSpeed.y) // Magnitude of Speed Vector for floatingObject 1
let speed2 = Math.sqrt(floatingObject2.currentSpeed.x * floatingObject2.currentSpeed.x + floatingObject2.currentSpeed.y * floatingObject2.currentSpeed.y) // Magnitude of Speed Vector for floatingObject 2
var direction_1 = Math.atan2(floatingObject1.currentSpeed.y, floatingObject1.currentSpeed.x)
var direction_2 = Math.atan2(floatingObject2.currentSpeed.y, floatingObject2.currentSpeed.x)
let direction_1 = Math.atan2(floatingObject1.currentSpeed.y, floatingObject1.currentSpeed.x)
let direction_2 = Math.atan2(floatingObject2.currentSpeed.y, floatingObject2.currentSpeed.x)
var new_xspeed_1 = speed1 * Math.cos(direction_1 - collisionision_angle)
var new_yspeed_1 = speed1 * Math.sin(direction_1 - collisionision_angle)
var new_xspeed_2 = speed2 * Math.cos(direction_2 - collisionision_angle)
var new_yspeed_2 = speed2 * Math.sin(direction_2 - collisionision_angle)
let new_xspeed_1 = speed1 * Math.cos(direction_1 - collisionision_angle)
let new_yspeed_1 = speed1 * Math.sin(direction_1 - collisionision_angle)
let new_xspeed_2 = speed2 * Math.cos(direction_2 - collisionision_angle)
let new_yspeed_2 = speed2 * Math.sin(direction_2 - collisionision_angle)
var final_xspeed_1 = ((floatingObject1.currentMass - floatingObject2.currentMass) * new_xspeed_1 + (floatingObject2.currentMass + floatingObject2.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass)
var final_xspeed_2 = ((floatingObject1.currentMass + floatingObject1.currentMass) * new_xspeed_1 + (floatingObject2.currentMass - floatingObject1.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass)
var final_yspeed_1 = new_yspeed_1
var final_yspeed_2 = new_yspeed_2
let final_xspeed_1 = ((floatingObject1.currentMass - floatingObject2.currentMass) * new_xspeed_1 + (floatingObject2.currentMass + floatingObject2.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass)
let final_xspeed_2 = ((floatingObject1.currentMass + floatingObject1.currentMass) * new_xspeed_1 + (floatingObject2.currentMass - floatingObject1.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass)
let final_yspeed_1 = new_yspeed_1
let final_yspeed_2 = new_yspeed_2
var cosAngle = Math.cos(collisionision_angle)
var sinAngle = Math.sin(collisionision_angle)
let cosAngle = Math.cos(collisionision_angle)
let sinAngle = Math.sin(collisionision_angle)
floatingObject1.currentSpeed.x = cosAngle * final_xspeed_1 - sinAngle * final_yspeed_1
floatingObject1.currentSpeed.y = sinAngle * final_xspeed_1 + cosAngle * final_yspeed_1
@@ -702,36 +735,36 @@ function newFloatingLayer () {
floatingObject2.currentSpeed.x = cosAngle * final_xspeed_2 - sinAngle * final_yspeed_2
floatingObject2.currentSpeed.y = sinAngle * final_xspeed_2 + cosAngle * final_yspeed_2
var pos1 = {
let pos1 = {
x: floatingObject1.container.frame.position.x,
y: floatingObject1.container.frame.position.y
}
var pos2 = {
let pos2 = {
x: floatingObject2.container.frame.position.x,
y: floatingObject2.container.frame.position.y
}
// get the mtd
var posDiff = {
let posDiff = {
x: pos1.x - pos2.x,
y: pos1.y - pos2.y
}
var d = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2))
let d = Math.sqrt(Math.pow(floatingObject2.container.frame.position.x - floatingObject1.container.frame.position.x, 2) + Math.pow(floatingObject2.container.frame.position.y - floatingObject1.container.frame.position.y, 2))
// minimum translation distance to push floatingObjects apart after intersecting
var scalar = (((floatingObject1.container.frame.radius + floatingObject2.container.frame.radius) - d) / d)
let scalar = (((floatingObject1.container.frame.radius + floatingObject2.container.frame.radius) - d) / d)
var minTD = {
let minTD = {
x: posDiff.x * scalar,
y: posDiff.y * scalar
}
// resolve intersection --
// computing inverse mass quantities
var im1 = 1 / floatingObject1.currentMass
var im2 = 1 / floatingObject2.currentMass
let im1 = 1 / floatingObject1.currentMass
let im2 = 1 / floatingObject2.currentMass
// push-pull them apart based off their mass
+2
View File
@@ -20,6 +20,7 @@ function newFloatingObject () {
rawRadius: 0, // This is the radius of this floating object without zoom.
targetRadius: 0, // This is the target radius of the floating object with zoom applied. It should be animated until reaching this value.
isPinned: false,
nearbyFloatingObjects: [],
pinToggle: pinToggle,
physics: physics,
initializeMass: initializeMass,
@@ -65,6 +66,7 @@ function newFloatingObject () {
thisObject.container = undefined
thisObject.payload = undefined
thisObject.fitFunction = undefined
thisObject.nearbyFloatingObjects = undefined
}
function initialize (type, payload) {
+236 -32
View File
@@ -17,6 +17,8 @@ function newStrategyPart () {
codeEditor: undefined,
partTitle: undefined,
isExecuting: undefined,
getReadyToAttach: getReadyToAttach,
showAvailabilityToAttach: showAvailabilityToAttach,
highlight: highlight,
unHighlight: unHighlight,
physics: physics,
@@ -43,16 +45,34 @@ function newStrategyPart () {
let selfFocusEventSubscriptionId
let selfNotFocuskEventSubscriptionId
let selfDisplaceEventSubscriptionId
let selfDragStartedEventSubscriptionId
let selfDragFinishedEventSubscriptionId
let isHighlighted
let highlightCounter = 0
let previousDistance
let readyToAttachDisplayCounter = 5
let readyToAttachDisplayIncrement = 0.1
let readyToAttachCounter = 0
let isReadyToAttach
let availableToAttachCounter = 0
let isAvailableToAttach
let isAttaching = false
let isDragging = false
let attachToNode
return thisObject
function finalize () {
thisObject.container.eventHandler.stopListening(selfFocusEventSubscriptionId)
thisObject.container.eventHandler.stopListening(selfNotFocuskEventSubscriptionId)
thisObject.container.eventHandler.stopListening(selfDisplaceEventSubscriptionId)
thisObject.container.eventHandler.stopListening(selfDragStartedEventSubscriptionId)
thisObject.container.eventHandler.stopListening(selfDragFinishedEventSubscriptionId)
thisObject.container.finalize()
thisObject.container = undefined
@@ -70,6 +90,7 @@ function newStrategyPart () {
}
icon = undefined
attachToNode = undefined
}
function initialize (payload, menuItemsInitialValues) {
@@ -95,22 +116,26 @@ function newStrategyPart () {
selfFocusEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onFocus', onFocus)
selfNotFocuskEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onNotFocus', onNotFocus)
selfDisplaceEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDisplace', onDisplace)
selfDragStartedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDragStarted', onDragStarted)
selfDragFinishedEventSubscriptionId = thisObject.container.eventHandler.listenToEvent('onDragFinished', onDragFinished)
}
function getContainer (point) {
let container
if (thisObject.codeEditor !== undefined) {
container = thisObject.codeEditor.getContainer(point)
if (isDragging === false && thisObject.isOnFocus === true) {
if (thisObject.codeEditor !== undefined) {
container = thisObject.codeEditor.getContainer(point)
if (container !== undefined) { return container }
}
container = thisObject.partTitle.getContainer(point)
if (container !== undefined) { return container }
container = thisObject.menu.getContainer(point)
if (container !== undefined) { return container }
}
container = thisObject.partTitle.getContainer(point)
if (container !== undefined) { return container }
container = thisObject.menu.getContainer(point)
if (container !== undefined) { return container }
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
return thisObject.container
} else {
@@ -127,8 +152,8 @@ function newStrategyPart () {
}
if (thisObject.payload.chainParent === undefined) {
thisObject.payload.targetPosition.x = canvas.floatingSpace.container.frame.width / 2,
thisObject.payload.targetPosition.y = canvas.floatingSpace.container.frame.height / 2
thisObject.payload.targetPosition.x = thisObject.payload.position.x,
thisObject.payload.targetPosition.y = thisObject.payload.position.y
} else {
thisObject.payload.targetPosition.x = thisObject.payload.chainParent.payload.position.x
thisObject.payload.targetPosition.y = thisObject.payload.chainParent.payload.position.y
@@ -136,6 +161,117 @@ function newStrategyPart () {
iconPhysics()
highlightPhisycs()
detachingPhysics()
attachingPhysics()
}
function attachingPhysics () {
attacchingCounters()
if (thisObject.isOnFocus !== true) { return }
if (isDragging !== true) { return }
if (thisObject.payload.chainParent !== undefined) { return }
let nearbyFloatingObjects = thisObject.payload.floatingObject.nearbyFloatingObjects
let compatibleType
let compatibleSubType
switch (thisObject.payload.node.type) {
case 'Strategy':
compatibleType = 'Trading System'
compatibleSubType = undefined
break
case 'Phase':
compatibleType = 'Stop' + '.' + 'Take Profit' + '.' + 'Phase'
compatibleSubType = undefined
break
case 'Situation':
compatibleType = 'Phase' + '.' + 'Take Position Event' + '.' + 'Trigger On Event' + '.' + 'Trigger Off Event'
compatibleSubType = undefined
break
case 'Condition':
compatibleType = 'Situation'
compatibleSubType = undefined
break
default:
return
}
let foundCompatible = false
attachToNode = undefined
isAttaching = false
for (let i = 0; i < nearbyFloatingObjects.length; i++) {
let nearby = nearbyFloatingObjects[i]
let distance = nearby[0]
let floatingObject = nearby[1]
let nearbyNode = floatingObject.payload.node
if (compatibleType.indexOf(nearbyNode.type) >= 0) {
if (thisObject.payload.node.type === 'Phase' && nearbyNode.type === 'Phase' && nearbyNode.payload.parentNode === undefined) { continue }
if (foundCompatible === false) {
if (distance < thisObject.container.frame.radius * 1.5 + floatingObject.container.frame.radius * 1.5) {
nearbyNode.payload.uiObject.getReadyToAttach()
isAttaching = true
attachToNode = nearbyNode
foundCompatible = true
}
}
nearbyNode.payload.uiObject.showAvailabilityToAttach()
}
}
}
function attacchingCounters () {
if (readyToAttachDisplayCounter > 15) {
readyToAttachDisplayIncrement = -0.25
}
if (readyToAttachDisplayCounter < 5) {
readyToAttachDisplayIncrement = 0.25
}
readyToAttachDisplayCounter = readyToAttachDisplayCounter + readyToAttachDisplayIncrement
readyToAttachCounter--
if (readyToAttachCounter <= 0) {
readyToAttachCounter = 0
isReadyToAttach = false
} else {
isReadyToAttach = true
}
availableToAttachCounter--
if (availableToAttachCounter <= 0) {
availableToAttachCounter = 0
isAvailableToAttach = false
} else {
isAvailableToAttach = true
}
}
function getReadyToAttach () {
readyToAttachCounter = 10
}
function showAvailabilityToAttach () {
availableToAttachCounter = 10
}
function detachingPhysics () {
if (isDragging !== true) { return }
let distanceToChainParent = Math.sqrt(Math.pow(thisObject.payload.position.x - thisObject.payload.targetPosition.x, 2) + Math.pow(thisObject.payload.position.y - thisObject.payload.targetPosition.y, 2))
let ratio = distanceToChainParent / previousDistance
previousDistance = distanceToChainParent
if (thisObject.isOnFocus !== true) { return }
if (thisObject.payload.chainParent === undefined) { return }
if (thisObject.payload.parentNode === undefined) { return }
let THRESHOLD = 1.15
if (previousDistance !== undefined) {
if (ratio > THRESHOLD) {
canvas.strategySpace.workspace.detachNode(thisObject.payload.node)
}
}
}
function highlightPhisycs () {
@@ -176,10 +312,28 @@ function newStrategyPart () {
thisObject.partTitle.exitEditMode()
}
function onDragStarted (event) {
thisObject.partTitle.exitEditMode()
if (thisObject.codeEditor !== undefined) {
thisObject.codeEditor.deactivate()
}
isDragging = true
}
function onDragFinished (event) {
if (isAttaching === true) {
canvas.strategySpace.workspace.attachNode(thisObject.payload.node, attachToNode)
}
isDragging = false
}
function drawBackground () {
if (thisObject.isOnFocus === false) {
drawConnectingLine()
thisObject.menu.drawBackground()
if (isDragging === false && thisObject.isOnFocus === true) {
thisObject.menu.drawBackground()
}
}
}
@@ -193,7 +347,9 @@ function newStrategyPart () {
function drawForeground () {
if (thisObject.isOnFocus === false) {
drawBodyAndPicture()
thisObject.menu.drawForeground()
if (isDragging === false) {
thisObject.menu.drawForeground()
}
}
}
@@ -212,13 +368,17 @@ function newStrategyPart () {
if (thisObject.codeEditor !== undefined) {
if (thisObject.codeEditor.visible === false) {
drawBodyAndPicture()
thisObject.menu.drawBackground()
thisObject.menu.drawForeground()
if (isDragging === false) {
thisObject.menu.drawBackground()
thisObject.menu.drawForeground()
}
}
} else {
drawBodyAndPicture()
thisObject.menu.drawBackground()
thisObject.menu.drawForeground()
if (isDragging === false) {
thisObject.menu.drawBackground()
thisObject.menu.drawForeground()
}
}
}
}
@@ -307,35 +467,50 @@ function newStrategyPart () {
switch (thisObject.payload.node.type) {
case 'Phase': {
let parent = thisObject.payload.parentNode
for (let i = 0; i < parent.phases.length; i++) {
let phase = parent.phases[i]
if (phase.id === thisObject.payload.node.id) {
label = label + ' #' + (i + 1)
return label
if (parent !== undefined) {
for (let i = 0; i < parent.phases.length; i++) {
let phase = parent.phases[i]
if (phase.id === thisObject.payload.node.id) {
label = label + ' #' + (i + 1)
return label
}
}
} else {
return label
}
break
}
case 'Situation': {
let parent = thisObject.payload.parentNode
for (let i = 0; i < parent.situations.length; i++) {
let situation = parent.situations[i]
if (situation.id === thisObject.payload.node.id) {
label = label + ' #' + (i + 1)
return label
if (parent !== undefined) {
for (let i = 0; i < parent.situations.length; i++) {
let situation = parent.situations[i]
if (situation.id === thisObject.payload.node.id) {
label = label + ' #' + (i + 1)
return label
}
}
} else {
return label
}
break
}
case 'Condition': {
let parent = thisObject.payload.parentNode
for (let i = 0; i < parent.conditions.length; i++) {
let condition = parent.conditions[i]
if (condition.id === thisObject.payload.node.id) {
label = label + ' #' + (i + 1)
return label
if (parent !== undefined) {
for (let i = 0; i < parent.conditions.length; i++) {
let condition = parent.conditions[i]
if (condition.id === thisObject.payload.node.id) {
label = label + ' #' + (i + 1)
return label
}
}
} else {
return label
}
break
}
default: {
@@ -395,6 +570,36 @@ function newStrategyPart () {
browserCanvasContext.setLineDash([4, 20])
browserCanvasContext.stroke()
}
if (isReadyToAttach === true) {
VISIBLE_RADIUS = thisObject.container.frame.radius * 2 + readyToAttachDisplayCounter * 2
let OPACITY = readyToAttachCounter / 10
browserCanvasContext.beginPath()
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TITANIUM_YELLOW + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = 10
browserCanvasContext.setLineDash([readyToAttachDisplayCounter, readyToAttachDisplayCounter * 2])
browserCanvasContext.stroke()
}
if (isAvailableToAttach === true && isReadyToAttach === false) {
VISIBLE_RADIUS = thisObject.container.frame.radius * 1.5
let OPACITY = availableToAttachCounter / 10
browserCanvasContext.beginPath()
browserCanvasContext.arc(visiblePosition.x, visiblePosition.y, VISIBLE_RADIUS, 0, Math.PI * 2, true)
browserCanvasContext.closePath()
browserCanvasContext.strokeStyle = 'rgba(' + UI_COLOR.TURQUOISE + ', ' + OPACITY + ')'
browserCanvasContext.lineWidth = 10
browserCanvasContext.setLineDash([8, 20])
browserCanvasContext.stroke()
}
}
/* Image */
@@ -428,4 +633,3 @@ function newStrategyPart () {
}
}
}
+7 -7
View File
@@ -41,7 +41,7 @@ function newStrategyPartConstructor () {
strategyPart.isVisibleFunction = canvas.floatingSpace.isThisPointVisible
let menuItemsInitialValues = getMenuItemsInitialValues(strategyPart, floatingObject, payload)
strategyPart.initialize(payload, menuItemsInitialValues)
strategyPart.container.connectToParent(floatingObject.container, false, false, true, true, false, false, true, true, true)
strategyPart.container.connectToParent(floatingObject.container, false, false, true, true, false, false, true, true, true, true, true)
payload.uiObject = strategyPart
setFloatingObjectBasicProperties(floatingObject, payload)
@@ -154,7 +154,7 @@ function newStrategyPartConstructor () {
}]
break
}
case 'Strategy Entry Event': {
case 'Trigger On Event': {
menuItemsInitialValues = [
{
action: 'Pin / Unpin',
@@ -196,7 +196,7 @@ function newStrategyPartConstructor () {
}]
break
}
case 'Strategy Exit Event': {
case 'Trigger Off Event': {
menuItemsInitialValues = [
{
action: 'Pin / Unpin',
@@ -238,7 +238,7 @@ function newStrategyPartConstructor () {
}]
break
}
case 'Trade Entry Event': {
case 'Take Position Event': {
menuItemsInitialValues = [
{
action: 'Pin / Unpin',
@@ -569,15 +569,15 @@ function newStrategyPartConstructor () {
level_1()
break
}
case 'Strategy Entry Event': {
case 'Trigger On Event': {
level_2()
break
}
case 'Strategy Exit Event': {
case 'Trigger Off Event': {
level_2()
break
}
case 'Trade Entry Event': {
case 'Take Position Event': {
level_2()
break
}
+6 -4
View File
@@ -55,13 +55,13 @@ function newStrategyPartTitle () {
thisObject.allwaysVisible = true
break
}
case 'Strategy Entry Event': {
case 'Trigger On Event': {
break
}
case 'Strategy Exit Event': {
case 'Trigger Off Event': {
break
}
case 'Trade Entry Event': {
case 'Take Position Event': {
break
}
case 'Stop': {
@@ -110,6 +110,7 @@ function newStrategyPartTitle () {
}
function physics () {
if (thisObject.payload.title === undefined) { return }
let title = trimTitle(thisObject.payload.title)
const FRAME_HEIGHT = 25
@@ -252,7 +253,8 @@ function newStrategyPartTitle () {
}
function trimTitle (title) {
const MAX_LABEL_LENGTH = 15
if (title === undefined) { return }
const MAX_LABEL_LENGTH = 35
if (title.length > MAX_LABEL_LENGTH) {
title = title.substring(0, MAX_LABEL_LENGTH) + '...'
}
+10
View File
@@ -8,6 +8,8 @@
assetBalances: undefined,
restartSimulation: undefined,
fullscreen: undefined,
toTop: toTop,
toBottom: toBottom,
draw: draw,
physics: physics,
getContainer: getContainer,
@@ -76,6 +78,14 @@
thisObject.container.frame.height = COCKPIT_SPACE_HEIGHT
}
function toTop () {
thisObject.container.frame.position.y = 0
}
function toBottom () {
thisObject.container.frame.position.y = browserCanvas.height - COCKPIT_SPACE_HEIGHT
}
function physics () {
thisObjectPhysics()
childrenPhysics()
+3 -4
View File
@@ -46,9 +46,9 @@ function newStrategySpace () {
const relationshipArray = [
['Trading System', 'analysis'],
['Strategy', 'quality'],
['Strategy Entry Event', 'startup'],
['Strategy Exit Event', 'support'],
['Trade Entry Event', 'compass'],
['Trigger On Event', 'startup'],
['Trigger Off Event', 'support'],
['Take Position Event', 'compass'],
['Stop', 'pixel'],
['Take Profit', 'competition'],
['Phase', 'placeholder'],
@@ -180,4 +180,3 @@ function newStrategySpace () {
}
}
}
+374 -64
View File
@@ -5,6 +5,9 @@ function newWorkspace () {
let thisObject = {
tradingSystem: undefined,
container: undefined,
spawn: spawn,
detachNode: detachNode,
attachNode: attachNode,
getContainer: getContainer,
initialize: initialize,
finalize: finalize
@@ -22,10 +25,14 @@ function newWorkspace () {
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
}
return thisObject
function finalize () {
destroyStrategyParts()
thisObject.tradingSystem = undefined
thisObject.container.finalize()
thisObject.container = undefined
@@ -43,12 +50,284 @@ function newWorkspace () {
}
function spawn (nodeText, point) {
point = canvas.floatingSpace.container.frameThisPoint(point)
spawnPosition.x = point.x
spawnPosition.y = point.y
let dirtyNode = JSON.parse(nodeText)
let rootNode = getProtocolNode(dirtyNode)
createPartFromNode(rootNode, undefined, undefined)
}
function createPartFromNode (node, parentNode, chainParent) {
switch (node.type) {
case 'Condition':
{
let condition = node
createPart('Condition', condition.name, condition, parentNode, chainParent, 'Condition')
return
}
case 'Situation': {
let situation = node
createPart('Situation', situation.name, situation, parentNode, chainParent, 'Situation')
for (let m = 0; m < node.conditions.length; m++) {
let condition = node.conditions[m]
createPartFromNode(condition, situation, situation)
}
return
}
case 'Phase': {
let phase = node
createPart('Phase', phase.name, phase, parentNode, chainParent, phase.subType)
for (let m = 0; m < node.situations.length; m++) {
let situation = node.situations[m]
createPartFromNode(situation, phase, phase)
}
return
}
case 'Stop': {
let lastPhase
let stop = node
createPart('Stop', stop.name, stop, parentNode, chainParent, 'Stop')
for (let m = 0; m < node.phases.length; m++) {
let phase = node.phases[m]
let thisChainParent
if (m === 0) {
thisChainParent = node
} else {
thisChainParent = lastPhase
}
lastPhase = phase
createPartFromNode(phase, stop, thisChainParent)
}
return
}
case 'Take Profit': {
let lastPhase
let takeProfit = node
createPart('Take Profit', takeProfit.name, takeProfit, parentNode, chainParent, 'Take Profit')
for (let m = 0; m < node.phases.length; m++) {
let phase = node.phases[m]
let thisChainParent
if (m === 0) {
thisChainParent = node
} else {
thisChainParent = lastPhase
}
lastPhase = phase
createPartFromNode(phase, takeProfit, thisChainParent)
}
return
}
case 'Take Position Event': {
let event = node
createPart('Take Position Event', event.name, event, parentNode, chainParent, 'Take Position Event')
for (let m = 0; m < node.situations.length; m++) {
let situation = node.situations[m]
createPartFromNode(situation, event, event)
}
return
}
case 'Trigger On Event': {
let event = node
createPart('Trigger On Event', event.name, event, parentNode, chainParent, 'Trigger On Event')
for (let m = 0; m < node.situations.length; m++) {
let situation = node.situations[m]
createPartFromNode(situation, event, event)
}
return
}
case 'Trigger Off Event': {
let event = node
createPart('Trigger Off Event', event.name, event, parentNode, chainParent, 'Trigger Off Event')
for (let m = 0; m < node.situations.length; m++) {
let situation = node.situations[m]
createPartFromNode(situation, event, event)
}
return
}
case 'Strategy': {
let strategy = node
createPart('Strategy', strategy.name, strategy, parentNode, chainParent, 'Strategy')
createPartFromNode(node.entryPoint, strategy, strategy)
createPartFromNode(node.exitPoint, strategy, strategy)
createPartFromNode(node.sellPoint, strategy, strategy)
createPartFromNode(node.stopLoss, strategy, strategy)
createPartFromNode(node.buyOrder, strategy, strategy)
return
}
case 'Trading System': {
let tradingSystem = node
createPart('Trading System', tradingSystem.name, tradingSystem, parentNode, chainParent, 'Trading System')
for (let m = 0; m < node.strategies.length; m++) {
let strategy = node.strategies[m]
createPartFromNode(strategy, tradingSystem, tradingSystem)
}
return
}
}
}
function detachNode (node) {
switch (node.type) {
case 'Trading System': {
return
}
case 'Strategy': {
let payload = node.payload
for (let i = 0; i < payload.parentNode.strategies.length; i++) {
let strategy = payload.parentNode.strategies[i]
if (strategy.id === node.id) {
payload.parentNode.strategies.splice(i, 1)
}
payload.parentNode = undefined
payload.chainParent = undefined
}
}
break
case 'Trigger On Event': {
return
}
break
case 'Trigger Off Event': {
return
}
break
case 'Take Position Event': {
return
}
break
case 'Stop': {
return
}
break
case 'Take Profit': {
return
}
break
case 'Condition': {
let payload = node.payload
for (let i = 0; i < payload.parentNode.conditions.length; i++) {
let condition = payload.parentNode.conditions[i]
if (condition.id === node.id) {
payload.parentNode.conditions.splice(i, 1)
}
}
node.payload.chainParent = undefined
node.payload.parentNode = undefined
}
break
case 'Situation': {
let payload = node.payload
for (let i = 0; i < payload.parentNode.situations.length; i++) {
let situation = payload.parentNode.situations[i]
if (situation.id === node.id) {
payload.parentNode.situations.splice(i, 1)
}
}
node.payload.chainParent = undefined
node.payload.parentNode = undefined
}
break
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)
payload.parentNode = undefined
payload.chainParent = undefined
return
}
}
}
}
}
function attachNode (node, attachToNode) {
switch (node.type) {
case 'Strategy': {
node.payload.parentNode = attachToNode
node.payload.chainParent = attachToNode
node.payload.parentNode.strategies.push(node)
}
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)
}
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)
}
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)
} 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)
return
}
}
}
}
}
}
break
case 'Situation': {
node.payload.parentNode = attachToNode
node.payload.chainParent = attachToNode
node.payload.parentNode.situations.push(node)
}
break
case 'Condition': {
node.payload.parentNode = attachToNode
node.payload.chainParent = attachToNode
node.payload.parentNode.conditions.push(node)
}
break
}
}
function createPart (partType, name, node, parentNode, chainParent, title) {
let payload = {}
if (chainParent === undefined) {
payload.targetPosition = {
x: canvas.floatingSpace.container.frame.width / 2,
y: canvas.floatingSpace.container.frame.height / 2
x: spawnPosition.x,
y: spawnPosition.y
}
} else {
payload.targetPosition = {
@@ -92,10 +371,10 @@ function newWorkspace () {
let strategy = tradingSystem.strategies[m]
createPart('Strategy', strategy.name, strategy, tradingSystem, tradingSystem)
createPart('Strategy Entry Event', '', strategy.entryPoint, strategy, strategy)
createPart('Trigger On Event', '', strategy.entryPoint, strategy, strategy)
for (let k = 0; k < strategy.entryPoint.situations.length; k++) {
let situation = strategy.entryPoint.situations[k]
createPart('Situation', situation.name, situation, strategy.entryPoint, strategy.entryPoint, 'Strategy Entry' + ' ' + 'Situation')
createPart('Situation', situation.name, situation, strategy.entryPoint, strategy.entryPoint, 'Trigger On' + ' ' + 'Situation')
for (let m = 0; m < situation.conditions.length; m++) {
let condition = situation.conditions[m]
@@ -103,10 +382,10 @@ function newWorkspace () {
}
}
createPart('Strategy Exit Event', '', strategy.exitPoint, strategy, strategy)
createPart('Trigger Off Event', '', strategy.exitPoint, strategy, strategy)
for (let k = 0; k < strategy.exitPoint.situations.length; k++) {
let situation = strategy.exitPoint.situations[k]
createPart('Situation', situation.name, situation, strategy.exitPoint, strategy.exitPoint, 'Strategy Exit' + ' ' + 'Situation')
createPart('Situation', situation.name, situation, strategy.exitPoint, strategy.exitPoint, 'Trigger Off' + ' ' + 'Situation')
for (let m = 0; m < situation.conditions.length; m++) {
let condition = situation.conditions[m]
@@ -114,10 +393,10 @@ function newWorkspace () {
}
}
createPart('Trade Entry Event', '', strategy.sellPoint, strategy, strategy)
createPart('Take Position Event', '', strategy.sellPoint, strategy, strategy)
for (let k = 0; k < strategy.sellPoint.situations.length; k++) {
let situation = strategy.sellPoint.situations[k]
createPart('Situation', situation.name, situation, strategy.sellPoint, strategy.sellPoint, 'Trade Entry' + ' ' + 'Situation')
createPart('Situation', situation.name, situation, strategy.sellPoint, strategy.sellPoint, 'Take Position' + ' ' + 'Situation')
for (let m = 0; m < situation.conditions.length; m++) {
let condition = situation.conditions[m]
@@ -174,10 +453,6 @@ function newWorkspace () {
}
}
function destroyStrategyParts () {
}
async function onMenuItemClick (payload, action) {
switch (action) {
case 'Save Trading System':
@@ -230,9 +505,9 @@ function newWorkspace () {
strategyParent.strategies.push(strategy)
createPart('Strategy', strategy.name, strategy, strategyParent, strategyParent, 'Strategy')
createPart('Strategy Entry Event', '', strategy.entryPoint, strategy, strategy)
createPart('Strategy Exit Event', '', strategy.exitPoint, strategy, strategy)
createPart('Trade Entry Event', '', strategy.sellPoint, strategy, strategy)
createPart('Trigger On Event', '', strategy.entryPoint, strategy, strategy)
createPart('Trigger Off Event', '', strategy.exitPoint, strategy, strategy)
createPart('Take Position Event', '', strategy.sellPoint, strategy, strategy)
createPart('Stop', '', strategy.stopLoss, strategy, strategy)
createPart('Take Profit', '', strategy.buyOrder, strategy, strategy)
}
@@ -303,19 +578,29 @@ function newWorkspace () {
function deleteStrategy (node) {
let payload = node.payload
for (let j = 0; j < payload.parentNode.strategies.length; j++) {
let strategy = payload.parentNode.strategies[j]
if (strategy.id === node.id) {
deleteEvent(strategy.entryPoint)
deleteEvent(strategy.exitPoint)
deleteEvent(strategy.sellPoint)
deleteManagedItem(strategy.stopLoss)
deleteManagedItem(strategy.buyOrder)
destroyPart(strategy)
payload.parentNode.strategies.splice(j, 1)
cleanNode(strategy)
return
if (payload.parentNode !== undefined) {
for (let j = 0; j < payload.parentNode.strategies.length; j++) {
let strategy = payload.parentNode.strategies[j]
if (strategy.id === node.id) {
deleteEvent(strategy.entryPoint)
deleteEvent(strategy.exitPoint)
deleteEvent(strategy.sellPoint)
deleteManagedItem(strategy.stopLoss)
deleteManagedItem(strategy.buyOrder)
payload.parentNode.strategies.splice(j, 1)
destroyPart(strategy)
cleanNode(strategy)
return
}
}
} else {
deleteEvent(node.entryPoint)
deleteEvent(node.exitPoint)
deleteEvent(node.sellPoint)
deleteManagedItem(node.stopLoss)
deleteManagedItem(node.buyOrder)
destroyPart(node)
cleanNode(node)
}
}
@@ -337,55 +622,80 @@ function newWorkspace () {
function deletePhase (node) {
let payload = node.payload
for (let k = 0; k < payload.parentNode.phases.length; k++) {
let phase = payload.parentNode.phases[k]
if (phase.id === node.id) {
while (phase.situations.length > 0) {
let situation = phase.situations[0]
deleteSituation(situation)
}
phase.situations = []
if (payload.parentNode !== undefined) {
for (let k = 0; k < payload.parentNode.phases.length; k++) {
let phase = payload.parentNode.phases[k]
if (phase.id === node.id) {
while (phase.situations.length > 0) {
let situation = phase.situations[0]
deleteSituation(situation)
}
phase.situations = []
/* Before deleting this phase we need to give its chainParent to the next phase down the chain */
if (k < payload.parentNode.phases.length - 1) {
payload.parentNode.phases[k + 1].payload.chainParent = payload.chainParent
}
if (k < payload.parentNode.phases.length - 1) {
payload.parentNode.phases[k + 1].payload.chainParent = payload.chainParent
}
/* Continue destroying this phase */
destroyPart(phase)
payload.parentNode.phases.splice(k, 1)
cleanNode(phase)
return
payload.parentNode.phases.splice(k, 1)
destroyPart(phase)
cleanNode(phase)
return
}
}
} else {
while (node.situations.length > 0) {
let situation = node.situations[0]
deleteSituation(situation)
}
node.situations = []
destroyPart(node)
cleanNode(node)
}
}
function deleteSituation (node) {
let payload = node.payload
for (let j = 0; j < payload.parentNode.situations.length; j++) {
let situation = payload.parentNode.situations[j]
if (situation.id === node.id) {
while (situation.conditions.length > 0) {
let condition = situation.conditions[0]
deleteCondition(condition)
if (payload.parentNode !== undefined) {
for (let j = 0; j < payload.parentNode.situations.length; j++) {
let situation = payload.parentNode.situations[j]
if (situation.id === node.id) {
while (situation.conditions.length > 0) {
let condition = situation.conditions[0]
deleteCondition(condition)
}
situation.conditions = []
payload.parentNode.situations.splice(j, 1)
destroyPart(situation)
cleanNode(situation)
return
}
situation.conditions = []
destroyPart(situation)
payload.parentNode.situations.splice(j, 1)
cleanNode(situation)
return
}
} else {
while (node.conditions.length > 0) {
let condition = node.conditions[0]
deleteCondition(condition)
}
node.conditions = []
destroyPart(node)
cleanNode(node)
}
}
function deleteCondition (node) {
let payload = node.payload
for (let i = 0; i < payload.parentNode.conditions.length; i++) {
let condition = payload.parentNode.conditions[i]
if (condition.id === node.id) {
destroyPart(node)
payload.parentNode.conditions.splice(i, 1)
cleanNode(condition)
return
if (payload.parentNode !== undefined) {
for (let i = 0; i < payload.parentNode.conditions.length; i++) {
let condition = payload.parentNode.conditions[i]
if (condition.id === node.id) {
payload.parentNode.conditions.splice(i, 1)
destroyPart(node)
cleanNode(condition)
return
}
}
} else {
destroyPart(node)
cleanNode(node)
}
}
@@ -486,7 +796,7 @@ function newWorkspace () {
return takeProfit
break
}
case 'Trade Entry Event': {
case 'Take Position Event': {
let event = {
type: node.type,
subType: node.subType,
@@ -501,7 +811,7 @@ function newWorkspace () {
return event
break
}
case 'Strategy Entry Event': {
case 'Trigger On Event': {
let event = {
type: node.type,
subType: node.subType,
@@ -516,7 +826,7 @@ function newWorkspace () {
return event
break
}
case 'Strategy Exit Event': {
case 'Trigger Off Event': {
let event = {
type: node.type,
subType: node.subType,