Skip to content
Snippets Groups Projects
Select Git revision
  • b08b0c2897e6fa5eb54507f3bb9b69e67b2c03cf
  • master default protected
  • at_palomagr
3 results

jsunit.js

Blame
  • jsunit.js 3.67 KiB
    // event system to include type-checking etc
    // dataflow types for javascript objects ... 
    
    var verbose = false 
    
    function Input(type, fn) {
        var input = {
            accepts: type,
            fn: fn
        }
    
        return input
    }
    
    function Output(type) {
        var output = {
            emits: type
        }
    
        output.calls = new Array()
    
        output.attach = function(input) {
            this.calls.push(input)
        }
    
        output.isLinked = function(input) {
            // return true if already hooked up 
            if (this.calls.includes(input)) {
                return true
            } else {
                return false
            }
        }
    
        output.remove = function(input) {
            if (!this.isLinked(input)) {
                console.log('attempt to rm input that is not attached')
                return false
            } else {
                this.calls.splice(this.calls.indexOf(input), 1)
            }
        }
    
        output.removeAllLinks = function() {
            this.calls = []
        }
    
        output.checkLinks = function(id) {
            console.log('checking links', this)
            for (index in this.calls) {
                if (this.calls[index].parentId == id) {
                    console.log('popping null entry from', this.calls)
                    this.calls.splice(index, 1)
                    console.log('new record', this.calls)
                } else {
                    // all good 
                }
            }
        }
    
        output.emit = function(data) {
            if (this.calls.length == 0) {
                if(verbose) console.log('no inputs bound to this output')
            } else {
                for (index in this.calls) {
                    this.calls[index].fn(JSON.parse(JSON.stringify(data)))
                }
            }
        }
    
        return output
    }
    
    function State() {
        var state = {}
    
        state.emitters = {}
        state.parentId = null
        state.socket = null
    
        // called when change from UI 
        state.onUiChange = function(item, fn) {
            this.emitters[item] = fn
        }
    
        state.emitUIChange = function(item) {
            if (this.emitters[item] != null) {
                this.emitters[item]()
            }
        }
    
        state.pushToUI = function(key) {
            if (this.socket.send != null) {
                var data = {
                    id: this.parentId,
                    key: key,
                    val: this[key]
                }
                this.socket.send('put state change', data)
            } else {
                console.log("ERR on state update to UI, socket is", this.socket)
            }
        }
    
        state.init = function(parentModId, socket) {
            // get hookups from top level program 
            this.parentId = parentModId
            this.socket = socket
            // and wrap state objects in getters / setters 
            for (key in this) {
                if (isStateKey(key)) {
                    this['_' + key] = this[key]
                    this[key] = {}
                    writeStateGetterSetter(this, key)
                }
            }
        }
    
        return state
    }
    
    function writeStateGetterSetter(state, key) {
        Object.defineProperty(state, key, {
            set: function(x) {
                // update internal value 
                state['_' + key] = x
                // console.log('SET', key, this['_' + key])
                // push to external view
                state.pushToUI(key)
            }
        })
        Object.defineProperty(state, key, {
            get: function() {
                //console.log('GET', key, this['_' + key])
                return state['_' + key]
            }
        })
    }
    
    function isStateKey(key) {
        if (key.indexOf('_') == 0 || key == 'parentId' || key == 'socket' || key == 'init' || key == 'pushToUI' || key == 'emitters' || key == 'onUIChange' || key == 'emitUIChange' ) {
            return false
        } else {
            return true
        }
    }
    
    module.exports = {
        Input: Input,
        Output: Output,
        State: State,
        isStateKey: isStateKey
    }