diff --git a/README.md b/README.md index 14bc3ffc947acf7ef69e1347441a05b18dc86139..61dfc673e497453fe5f06ac238526e049a8c371f 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,34 @@ This project serves the developement environment / api we use to write and repre ## For MW + - GIFS + - load a program + - drag around + - zoom in and out + - add a module + - hook events up + - rm events + - rm modules + - change settings + - *don't forget* + - onload, load state... - when hooking back to server, server.emitChange(key) ... from writeStateObject - - does state copy over successfully from loaded mod? + + - this spiral + - entire programs read into UI + - hook sever-and-back + - for event hookup + - for module add + - for state push-down + - re-hook state push-down + - can req and add to program new modules + - can req to load new program + - can req to save this program + + - next spiral + - programs come in chunk-wise and get placed + - programs are modules are heirarchical - fundament - the basic unit is a .js file having inputs, outputs, and state objects diff --git a/client/client.js b/client/client.js index 4252f5c7f40e7ba94112bcfc2ae60e2ba921eab6..35db7fc2bc104f45e1eb193ad1ae89a9741ac706 100644 --- a/client/client.js +++ b/client/client.js @@ -1,17 +1,85 @@ -// client side js for atkapi reconf +// +// +// new node controller / VIEW +// +// client.js +// +// +// Jake Read at the Center for Bits and Atoms +// (c) Massachusetts Institute of Technology 2018 +// +// This work may be reproduced, modified, distributed, performed, and +// displayed for any purpose, but must acknowledge the mods +// project. Copyright is retained and must be preserved. The work is +// provided as is; no warranty is provided, and users accept all +// liability. +/* -// client globals +CLIENT GLOBALS --------------------------------------------------- -var reps = new Array() +*/ var sckt = {} -var lastPos = {} +var lastPos = { x: 10, y: 10 } // drawing / div-ing var wrapper = {} -// client fns +/* + +STARTUP --------------------------------------------------- + +*/ + +window.onload = function() { + svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg') + svg.style.position = 'absolute' + svg.style.left = 0 + svg.style.top = 0 + svg.style.zIndex = 0 + svg.style.overflow = 'visible' + svg.setAttribute('width', 2) + svg.setAttribute('height', 2) + svg.setAttribute('id', 'svg') + svg.setAttribute('width', '100%') + svg.setAttribute('height', '100%') + document.body.appendChild(svg) + + wrapper = document.createElement('div') + wrapper.id = 'wrapper' + document.body.append(wrapper) + + const socket = new WebSocket('ws://localhost:8081') + + socket.onopen = function(evt) { + // pass to global ref + sckt = this + // say hello + socketSend('console', 'hello server') + console.log('socket open') + // ask for the current program + socketSend('get current program', '') + // main socket entry point + this.onmessage = (evt) => { + socketRecv(evt) + } + // others + this.onerror = (err) => { + console.log('socket error', err) + } + this.onclose = (evt) => { + console.log('socket closed', evt) + sckt = null + } + } +} + +/* + +RECV / SEND PORTALS --------------------------------------------------- + +*/ function socketSend(type, data) { var msg = { @@ -22,21 +90,6 @@ function socketSend(type, data) { sckt.send(JSON.stringify(msg)) } -// get json menu item and render -// and ask for module at /obj/key -oncontextmenu = function(evt) { - if (sckt) { - lastPos.X = evt.pageX - lastPos.Y = evt.pageY - socketSend('get menu', '') - } else { - // socket brkn - location.reload() - } - // prevents event bubbling - return false -} - function socketRecv(evt) { var recv = JSON.parse(evt.data) var type = recv.type @@ -47,39 +100,113 @@ function socketRecv(evt) { case 'console': console.log('RECV CONSOLE:', data) break - case 'put menu': - buildMenu(data) + case 'put module menu': + console.log('RECV MENU') + heapSendsModuleMenu(data) break - case 'add reps': + case 'put program': console.log('RECV PROGRAM') - addReps(data) - break - case 'add rep': - addRep(data) - break - case 'change rep': - changeRep(data) - break - case 'change state': - changeState(data) + heapSendsNewProgram(data) break + case 'put module': + console.log('RECV NEW MODULE') + heapSendsNewModule(data) + break + case 'put state': + console.log('RECV STATE CHANGE') + heapSendsNewState(data) + break default: console.log('ERR recv with non recognized type', recv) break } } +/* + +MISC --------------------------------------------------- -function addReps(reps) { +*/ + +// return ul element with name and alt and link? +function heapSendsModuleMenu(tree) { + var menuDom = document.createElement('div') + menuDom.id = 'menu' + menuDom.style.left = lastPos.x + 'px' + menuDom.style.top = lastPos.y + 'px' + for (key in tree) { + var ul = document.createElement('ul') + ul.innerHTML = key.toString() + for (subkey in tree[key]) { + var li = document.createElement('li') + var path = tree[key][subkey].path + li.innerHTML = subkey.toString() + li.id = path + li.addEventListener('click', function(evt) { + var data = this.id + socketSend('add module', data) + wrapper.removeChild(document.getElementById('menu')) + }) + ul.appendChild(li) + } + menuDom.appendChild(ul) + } + wrapper.append(menuDom) + + function rmListener(evt) { + var findMenu = document.getElementById('menu') + if (findMenu !== null && findMenu.id == 'menu') { + wrapper.removeChild(findMenu) + } + } + + document.addEventListener('click', rmListener) +} + +/* + +HEAP -> SERVER --------------------------------------------------- + +*/ + +// always a rep, tho +var program = {} + + +// re-writes the program, adds a description, +// and loads multiple representations of modules to the view + +function heapSendsNewProgram(prgm) { + // whole hearted replace + // hello for bugs when we lay this on top of something else + program = prgm + // 1st we want to git rm old shit ... // when adding links, we'll have to add all and then draw links - for (rep in reps) { - addRep(reps[rep]) + console.log(program) + for (mdlName in program.modules) { + addRepToView(program.modules[mdlName]) + } + redrawLinks() +} + +function heapSendsNewModule(mdl){ + if(program.description == null){ + program.description.name = 'unnamed program' + } + if(program.modules == null){ + program.modules = {} } + addRepToView(mdl) + program.modules[mdl.description.id] = mdl redrawLinks() } -// write html from json representation -function addRep(rep) { + +// writes DOM elements to represent the module, appends to the wrapper +// and appends to the rep object a .ui object +// containing references to those DOM objects + +function addRepToView(rep) { // a div to locate it var domElem = document.createElement('div') // dif. color for hardwares ? @@ -87,8 +214,8 @@ function addRep(rep) { if (rep.description.isHardware) { domElem.classList.add('hardware') } - domElem.style.left = lastPos.X + 'px' - domElem.style.top = lastPos.Y + 'px' + domElem.style.left = lastPos.x + 'px' + domElem.style.top = lastPos.y + 'px' // more html: the title var title = document.createElement('div') @@ -97,8 +224,8 @@ function addRep(rep) { title.alt = rep.description.alt domElem.appendChild(title) - // make UI elements // place in pos if info present + // the rep.ui object will store references to the module's related DOM elements if (rep.ui != null) { if (rep.ui.left != null) { domElem.style.left = rep.ui.left + 'px' @@ -108,8 +235,8 @@ function addRep(rep) { } } else { rep.ui = {} - rep.ui.left = lastPos.X - rep.ui.top = lastPos.Y + rep.ui.left = lastPos.x + rep.ui.top = lastPos.y } rep.ui.domElem = domElem @@ -164,7 +291,7 @@ function addRep(rep) { document.addEventListener('mousemove', domElemMouseMove) - domElem.onmouseup = function() { + title.onmouseup = function() { rep.ui.left = parseInt(domElem.style.left, 10) rep.ui.top = parseInt(domElem.style.top, 10) putUi(rep) @@ -173,55 +300,12 @@ function addRep(rep) { } } - console.log('REP AT ADD', rep) - - // ADD TO LISTS, DOC - reps.push(rep) wrapper.appendChild(rep.ui.domElem) - - putUi(rep) -} - -function redrawLinks() { - while (svg.firstChild) { - svg.removeChild(svg.firstChild) - } - // rm old links then redraw everything - //console.log('now drawing links') - for (var i = 0; i < reps.length; i++) { - var rep = reps[i] - for (key in rep.outputs) { - var output = rep.outputs[key] - var outputUi = rep.ui.outputs[key] - for (input in output.calls) { - var toId = output.calls[input].parentId - var toKey = output.calls[input].key - var inputUi = reps[toId].ui.inputs[toKey] - - var outPos = getOutputArrow(outputUi) - var inPos = getInputArrow(inputUi) - - var bz = newBezier(outPos.x, outPos.y, inPos.x, inPos.y) - } - } - } -} - -function changeRep(data) { - console.log('CHANGE REP', data) - var rep = reps[data.id] - - for (var key in data) { - if (key == 'outputs') { - rep.outputs = data.outputs - } - } - - redrawLinks() } // update state from server to UI -function changeState(data) { +function heapSendsNewState(data) { + console.log('HEAP SENDS CHANGE STATE IN MODULE', data) var rep = reps[data.id] for (var key in data.state) { if (data.state[key].isButton) { @@ -239,13 +323,11 @@ function changeState(data) { } } -function isStateKey(key) { - if (key.indexOf('_') == 0 || key == 'emitters' || key == 'onChange' || key == 'emitChange') { - return false - } else { - return true - } -} +/* + +UI -> HEAP --------------------------------------------------- + +*/ // push new state from UI to server function putState(rep) { @@ -269,42 +351,45 @@ function putUi(rep) { socketSend('put ui', data) } -var clkState = false -var oClk = {} -var tmpBz = {} +/* -// input / output click handling -function evtConnectHandler(clk) { - if (!clkState) { - // first click - oClk = clk - clkState = true +UTILITIES? --------------------------------------------------- + +*/ + +function isStateKey(key) { + if (key.indexOf('_') == 0 || key == 'emitters' || key == 'onChange' || key == 'emitChange') { + return false } else { - // second click - var tClk = clk - console.log(oClk, tClk) - var x1 = parseInt(oClk.evt.target.offsetParent.style.left, 10) + oClk.evt.target.offsetLeft + oClk.evt.target.clientWidth - var y1 = parseInt(oClk.evt.target.offsetParent.style.top, 10) + oClk.evt.target.offsetTop + oClk.evt.target.clientHeight / 2 - var x2 = parseInt(tClk.evt.target.offsetParent.style.left, 10) + tClk.evt.target.offsetLeft - var y2 = parseInt(tClk.evt.target.offsetParent.style.top, 10) + tClk.evt.target.offsetTop + tClk.evt.target.clientHeight / 2 - var bz = newBezier(x1, y1, x2, y2) - clkState = false + return true + } +} - console.log('connect', oClk.rep.id, oClk.name, 'to', tClk.rep.id, tClk.name) - var data = { - from: { - id: oClk.rep.id, - output: oClk.name - }, - to: { - id: tClk.rep.id, - input: tClk.name +function redrawLinks() { + // probably not a great way to do this, we're removing everything + // svg -rm -r + while (svg.firstChild) { + svg.removeChild(svg.firstChild) + } + // redraw thru all links, just look at reps + for(mdlName in program.modules){ + var mdlRep = program.modules[mdlName] + for(key in mdlRep.outputs){ + var output = mdlRep.outputs[key] + var outputUi = mdlRep.ui.outputs[key] + for (input in output.calls) { + var toId = output.calls[input].parentId + var toKey = output.calls[input].key + var inputUi = program.modules[toId].ui.inputs[toKey] + var outPos = getOutputArrow(outputUi) + var inPos = getInputArrow(inputUi) + var bz = newBezier(outPos.x, outPos.y, inPos.x, inPos.y) } } - socketSend('put link', data) } } + // need top level rep of program - nice to think of how to handle heirarchy later on? tl rep is internal rep ... is same ? // how to handle movement of rep, incl. svg - goes with moving mouse after 1st click: svg lives 'in' rep ? @@ -315,99 +400,58 @@ function evtConnectHandler(clk) { var svgns = 'http://www.w3.org/2000/svg' var svg = {} -// 651 -// 1554 - - /* -var crv = {} -document.addEventListener('mousemove', function(evt) { - modifyBezier(crv, 0, 0, evt.pageX, evt.pageY) -}) -*/ +UI EVENTS --------------------------------------------------- -// return ul element with name and alt and link? -function buildMenu(tree) { - var menuDom = document.createElement('div') - menuDom.id = 'menu' - menuDom.style.left = lastPos.X + 'px' - menuDom.style.top = lastPos.Y + 'px' - for (key in tree) { - var ul = document.createElement('ul') - ul.innerHTML = key.toString() - for (subkey in tree[key]) { - var li = document.createElement('li') - var path = tree[key][subkey].path - li.innerHTML = subkey.toString() - li.id = path - li.addEventListener('click', function(evt) { - var data = this.id - socketSend('add module', data) - wrapper.removeChild(document.getElementById('menu')) - }) - ul.appendChild(li) - } - menuDom.appendChild(ul) - } - wrapper.append(menuDom) +*/ - function rmListener(evt) { - var findMenu = document.getElementById('menu') - if (findMenu !== null && findMenu.id == 'menu') { - wrapper.removeChild(findMenu) - } +// get json menu item and render +// and ask for module at /obj/key +oncontextmenu = function(evt) { + if (sckt) { + lastPos.x = evt.pageX + lastPos.y = evt.pageY + socketSend('get module menu', '') + } else { + // socket brkn, reload page + location.reload() } - - document.addEventListener('click', rmListener) + // prevents event bubbling + return false } -// init & hookup - -window.onload = function() { - svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg') - svg.style.position = 'absolute' - svg.style.left = 0 - svg.style.top = 0 - svg.style.zIndex = 0 - svg.style.overflow = 'visible' - svg.setAttribute('width', 2) - svg.setAttribute('height', 2) - svg.setAttribute('id', 'svg') - svg.setAttribute('width', '100%') - svg.setAttribute('height', '100%') - document.body.appendChild(svg) - - wrapper = document.createElement('div') - wrapper.id = 'wrapper' - document.body.append(wrapper) - - const socket = new WebSocket('ws://localhost:8081') +var clkState = false +var oClk = {} +var tmpBz = {} - socket.onopen = function(evt) { - // pass to global ref - sckt = this - // say hello - socketSend('console', 'hello server') - console.log('socket open') - // main socket entry point - this.onmessage = (evt) => { - socketRecv(evt) - } - // others - this.onerror = (err) => { - console.log('socket error', err) - } - this.onclose = (evt) => { - console.log('socket closed', evt) - sckt = null +// input / output click handling +function evtConnectHandler(clk) { + if (!clkState) { + // first click + oClk = clk + clkState = true + } else { + // second click + var tClk = clk + //console.log(oClk, tClk) + var x1 = parseInt(oClk.evt.target.offsetParent.style.left, 10) + oClk.evt.target.offsetLeft + oClk.evt.target.clientWidth + var y1 = parseInt(oClk.evt.target.offsetParent.style.top, 10) + oClk.evt.target.offsetTop + oClk.evt.target.clientHeight / 2 + var x2 = parseInt(tClk.evt.target.offsetParent.style.left, 10) + tClk.evt.target.offsetLeft + var y2 = parseInt(tClk.evt.target.offsetParent.style.top, 10) + tClk.evt.target.offsetTop + tClk.evt.target.clientHeight / 2 + //var bz = newBezier(x1, y1, x2, y2) + clkState = false + //console.log('connect', oClk.rep.description.id, oClk.name, 'to', tClk.rep.description.id, tClk.name) + var data = { + from: { + id: oClk.rep.description.id, + output: oClk.name + }, + to: { + id: tClk.rep.description.id, + input: tClk.name + } } + socketSend('put link', data) } -} - -/* - - add inputs and outputs - - ui for link inputs and outputs - - - .. hold svg's in div of ui element rep.ui.domElement - also track endpts there, write tiny svg class ? then .onmove etc ties through to all elements ? -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/client/divtools.js b/client/divtools.js index 1b57063a28793b6dbc1df51a0ffa26517892167a..fb99fc95f2f751966ae58b2dcae357417e463410 100644 --- a/client/divtools.js +++ b/client/divtools.js @@ -2,68 +2,56 @@ function writeStateRep(container, rep, key) { var variable = rep.state[key] - if (variable.isButton) { - console.log('BUTTON!') - var li = document.createElement('li') - li.appendChild(document.createTextNode(variable.label)) - li.addEventListener('click', function() { - // invert - if (rep.state[key].isPressed) { - rep.state[key].isPressed = false - } else { - rep.state[key].isPressed = true - } - putState(rep) - }) - container.appendChild(li) - return li - } else if (variable.isMultiLine) { - console.log('MULTILINE!') - var li = document.createElement('li') - li.appendChild(document.createTextNode(variable.label)) - li.appendChild(document.createElement('br')) - var txtArea = document.createElement('textarea') - txtArea.rows = variable.rows - txtArea.cols = 27 - txtArea.value = variable.value - txtArea.addEventListener('change', function(){ - rep.state[key].value = txtArea.value - putState(rep) - }) - li.appendChild(txtArea) - container.appendChild(li) - return txtArea - } else { - if (typeof variable == 'string') { + switch (variable.type) { + case 'button': + console.log('BUTTON!') var li = document.createElement('li') - li.appendChild(document.createTextNode(key)) - var input = document.createElement('input') - input.type = 'text' - input.size = 24 - input.value = variable - input.addEventListener('change', function() { - rep.state[key] = input.value + li.appendChild(document.createTextNode(variable.label)) + li.addEventListener('click', function() { + // invert + if (rep.state[key].isPressed) { + rep.state[key].isPressed = false + } else { + rep.state[key].isPressed = true + } putState(rep) }) - li.appendChild(input) container.appendChild(li) - return input - } else if (typeof variable == 'number') { + return li + break + case 'multiline': + console.log('MULTILINE!') var li = document.createElement('li') - li.appendChild(document.createTextNode(key)) - var input = document.createElement('input') - input.type = 'text' - input.size = 24 - input.value = variable.toString() - input.addEventListener('change', function() { - rep.state[key] = parseFloat(input.value) + li.appendChild(document.createTextNode(variable.label)) + li.appendChild(document.createElement('br')) + var txtArea = document.createElement('textarea') + txtArea.rows = variable.rows + txtArea.cols = 27 + txtArea.value = variable.value + txtArea.addEventListener('change', function() { + rep.state[key].value = txtArea.value putState(rep) }) - li.appendChild(input) + li.appendChild(txtArea) container.appendChild(li) - return input - } else if (typeof variable == 'object') { - if (Array.isArray(variable)) { + return txtArea + break + default: + if (typeof variable == 'string') { + var li = document.createElement('li') + li.appendChild(document.createTextNode(key)) + var input = document.createElement('input') + input.type = 'text' + input.size = 24 + input.value = variable + input.addEventListener('change', function() { + rep.state[key] = input.value + putState(rep) + }) + li.appendChild(input) + container.appendChild(li) + return input + } else if (typeof variable == 'number') { var li = document.createElement('li') li.appendChild(document.createTextNode(key)) var input = document.createElement('input') @@ -71,20 +59,36 @@ function writeStateRep(container, rep, key) { input.size = 24 input.value = variable.toString() input.addEventListener('change', function() { - var arr = input.value.split(',') - arr.forEach(function(element, index, array) { - array[index] = parseFloat(element) - }) - rep.state[key] = arr + rep.state[key] = parseFloat(input.value) putState(rep) }) li.appendChild(input) container.appendChild(li) return input + } else if (typeof variable == 'object') { + if (Array.isArray(variable)) { + var li = document.createElement('li') + li.appendChild(document.createTextNode(key)) + var input = document.createElement('input') + input.type = 'text' + input.size = 24 + input.value = variable.toString() + input.addEventListener('change', function() { + var arr = input.value.split(',') + arr.forEach(function(element, index, array) { + array[index] = parseFloat(element) + }) + rep.state[key] = arr + putState(rep) + }) + li.appendChild(input) + container.appendChild(li) + return input + } + } else { + console.log("unui'd type:", typeof variable) } - } else { - console.log("unui'd type:", typeof variable) - } + break } } @@ -123,7 +127,6 @@ function newBezier(x1, y1, x2, y2) { return bz } - function redrawBezier(bz) { var bl = Math.sqrt(Math.pow((bz.x1 - bz.x2), 2) + Math.pow((bz.y1 - bz.y2), 2)) * 0.6 var ps = 'M ' + bz.x1 + ' ' + bz.y1 + ' C ' + (bz.x1 + bl) + ' ' + bz.y1 diff --git a/main.js b/main.js index 86ead59d7ccec40b9906fd82a464c2d226b4b402..fd762dd08ce1966dfc2647974a5a12c49a9175c7 100644 --- a/main.js +++ b/main.js @@ -1,6 +1,6 @@ // // -// new node controller +// new node controller / HEAP // // main.js // @@ -18,27 +18,11 @@ RULES: -*/ - -/* - -SERVER +modules are objects having inputs, outputs, and state +programs are assemblies of modules */ -/* ------------------------------------------------------- -PROGRAM AS API ------------------------------------------------------- -*/ - -// nodes are objects having inputs, outputs, and state -// nodes can be made up of other nodes -// a node originates somewhere, - -// is it a JSON, or a txt .js file ? loadProgram and loadModule ... -// it wants to be an object that gets 'read' in ... - const Reps = require('./reps.js') const Programs = require('./programs.js') @@ -59,46 +43,7 @@ PROGRAM REPRESENT */ -//console.log('modules at prgmem start', modules) -function putReps() { - var reps = new Array() - for (mod in modules) { - reps.push(makeRep(modules[mod])) - } - socketSend('add reps', reps) -} - -function makeRep(mod) { - // scrape for only things we'll want to represent - var rep = { - id: mod.id, - desc: mod.description, - inputs: mod.inputs, - outputs: mod.outputs, - state: {} - } - - // holds UI information - to load mods at location - if (mod.ui != null) { - rep.ui = mod.ui - } - - for (var key in mod.state) { - if (isStateKey(key)) { - rep.state[key] = mod.state[key] - } - } - - return rep -} - -function putRep(mod) { - socketSend('add rep', makeRep(mod)) -} - -function changeRep(mod) { - socketSend('change rep', makeRep(mod)) -} +/* // update state from UI to server function changeState(data) { @@ -188,23 +133,6 @@ function putLink(data) { changeRep(fromModule) } -function buildMenu() { - var tree = {} - var dir = fs.readdirSync('./src') - for (i in dir) { - tree[dir[i]] = {} - var subdir = fs.readdirSync('./src/' + dir[i]) - for (j in subdir) { - // find js files - if (subdir[j].slice(-3) === '.js') { - var obj = {} - obj.path = './src/' + dir[i] + '/' + subdir[j] - tree[dir[i]][subdir[j].slice(0, -3)] = obj - } - } - } - - return tree -} +*/ // put \ No newline at end of file diff --git a/reps.js b/reps.js index 7e0024105b23bd1a452cb63184f9fa2bf9c702e0..81a4fbeda41ae95ec00ad096a1f8053bf894d222 100644 --- a/reps.js +++ b/reps.js @@ -1,3 +1,6 @@ +const JSUnit = require('./lib/jsunit.js') +let isStateKey = JSUnit.isStateKey + function makeRepFromModule(mdl) { var rep = { description: { diff --git a/save/onesave.json b/save/onesave.json index 97421540da2a85a82027de9155330c52a0a90723..9f9dcf6bfc6ebc9864e10e8ab6e09e845eede9d1 100644 --- a/save/onesave.json +++ b/save/onesave.json @@ -23,10 +23,6 @@ { "parentId": "delay-2", "key": "thru" - }, - { - "parentId": "logger-3", - "key": "thru" } ] } diff --git a/views.js b/views.js index 80c3782025b1aadf572cbdad72a75606ae71d53a..57bfa9d0fa32c409a7c14f7cbac4f484fec3c28c 100644 --- a/views.js +++ b/views.js @@ -8,13 +8,15 @@ const http = require('http').Server(app) // websocket, to share program representations with the client (and back) const WebSocket = require('ws') +const Reps = require('./reps.js') + /* -SERVER AND WS SETUP +SERVER AND WS SETUP -------------------------------------------------- */ -var program = null +var program = null var sckt = null function startHttp() { @@ -45,7 +47,6 @@ function startWs() { // say hello socketSend('console', 'hello client') // send current config as list of all modules - uiInit() console.log('socket open on 8081') ws.on('message', (evt) => { socketRecv(evt) @@ -53,6 +54,22 @@ function startWs() { }) } +/* + +HOOKUP REF TO TL ------------------------------------------------------ + +*/ + +function assignProgram(prgm) { + program = prgm +} + +/* + +RECV / SEND PORTALS --------------------------------------------------- + +*/ + function socketRecv(evt) { var recv = JSON.parse(evt) var type = recv.type @@ -63,25 +80,27 @@ function socketRecv(evt) { case 'console': console.log('RECV CONSOLE:', data) break - case 'get menu': - var tree = buildMenu() - socketSend('put menu', tree) + case 'get current program': + uiRequestCurrentProgram() + break + case 'get module menu': + uiRequestModuleMenu() + break + case 'load program': + uiRequestLoadProgram() break - case 'add module': - addModule(data) + case 'put module': + uiRequestNewModule(data) break case 'put state': - changeState(data) + uiRequestStateChange(data) break case 'put link': - putLink(data) + uiRequestLinkChange(data) // id:output > id:input break case 'put ui': - changeUi(data) - break - case 'rm link': - // id:output > id:input + uiRequestUiChange(data) break default: console.log('ERR server recv with non recognized type', recv) @@ -100,18 +119,84 @@ function socketSend(type, data) { } } -function assignProgram(prgm){ - program = prgm -} +/* + +HEAP -> UI HANDLES --------------------------------------------------- + +*/ // runs when browser first loads -function uiInit(){ +function uiRequestCurrentProgram() { // make reps from program and send the list - console.log("BRWSER LOADED") - console.log(program) + console.log('SEND PROGRAMS TO UI') + var prgRep = { + description: { + name: program.description.name, + id: program.description.id, + path: program.description.path + }, + modules: {} + } + + for (mdlName in program.modules) { + var mdlRep = Reps.makeFromModule(program.modules[mdlName]) + prgRep.modules[mdlName] = mdlRep + } + socketSend('put program', prgRep) +} + +function uiRequestModuleMenu() { + var availableSourceRep = {} + var dir = fs.readdirSync('./src') + for (i in dir) { + availableSourceRep[dir[i]] = {} + var subdir = fs.readdirSync('./src/' + dir[i]) + for (j in subdir) { + // find js files + if (subdir[j].slice(-3) === '.js') { + var obj = {} + obj.path = './src/' + dir[i] + '/' + subdir[j] + availableSourceRep[dir[i]][subdir[j].slice(0, -3)] = obj + } + } + } + + socketSend('put module menu', availableSourceRep) } +/* + +UI -> HEAP HANDLES --------------------------------------------------- + +*/ + +function uiRequestLoadProgram(data){ + console.log('UI REQUEST TO OPEN NEW PROGRAM', data) +} +function uiRequestNewModule(data) { + console.log('UI REQUEST ADD MODULE TO PROGRAM', data) +} + +function uiRequestStateChange(data) { + console.log('UI REQUEST CHANGE STATE IN MODULE', data) + // do state.obj.emit +} + +function uiRequestLinkChange(data) { + console.log('UI REQUEST ADD EVENT LINK', data) +} + +function uiRequestUiChange(data) { + console.log('UI REQUEST ADD / CHANGE UI INFO TO MODULE', data) + // do it in module.description +} + +/* + +EXPORTS -------------------------------------------------------------- + +*/ module.exports = { startHttp: startHttp,