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 --------------------------------------------------
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, () => {
})
}
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)
case 'remove module':
uiRequestRemoveModule(data)
break
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 = {}
for (i in dir) {
availableSourceRep[dir[i]] = {}
var subdir = fs.readdirSync('./modules/' + dir[i])
for (j in subdir) {
// find js files
if (subdir[j].slice(-3) === '.js') {
var obj = {}
obj.path = './modules/' + 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)
var latest = keys[keys.length - 1]
if(program.modules[latest].description.isLink && data != './modules/hardware/atkseriallink.js'){
// we just added hardware, so added a link, so we've added two
// just burn it down
socketSend('restart', '')
}
socketSend('put module', Reps.makeFromModule(program.modules[keys[keys.length - 1]]))
function uiRequestRemoveModule(data){
console.log('UI REQUEST TO REMOVE MODULE', data.id)
Programs.removeModule(program, data.id)
socketSend('restart', '')
function uiRequestStateChange(data) {
console.log('UI REQUEST CHANGE STATE IN MODULE', data)
var mdlState = program.modules[data.id].state
if (mdlState[data.key]) {
switch (mdlState[data.key].type) {
mdlState[data.key].value = data.val
mdlState.emitChange(data.key)
mdlState[data.key] = data.val
mdlState.emitChange(data.key)
break
}
} else {
console.log("ERR no state key,", key, "found here", data)
}
}
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
var fromMdl = program.modules[fromId]
var toMdl = program.modules[toId]
// if it's already attached, we rm
if(fromMdl.outputs[outputName].isLinked(toMdl.inputs[inputName])){
fromMdl.outputs[outputName].remove(toMdl.inputs[inputName])
} else {
fromMdl.outputs[outputName].attach(toMdl.inputs[inputName])
}
var nRep = Reps.makeFromModule(fromMdl)
}
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 --------------------------------------------------------------
*/