Newer
Older
// 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')
const Programs = require('./programs.js')
SERVER AND WS SETUP --------------------------------------------------
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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
console.log('socket open on 8081')
ws.on('message', (evt) => {
socketRecv(evt)
})
/*
HOOKUP REF TO TL ------------------------------------------------------
*/
function assignProgram(prgm) {
program = prgm
}
/*
RECV / SEND PORTALS ---------------------------------------------------
*/
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 current program':
uiRequestCurrentProgram()
break
case 'get module menu':
uiRequestModuleMenu()
break
case 'get program menu':
uiRequestProgramMenu()
break
case 'save program':
uiRequestSaveProgram(data)
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))
}
}
/*
HEAP -> UI HANDLES ---------------------------------------------------
*/
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)
}
// TODO: proper heirarchy, with both of these ...
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)
function uiRequestProgramMenu() {
var availableProgramRep = {}
var paths = fs.readdirSync('./programs')
for (i in paths) {
if (paths[i].slice(-5) === '.json') {
var name = paths[i].slice(0, -5)
var path = './programs/' + paths[i]
availableProgramRep[paths[i]] = {
name: name,
path: path
}
}
}
socketSend('put program menu', availableProgramRep)
}
/*
UI -> HEAP HANDLES ---------------------------------------------------
*/
// gonna tear it doooown, maybe just kick page afterwards to restart it?
program = null
program = Programs.open(data)
socketSend('restart', '')
console.log('UI REQUEST TO SAVE PROGRAM', data)
// is data a path? add .json ?
if (data) {
if (!data.includes('.json')) {
data = data + '.json'
}
path = 'programs/' + data
Programs.save(program, path)
socketSend('console', ('saved program at' + path))
function uiRequestNewModule(data) {
console.log('UI REQUEST ADD MODULE TO PROGRAM', data)
Programs.loadModuleFromSource(program, data)
// bit of a mess to pick out the last entered module
var keys = Object.keys(program.modules)
socketSend('put module', Reps.makeFromModule(program.modules[keys[keys.length - 1]]))
}
function uiRequestStateChange(data) {
console.log('UI REQUEST CHANGE STATE IN MODULE', data)
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
// there should only be one !
var id = data.description.id
var key = data.state.key
var val = data.state.val
var mdlState = program.modules[id].state
console.log('mdlState', mdlState)
var mdlStateItem = program.modules[id].state[key]
console.log('mdlStateItem', mdlStateItem)
if (mdlStateItem) {
switch (mdlState.type) {
case 'button':
mdlStateItem.onClick()
break
case 'multiline':
mdlStateItem.value = val
mdlState.emitChange(key)
break
default:
mdlStateItem = val
mdlState.emitChange(key)
break
}
} else {
console.log("ERR no state key,", key, "found here", data)
}
console.log('mdlStateItem', mdlStateItem)
console.log(program.modules[id])
}
function uiRequestLinkChange(data) {
console.log('UI REQUEST ADD EVENT LINK', data)
var fromId = data.from.id
var outputName = data.from.output
var toId = data.to.id
var inputName = data.to.input
// HERE: check if hooked already
var fromMdl = program.modules[fromId]
var toMdl = program.modules[toId]
fromMdl.outputs[outputName].attach(toMdl.inputs[inputName])
var nRep = Reps.makeFromModule(fromMdl)
socketSend('put module change', nRep)
}
function uiRequestUiChange(data) {
console.log('UI REQUEST ADD / CHANGE UI INFO TO MODULE', data)
var mod = program.modules[data.description.id]
mod.description.position = data.description.position
}
/*
EXPORTS --------------------------------------------------------------
*/