Skip to content
Snippets Groups Projects
programs.js 5.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • Jake Read's avatar
    Jake Read committed
    const fs = require('fs')
    
    Jake Read's avatar
    Jake Read committed
    const JSUnit = require('./lib/jsunit.js')
    let isStateKey = JSUnit.isStateKey
    
    Jake Read's avatar
    Jake Read committed
    function loadModuleFromSource(program, path) {
    
    Jake Read's avatar
    Jake Read committed
        // source -> heap
        if (fs.existsSync(path)) {
            var src = require(path)
            var mod = new src()
    
            // wants unique module id's 
            if(program.description.counter == null){
                program.description.counter = 0
            } else {
                program.description.counter ++ 
            }
    
            // make unique name 
            mod.description.id = mod.description.id = mod.description.name + '-' + program.description.counter
            mod.description.path = path
            
            // 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 updating, begs for update 
            for (key in mod.state) {
                if (key == 'onChange' | key == 'emitChange' | key == 'emitters') {
                    //console.log('rolling past change fn')
                } else {
                    mod.state['_' + key] = mod.state[key]
                    mod.state[key] = {}
                    writeStateObject(mod, key)
                }
            }
    
            if (program.description.id == null) {
                if (program.description.name == null) {
                    if (program.description == null) {
                        program.description = {}
                    }
                    program.description.name = 'unnamed program'
                }
                program.description.id = program.description.name + '-' + 0
            }
    
            console.log('ADDING', mod.description.id, 'to', program.description.id)
            // also return it so that we can write programs without the UI 
            return mod
        } else {
            console.log('ERR no module found at ', path)
        }
    }
    
    function writeStateObject(mod, key) {
        Object.defineProperty(mod.state, key, {
            set: function(x) {
                // update internal value 
                this['_' + key] = x
                //console.log('SET', key, this['_' + key])
                // push to internal state change handler
    
    Jake Read's avatar
    Jake Read committed
                // 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)
                }
    
    Jake Read's avatar
    Jake Read committed
            }
        })
        Object.defineProperty(mod.state, key, {
            get: function() {
                //console.log('GET', key, this['_' + key])
                return this['_' + key]
            }
        })
    }
    
    
    Jake Read's avatar
    Jake Read committed
    /*
    
    EXTERNAL HOOKS
    
    */
    
    function assignSocket(sckt){
        socket = sckt 
    }
    
    function pushState(mod, key){
        console.log("GONNA PUSH IT OOOOOUT")
        console.log('link', socket)
    }
    
    
    
    Jake Read's avatar
    Jake Read committed
    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 mdl = mdls[key]
            var og = makeRepFromModule(mdl)
            svprgmem.modules[mdl.description.id] = og 
        }
    
        fs.writeFileSync(path, JSON.stringify(svprgmem, null, 2), 'utf8')
    }
    
    
    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){
            var mdlRep = prgRep.modules[key]
    
    Jake Read's avatar
    Jake Read committed
            loadModuleFromSource(program, mdlRep.description.path)
    
    Jake Read's avatar
    Jake Read committed
        // restore saved state and links 
    
    Jake Read's avatar
    Jake Read committed
        for(modName in prgRep.modules){
            // keys should be identical for rep and heap
            var mdlRep = prgRep.modules[modName]
            var mdl = program.modules[modName]
    
    
    Jake Read's avatar
    Jake Read committed
            // hooking outputs -> inputs 
    
    Jake Read's avatar
    Jake Read committed
            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)
                }
            }
    
    Jake Read's avatar
    Jake Read committed
    
            // 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 
                }
            }
    
    Jake Read's avatar
    Jake Read committed
        }
    
        // once modules exist, link inputs / outputs / copy state ? 
    
        return program
    }
    
    module.exports = {
        open: openProgram,
        save: saveProgram,
    
    Jake Read's avatar
    Jake Read committed
        loadModuleFromSource: loadModuleFromSource,
        assignSocket: assignSocket