Newer
Older
const Reps = require('./reps.js')
id: name
},
modules: {}
}
return program
}
function loadModuleFromSource(program, path, id) {
// compile a new object based on definition in path
var src = {}
try {
src = require(path)
}
catch(err){
console.log('ERR on module load, at path', path, err)
return false
}
var mod = new src()
// wants unique module id's
if (program.description.counter == null) {
program.description.counter++
// make unique name, or recall from program save
if (id) {
mod.description.id = id
} else {
mod.description.id = mod.description.name + '-' + program.description.counter
}
// add to program object
program.modules[mod.description.id] = mod
// input need references for later hookup
for (key in mod.inputs) {
mod.inputs[key].parentId = mod.description.id
mod.inputs[key].key = key
}
// state items get wrapped in a getter / setter
// so that changes from internal modules can
// push to UI
// and not all have state
if(mod.state != null){
mod.state.init(mod.description.id, socket)
}
// not all have ui,
if(mod.ui != null){
mod.ui.init(mod.description.id, socket)
}
*/
console.log('ADDING', mod.description.id, 'to', program.description.id)
/* ---------------------------------- */
// WARN! Corner Case should Go Away or Improve at next spiral
if (mod.description.isLink) {
for (mdlName in program.modules) {
if (program.modules[mdlName].description.isLink) {
console.log("PRGMEM ONLY BIG ENOUGH FOR ONE LINK")
//process.exit()
// end corner case code
/* ---------------------------------- */
/* ---------------------------------- */
// WARN! Corner Case should Go Away or Improve at next spiral
// hardware corner case is hardware corner case
// here's what we'll do
// if it's hardware, and we're not loading from some saved program (no id)
//
if (mod.description.isHardware && !mod.description.isLink /* && id == null */ ) {
for (mdlName in program.modules) {
if (program.modules[mdlName].description.isLink) {
lnk = mdlName
}
}
if (lnk) {
console.log('CORNER CASE: LOADING HW MODULE, LINKING TO LINK')
program.modules[lnk].attach(mod.route)
} else {
console.log('CORNER CASE: LOADING HW MODULE, ALSO LOADING LINK')
var link = loadModuleFromSource(program, './modules/hardware/atkseriallink.js')
// hook it up auto-like
link.attach(mod.route)
}
}
// also return it so that we can write programs without the UI
return mod
} else {
console.log('ERR no module found at ', path)
}
}
mod.state['_' + key] = mod.state[key]
mod.state[key] = {}
Object.defineProperty(mod.state, key, {
set: function(x) {
// update internal value
this['_' + key] = x
// console.log('SET', key, this['_' + key])
if (socket) {
}
})
Object.defineProperty(mod.state, key, {
get: function() {
console.log('KEY', key)
console.log("IS", this['_' + key])
//console.log('GET', key, this['_' + key])
return this['_' + key]
}
})
}
function removeModuleFromProgram(program, id) {
for (key in program.modules) {
for (otKey in mdl.outputs) {
function assignSocket(sckt) {
// we can pass this object 'down' by reference, once it loads
socket.send = sckt.send
function saveProgram(prgmem, path) {
// ok, and we're interested in just copying the relevant things ...
var svprgmem = {
description: {
name: prgmem.description.name,
counter: prgmem.description.counter
},
modules: {}
}
var mdls = prgmem.modules
for (key in mdls) {
var og = Reps.makeFromModule(mdl)
svprgmem.modules[mdl.description.id] = og
}
fs.writeFileSync(path, JSON.stringify(svprgmem, null, 2), 'utf8')
console.log('PROGRAM SAVED AT', path)
function openProgram(path) {
var program = {}
// get the .json file as an object
var prgRep = JSON.parse(fs.readFileSync(path, 'utf8'))
console.log('OPENING THIS PRGRAM REP', prgRep)
// copy-pasta the program descro,
program.description = {
name: prgRep.description.name,
counter: 0,
id: prgRep.description.name + 1, // in another world, we count
path: path
}
// gonna get those modules from source
program.modules = {}
for (key in prgRep.modules) {
loadModuleFromSource(program, mdlRep.description.path, mdlRep.description.id)
for (modName in prgRep.modules) {
// this is the representation that we're opening up from
// this is the actual object, having functions and whatnot
if (mdl == null) {
console.log('-------------------------------- NULL MDL at openProgram')
console.log('prgRep modules', prgRep.modules)
console.log('program modules', program.modules)
}
for (outName in mdlRep.outputs) {
var outRep = mdlRep.outputs[outName]
// each has some caller ids
for (nestedInputRep in outRep.calls) {
// conn from tl program -> this hookup
var nIRParent = outRep.calls[nestedInputRep].parentId
var nIRKey = outRep.calls[nestedInputRep].key
var nI = program.modules[nIRParent].inputs[nIRKey]
console.log("ATTACHING", nIRKey, 'to', outName)
mdl.outputs[outName].attach(nI)
}
}
/* the first wrap, only here to prevent link not-reconnecting on program restart, should go away */
if (!mdlRep.description.isLink) {
for (key in mdlRep.state) {
if (isStateKey(key)) {
// I think this is OK?
// would prefer to do this before we write getters and setters
// for now we walk-around to secret key ...
if (mdl.state[key].type == 'button' || mdl.state[key].type == 'multiline') {
// defaul vals
} else if (key == 'route'){
// absolutely does not belong here
// TODO: states: sometimes we load, we want to run the change emitter ... sometimes we don't
// what choice ?
mdl.state['_' + key] = mdlRep.state[key]
} else {
mdl.state['_' + key] = mdlRep.state[key]
}
}
// and let's run init if it's there
if(mdl.init != null){
mdl.init()
}
//console.log('mdlRep', mdlRep)
//console.log('mdl', mdl)
// restore position / UI state
if (mdlRep.description.position != null) {
mdl.description.position = {}
mdl.description.position.left = mdlRep.description.position.left
mdl.description.position.top = mdlRep.description.position.top
}
// once modules exist, link inputs / outputs / copy state ?
return program
}
module.exports = {