diff --git a/README.md b/README.md index e4788a14578dc58922d956702926b814c5b881d2..14bc3ffc947acf7ef69e1347441a05b18dc86139 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,10 @@ This project serves the developement environment / api we use to write and repre ## For MW + - *don't forget* + - when hooking back to server, server.emitChange(key) ... from writeStateObject + - does state copy over successfully from loaded mod? + - fundament - the basic unit is a .js file having inputs, outputs, and state objects - we can compose programs of these modules, being collections of them with connections diff --git a/lib/jsunit.js b/lib/jsunit.js index 4f917eaab32088dc5996948e086badc80b184567..714505339514196d7e457a238356d7ae16ba8b11 100644 --- a/lib/jsunit.js +++ b/lib/jsunit.js @@ -70,6 +70,14 @@ function State() { return state } +function isStateKey(key) { + if (key.indexOf('_') == 0 || key == 'emitters' || key == 'onChange' || key == 'emitChange') { + return false + } else { + return true + } +} + // a coupl'a fancy UI state hooks function Button(label) { var button = { @@ -97,6 +105,7 @@ module.exports = { Input: Input, Output: Output, State: State, + isStateKey: isStateKey, Button: Button, MultiLine: MultiLine } \ No newline at end of file diff --git a/main.js b/main.js index 769bb6ce98ff57848ac1b2b972592b6fb3cdde1a..86ead59d7ccec40b9906fd82a464c2d226b4b402 100644 --- a/main.js +++ b/main.js @@ -22,115 +22,10 @@ RULES: /* -SYSTEM REQUIRES - -*/ - -// file system to load / look at our available modules / edit them -const fs = require('fs') - -// express serves files, http makes the connection -const app = require('express')() -const http = require('http').Server(app) - -// websocket, to share program representations with the client (and back) -const WebSocket = require('ws') - -// setup prgmem land first, then load server stuff -// break server off into obj ? cumbersome ? probably nice to be able to turn it off - -/* - -SERVER AND WS SETUP - -*/ - -// serving this handful of static files -app.get('/', (req, res) => { - console.log('client req /') - res.sendFile(__dirname + '/client/index.html') -}) - -app.get('/:file', (req, res) => { - console.log('client req', req.params.file) - res.sendFile(__dirname + '/client/' + req.params.file) -}) - -// and listening for requests here -const wss = new WebSocket.Server({ port: 8081 }) - -wss.on('connection', (ws) => { - sckt = ws - // say hello - socketSend('console', 'hello client') - // send current config as list of all modules - putReps() - console.log('socket open on 8081') - ws.on('message', (evt) => { - socketRecv(evt) - }) -}) - -// through this window -http.listen(8080, () => { - console.log('listening on 8080 for static files') -}) - -/* - SERVER */ -var sckt = null - -function socketSend(type, data) { - if (sckt) { - var msg = { - type: type, - data: data - } - //console.log('SEND', msg) - sckt.send(JSON.stringify(msg)) - } -} - -function socketRecv(evt) { - var recv = JSON.parse(evt) - var type = recv.type - var data = recv.data - //console.log('RECV', recv) - // bang thru - switch (type) { - case 'console': - console.log('RECV CONSOLE:', data) - break - case 'get menu': - var tree = buildMenu() - socketSend('put menu', tree) - break - case 'add module': - addModule(data) - break - case 'put state': - changeState(data) - break - case 'put link': - putLink(data) - // id:output > id:input - break - case 'put ui': - changeUi(data) - break - case 'rm link': - // id:output > id:input - break - default: - console.log('ERR server recv with non recognized type', recv) - break - } -} - /* ------------------------------------------------------ PROGRAM AS API @@ -151,8 +46,12 @@ var program = {} program = Programs.open('save/onesave.json') -var View = require('./views.js') +const View = require('./views.js') +View.startHttp() +View.startWs() +Programs.assignSocket(View.uiSocket) +View.assignProgram(program) /* @@ -160,7 +59,6 @@ PROGRAM REPRESENT */ - //console.log('modules at prgmem start', modules) function putReps() { var reps = new Array() @@ -174,7 +72,7 @@ function makeRep(mod) { // scrape for only things we'll want to represent var rep = { id: mod.id, - description: mod.description, + desc: mod.description, inputs: mod.inputs, outputs: mod.outputs, state: {} @@ -253,15 +151,6 @@ function setUiPos(module, left, top) { module.ui.top = top } - -function isStateKey(key) { - if (key.indexOf('_') == 0 || key == 'emitters' || key == 'onChange' || key == 'emitChange') { - return false - } else { - return true - } -} - // push new state from server to UI function putState(mod) { // push just the state to the individual mod diff --git a/programs.js b/programs.js index c29c204f727cc0e881e2615ee7ba28dc20dd3420..9ab2299e30f16379e81a60994eadc0d3a793fdc1 100644 --- a/programs.js +++ b/programs.js @@ -1,6 +1,8 @@ const fs = require('fs') +const JSUnit = require('./lib/jsunit.js') +let isStateKey = JSUnit.isStateKey -function addModuleToProgram(program, path) { +function loadModuleFromSource(program, path) { // source -> heap if (fs.existsSync(path)) { var src = require(path) @@ -62,9 +64,14 @@ function writeStateObject(mod, key) { this['_' + key] = x //console.log('SET', key, this['_' + key]) // push to internal state change handler - this.emitChange(key) - // update server (or in some cases, a confirmation) - putState(mod) + // let's call emitChange from the server-side ... + // so that we don't get into any heavy VIR + // when we change it within the module + // this.emitChange(key) + // push to external view + if(link){ + pushState(mod, key) + } } }) Object.defineProperty(mod.state, key, { @@ -75,6 +82,22 @@ function writeStateObject(mod, key) { }) } +/* + +EXTERNAL HOOKS + +*/ + +function assignSocket(sckt){ + socket = sckt +} + +function pushState(mod, key){ + console.log("GONNA PUSH IT OOOOOUT") + console.log('link', socket) +} + + function saveProgram(prgmem, path) { // ok, and we're interested in just copying the relevant things ... var svprgmem = { @@ -117,15 +140,16 @@ function openProgram(path){ for(key in prgRep.modules){ var mdlRep = prgRep.modules[key] - addModuleToProgram(program, mdlRep.description.path) + loadModuleFromSource(program, mdlRep.description.path) } - // gonna hook 'em up + // restore saved state and links for(modName in prgRep.modules){ // keys should be identical for rep and heap var mdlRep = prgRep.modules[modName] var mdl = program.modules[modName] + // hooking outputs -> inputs for(outName in mdlRep.outputs){ var outRep = mdlRep.outputs[outName] // each has some caller ids @@ -138,16 +162,26 @@ function openProgram(path){ mdl.outputs[outName].attach(nI) } } + + // restoring state + for(key in mdlRep.state){ + if(isStateKey(key)){ + console.log("STATE - NEEDS WORK", key) + // want to do this without asserting the change though + // actually, if new paradigm, we don't call .onChange + // rename .onChange for 'onUiChange' or something + } + } } // once modules exist, link inputs / outputs / copy state ? - return program } module.exports = { open: openProgram, save: saveProgram, - addModule: addModuleToProgram + loadModuleFromSource: loadModuleFromSource, + assignSocket: assignSocket } \ No newline at end of file diff --git a/views.js b/views.js index aab65759f0208faa812ab74a5556bfb5c41c975a..80c3782025b1aadf572cbdad72a75606ae71d53a 100644 --- a/views.js +++ b/views.js @@ -8,42 +8,116 @@ const http = require('http').Server(app) // websocket, to share program representations with the client (and back) const WebSocket = require('ws') -// setup prgmem land first, then load server stuff -// break server off into obj ? cumbersome ? probably nice to be able to turn it off - /* SERVER AND WS SETUP */ -// serving this handful of static files -app.get('/', (req, res) => { - console.log('client req /') - res.sendFile(__dirname + '/client/index.html') -}) - -app.get('/:file', (req, res) => { - console.log('client req', req.params.file) - res.sendFile(__dirname + '/client/' + req.params.file) -}) - -// and listening for requests here -const wss = new WebSocket.Server({ port: 8081 }) - -wss.on('connection', (ws) => { - sckt = ws - // say hello - socketSend('console', 'hello client') - // send current config as list of all modules - putReps() - console.log('socket open on 8081') - ws.on('message', (evt) => { - socketRecv(evt) +var program = null +var sckt = null + +function startHttp() { + // serving this handful of static files + app.get('/', (req, res) => { + console.log('client req /') + res.sendFile(__dirname + '/client/index.html') + }) + + app.get('/:file', (req, res) => { + console.log('client req', req.params.file) + res.sendFile(__dirname + '/client/' + req.params.file) + }) + + // through this window + http.listen(8080, () => { + console.log('listening on 8080 for static files') + }) +} + + +function startWs() { + // and listening for requests here + const wss = new WebSocket.Server({ port: 8081 }) + + wss.on('connection', (ws) => { + sckt = ws + // 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) + }) }) -}) +} + +function socketRecv(evt) { + var recv = JSON.parse(evt) + var type = recv.type + var data = recv.data + //console.log('RECV', recv) + // bang thru + switch (type) { + case 'console': + console.log('RECV CONSOLE:', data) + break + case 'get menu': + var tree = buildMenu() + socketSend('put menu', tree) + break + case 'add module': + addModule(data) + break + case 'put state': + changeState(data) + break + case 'put link': + putLink(data) + // id:output > id:input + break + case 'put ui': + changeUi(data) + break + case 'rm link': + // id:output > id:input + break + default: + console.log('ERR server recv with non recognized type', recv) + break + } +} + +function socketSend(type, data) { + if (sckt) { + var msg = { + type: type, + data: data + } + //console.log('SEND', msg) + sckt.send(JSON.stringify(msg)) + } +} + +function assignProgram(prgm){ + program = prgm +} + +// runs when browser first loads +function uiInit(){ + // make reps from program and send the list + console.log("BRWSER LOADED") + console.log(program) +} + + -// through this window -http.listen(8080, () => { - console.log('listening on 8080 for static files') -}) +module.exports = { + startHttp: startHttp, + startWs: startWs, + uiSocket: { + send: socketSend + }, + assignProgram: assignProgram +} \ No newline at end of file