From d7e22dbce4bcfcf19f30a6b1cbd7dc094df2796f Mon Sep 17 00:00:00 2001 From: Jake <jake.read@cba.mit.edu> Date: Mon, 26 Nov 2018 16:39:13 -0500 Subject: [PATCH] more work button --- README.md | 2 +- client/client.js | 4 +- client/ui/uiButton.js | 8 +- lib/atkroute.js | 37 ------- lib/atkunit.js | 59 ------------ lib/cartesian.js | 28 ------ lib/jsunit.js | 128 ------------------------- lib/packets.js | 24 ----- modules/hardware/atkbreadboardboard.js | 2 +- modules/hardware/atkmrobot.js | 2 +- modules/hardware/atkseriallink.js | 16 +++- modules/hardware/atkstepper.js | 9 +- modules/hardware/webcam.js | 2 +- modules/motion/planner.js | 4 +- modules/ui/number.js | 2 +- modules/ui/stest.js | 4 + modules/ui/terminal.js | 2 +- modules/util/delay.js | 2 +- programs.js | 10 +- src/atkunit.js | 24 ++++- src/jsunit.js | 2 +- src/ui/uiButton.js | 9 +- 22 files changed, 78 insertions(+), 302 deletions(-) delete mode 100644 lib/atkroute.js delete mode 100644 lib/atkunit.js delete mode 100644 lib/cartesian.js delete mode 100644 lib/jsunit.js delete mode 100644 lib/packets.js diff --git a/README.md b/README.md index 665d878..6a0930c 100644 --- a/README.md +++ b/README.md @@ -175,7 +175,7 @@ function uiNum() { var state = uinum.state state.number = 10 - state.onChange('number', onNumberDesire) + state.onUiChange('number', onNumberDesire) state.button = Button('WHAM', onNumberDesire) diff --git a/client/client.js b/client/client.js index 45a73a0..75985c2 100644 --- a/client/client.js +++ b/client/client.js @@ -316,8 +316,8 @@ function redrawLinks() { svg.removeChild(svg.firstChild) } // draw origin - var og1 = newLine(-15, 0, 15, 0, 5, false) - var og2 = newLine(0, -15, 0, 15, 5, false) + var og1 = newLine(20, 30, 40, 30, 3, false) + var og2 = newLine(30, 20, 30, 40, 3, false) // find that link var lnkPt var nLnk = 0 diff --git a/client/ui/uiButton.js b/client/ui/uiButton.js index 3d8f021..82d0935 100644 --- a/client/ui/uiButton.js +++ b/client/ui/uiButton.js @@ -44,6 +44,12 @@ btn.key = key // affectionately named lump of code, insert ourselves here program.modules[id].ui[key].lump = btn - socketSend('console', 'hello from' + btn.parentId + btn.key) + // and call-back to do onload things + var data = { + id: btn.parentId, + key: btn.key, + msg: 'onload' + } + socketSend('put ui change', data) } })() \ No newline at end of file diff --git a/lib/atkroute.js b/lib/atkroute.js deleted file mode 100644 index 02c2ba4..0000000 --- a/lib/atkroute.js +++ /dev/null @@ -1,37 +0,0 @@ -// object to extend for things-that-are-hardware - -// and pass f'n to call on received messages -function ATKRoute(route, calls) { - var atkroute = { - isAtkRoute: true, - link: null, // pls, deliver 2 me a hw outlet - route: route, - calls: {} - } - - atkroute.send = function(msg) { - if (this.link != null) { - // CHECKS and append route, then send - this.link.send(msg, this) - } else { - console.log("NO LINK NO SEND") - } - } - - atkroute.subscribe = function(key, callback){ - this.calls[key.toString()] = callback - } - - atkroute.onMessage = function(msg){ - // one key at a time, for now - var key = msg[0].toString() - // *could* slice the key out at this point, but nah - if(this.calls[key] != null){ - this.calls[key](msg) - } - } - - return atkroute -} - -module.exports = ATKRoute \ No newline at end of file diff --git a/lib/atkunit.js b/lib/atkunit.js deleted file mode 100644 index 08e7f12..0000000 --- a/lib/atkunit.js +++ /dev/null @@ -1,59 +0,0 @@ -// software object for reciprocal hardware object - -// boilerplate atkapi header -const InOut = require('./jsunit.js') -let Input = InOut.Input -let Output = InOut.Output -let State = InOut.State -let Button = InOut.Button - -let ATKRoute = require('./atkroute.js') - -function Hardware(){ - var hardware = { - description:{ - name: 'hardwareUnit', - alt: 'software representation of networked hardware object', - isHardware: true - }, - route: ATKRoute('0,0') - } - - hardware.state = State() - var state = hardware.state - - state.reset = Button('reset hardware', onReset) - - state.test = Button('test network', onNetworkTest) - state.message = 'click above to test network' - state.route = '0,0' // default - - state.onChange('route', function(){ - hardware.route.route = state.route - }) - - function onReset(){ - var rstpck = new Array() - rstpck.push(128) - state.message = 'reset command issued' - hardware.route.send(rstpck) - } - - function onNetworkTest(){ - var tstpck = new Array() - tstpck.push(127) - state.message = 'test packet out' - hardware.route.send(tstpck) - } - - hardware.route.subscribe(127, testReturn) - - function testReturn(msg){ - state.message = 'test OK' - console.log('test returns with msg', msg) - } - - return hardware -} - -module.exports = Hardware \ No newline at end of file diff --git a/lib/cartesian.js b/lib/cartesian.js deleted file mode 100644 index c6255fe..0000000 --- a/lib/cartesian.js +++ /dev/null @@ -1,28 +0,0 @@ -function distance(p1, p2) { - // takes p1, p2 to be arrays of same length - // computes cartesian distance - var sum = 0 - for (var i = 0; i < p1.length; i++) { - sum += Math.pow((p1[i] - p2[i]), 2) - } - return Math.sqrt(sum) -} - -function length(v) { - // length of vector - var sum = 0 - for (var i = 0; i < v.length; i++) { - sum += Math.pow(v[i], 2) - } - return Math.sqrt(sum) -} - -function degrees(rad){ - return rad * (180 / Math.PI) -} - -module.exports = { - distance: distance, - length: length, - degrees: degrees -} \ No newline at end of file diff --git a/lib/jsunit.js b/lib/jsunit.js deleted file mode 100644 index 084bc36..0000000 --- a/lib/jsunit.js +++ /dev/null @@ -1,128 +0,0 @@ -// event system to include type-checking etc -// dataflow types for javascript objects ... - -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) { - 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.onChange = function(item, fn) { - this.emitters[item] = fn - } - - state.emitChange = function(item) { - if (this.emitters[item] != null) { - this.emitters[item]() - } - } - - return state -} - -function isStateKey(key) { - if (key.indexOf('_') == 0 || key == 'emitters' || key == 'onChange' || key == 'emitChange') { - return false - } else { - return true - } -} - -// a coupl'a fancy UI state hooks -function Button(label, onClick) { - var button = { - type: 'button', - label: label, - onClick: onClick - } - - return button -} - -// now we're definitely writing a UI class -function MultiLine(label, rows) { - var ml = { - type: 'multiline', - label: label, - rows: rows, - value: '' - } - - return ml -} - -module.exports = { - Input: Input, - Output: Output, - State: State, - isStateKey: isStateKey, - Button: Button, - MultiLine: MultiLine -} \ No newline at end of file diff --git a/lib/packets.js b/lib/packets.js deleted file mode 100644 index ad63359..0000000 --- a/lib/packets.js +++ /dev/null @@ -1,24 +0,0 @@ -function pack32(val) { - var pack = new Array(); - pack[0] = (val >> 24) & 255; - pack[1] = (val >> 16) & 255; - pack[2] = (val >> 8) & 255; - pack[3] = val & 255; - - return pack; -} - -function unPack32(arr){ - if(arr.length == 4){ - var unPacked = arr[0] << 24 | arr[1] << 16 | arr[2] << 8 | arr[3] - return unPacked - } else { - console.log("ERR: arr > 4 at unPack32", arr) - } - -} - -module.exports = { - pack32: pack32, - unPack32: unPack32 -} \ No newline at end of file diff --git a/modules/hardware/atkbreadboardboard.js b/modules/hardware/atkbreadboardboard.js index 98bfd27..6a546c2 100644 --- a/modules/hardware/atkbreadboardboard.js +++ b/modules/hardware/atkbreadboardboard.js @@ -35,7 +35,7 @@ function ATKBreadBoardBoard() { state.servoButton = Button('SEND VALUE', onServoValChange) state.servoVal = 0 // 0->100 does 1 -> 2ms duty on 20ms period - state.onChange('servoVal', onServoValChange) + state.onUiChange('servoVal', onServoValChange) state.adcButton = Button('REQUEST ADC CONVERSION', onADCRequest) diff --git a/modules/hardware/atkmrobot.js b/modules/hardware/atkmrobot.js index 70cf5d7..f80497b 100644 --- a/modules/hardware/atkmrobot.js +++ b/modules/hardware/atkmrobot.js @@ -33,7 +33,7 @@ function ATKMathRobot() { state.message = 'no packet yet' state.pc_t = 2048 - state.onChange('pc_t', onPositionTargetUserChange) + state.onUiChange('pc_t', onPositionTargetUserChange) state.walk = 1024 state.tickButton = Button('Walk Value', onPositionTickTock) diff --git a/modules/hardware/atkseriallink.js b/modules/hardware/atkseriallink.js index 2c2e672..21f88b3 100644 --- a/modules/hardware/atkseriallink.js +++ b/modules/hardware/atkseriallink.js @@ -2,9 +2,11 @@ const JSUnit = require('../../src/jsunit.js') let Input = JSUnit.Input let Output = JSUnit.Output - let State = JSUnit.State -let Button = JSUnit.Button + +// interface elements +const JSUI = require('../../src/jsui.js') +let UI = JSUI.UI const SerialPort = require('serialport') @@ -23,9 +25,17 @@ function ATKSerialLink() { var state = atkSerialLink.state state.portName = '---' - state.connect = Button('click to find and connect', findSerialPort) state.portStatus = 'closed' // or we hope it will be + atkSerialLink.ui = UI() + var ui = atkSerialLink.ui + + ui.addElement('kickButton', './ui/uiButton.js', findSerialPort) + + ui.kickButton.onload = function(){ + ui.kickButton.setText('click to find and connect') + } + atkSerialLink.init = function(){ //findSerialPort() } diff --git a/modules/hardware/atkstepper.js b/modules/hardware/atkstepper.js index d819b34..c928b5f 100644 --- a/modules/hardware/atkstepper.js +++ b/modules/hardware/atkstepper.js @@ -4,7 +4,6 @@ let Input = JSUnit.Input let Output = JSUnit.Output let State = JSUnit.State -let Button = JSUnit.Button const MJS = require('mathjs') const DCRT = require('../../src/cartesian.js') @@ -36,7 +35,7 @@ function Stepper() { // for acceleration moves, in steps/s/s state.rate = 2000 - state.onChange('rate', () => { + state.onUiChange('rate', () => { if(state.rate > 2000){ state.rate = 2000 } else if (state.rate < 100){ @@ -48,7 +47,11 @@ function Stepper() { state.spu = 200 // steps per unit state.rawMove = -10 - state.makeMove = Button('test move', onRawMove) + var ui = stepper.ui + ui.addElement('rawButton', './ui/uiButton.js', onRawMove) + ui.rawButton.onload = function(){ + ui.rawButton.setText('click to send test move') + } state.lead = 0 state.position = 0 // in steps diff --git a/modules/hardware/webcam.js b/modules/hardware/webcam.js index 3ac82a7..87ed9c0 100644 --- a/modules/hardware/webcam.js +++ b/modules/hardware/webcam.js @@ -43,7 +43,7 @@ function WEBCAM() { var state = webcam.state state.button = Button('REQUEST IMAGE') - state.onChange('button', onButtonPress) + state.onUiChange('button', onButtonPress) state.counter = 0 webcam.inputs = { diff --git a/modules/motion/planner.js b/modules/motion/planner.js index 04e088a..dff61e2 100644 --- a/modules/motion/planner.js +++ b/modules/motion/planner.js @@ -24,7 +24,7 @@ function Planner() { var state = planner.state // reference pass attempt? state.axisIDs = 'X,Y,Z' - state.onChange('axisIDs', axisIDUpdate) + state.onUiChange('axisIDs', axisIDUpdate) state.reset = Button('reset planner', onPlannerReset) @@ -38,7 +38,7 @@ function Planner() { // should be grn / red button ... state.isRunning = 1 - state.onChange('isRunning', netStateRefresh) + state.onUiChange('isRunning', netStateRefresh) state.netWindow = 3 state.netState = [0, 0, 0] diff --git a/modules/ui/number.js b/modules/ui/number.js index c0c17a1..08302e1 100644 --- a/modules/ui/number.js +++ b/modules/ui/number.js @@ -25,7 +25,7 @@ function uiNum() { var state = uinum.state state.number = 10 - state.onChange('number', onNumberDesire) + state.onUiChange('number', onNumberDesire) state.button = Button('WHAM', onNumberDesire) diff --git a/modules/ui/stest.js b/modules/ui/stest.js index 657e257..4f43d49 100644 --- a/modules/ui/stest.js +++ b/modules/ui/stest.js @@ -50,6 +50,10 @@ function STest() { var ui = stest.ui ui.addElement('btnex', './ui/uiButton.js', onButtonData) + ui.btnex.onload = function(){ + console.log('ok, yes, loaded') + } + function onButtonData(evt){ console.log('on module callback', evt) ui.btnex.setText('hello from ss') diff --git a/modules/ui/terminal.js b/modules/ui/terminal.js index c153aa9..d6376c9 100644 --- a/modules/ui/terminal.js +++ b/modules/ui/terminal.js @@ -29,7 +29,7 @@ function Terminal() { // we'll occasionally want a hook here to do stuff when a state variable is changed // these will fire if we change them internally, or if they're changed from the ui - terminal.state.onChange('uiInput', function(){ + terminal.state.onUiChange('uiInput', function(){ terminal.outputs.lineOut.emit(terminal.state.uiInput) }) diff --git a/modules/util/delay.js b/modules/util/delay.js index b20c87c..6f45292 100644 --- a/modules/util/delay.js +++ b/modules/util/delay.js @@ -21,7 +21,7 @@ function Delay() { var state = delay.state state.ms = 100 - state.onChange('ms', onMsChange) + state.onUiChange('ms', onMsChange) delay.inputs = { thru: Input('any', onDelayBegin) // makes anything into '1' event diff --git a/programs.js b/programs.js index 97121d8..2478362 100644 --- a/programs.js +++ b/programs.js @@ -23,7 +23,15 @@ function loadModuleFromSource(program, path, id) { // source -> heap if (fs.existsSync(path)) { // compile a new object based on definition in path - var src = require(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 diff --git a/src/atkunit.js b/src/atkunit.js index 529bc8b..b3b355b 100644 --- a/src/atkunit.js +++ b/src/atkunit.js @@ -7,6 +7,10 @@ let Output = JSUnit.Output let State = JSUnit.State let Button = JSUnit.Button +// interface elements +const JSUI = require('./jsui.js') +let UI = JSUI.UI + let ATKRoute = require('./atkroute.js') function Hardware(){ @@ -22,13 +26,23 @@ function Hardware(){ hardware.state = State() var state = hardware.state - state.reset = Button('reset hardware', onReset) - - state.test = Button('test network', onNetworkTest) - state.message = 'click above to test network' + state.message = 'click below to test network' state.route = '0,0' // default - state.onChange('route', function(){ + hardware.ui = UI() + var ui = hardware.ui + + ui.addElement('resetButton', './ui/uiButton.js', onReset) + ui.resetButton.onload = function(){ + ui.resetButton.setText('reset hardware') + } + + ui.addElement('testButton', './ui/uiButton.js', onNetworkTest) + ui.testButton.onload = function(){ + ui.testButton.setText('test network') + } + + state.onUiChange('route', function(){ hardware.route.route = state.route }) diff --git a/src/jsunit.js b/src/jsunit.js index 90cbec4..f1e4f2d 100644 --- a/src/jsunit.js +++ b/src/jsunit.js @@ -77,7 +77,7 @@ function State() { state.socket = null // called when change from UI - state.onUIChange = function(item, fn) { + state.onUiChange = function(item, fn) { this.emitters[item] = fn } diff --git a/src/ui/uiButton.js b/src/ui/uiButton.js index b47a50d..576a3d5 100644 --- a/src/ui/uiButton.js +++ b/src/ui/uiButton.js @@ -7,17 +7,24 @@ function UIButton() { isPressed: false } + // hook to recv messages from the ui counterpart uiButton.onMessage = function(msg) { console.log('message into server side object', msg) - this.callback(msg) + if(msg == 'onload'){ + this.onload() + } else { + this.callback(msg) + } } + // example of a function to use within the module uiButton.setText = function(text) { // ex. of how to send data up to client var msg = { call: 'setText', argument: text } + // this.sendToUi is given to us during load this.sendToUi(msg) } -- GitLab