diff --git a/README.md b/README.md index 8cccc6cc0b286689e3e2bd62cb215a63542bd1b3..5530f1ebd53484843274f064cc899ba376149fe9 100644 --- a/README.md +++ b/README.md @@ -127,17 +127,95 @@ To disconnect, click the output to disconnect, and then the input to disconnect # RuNDMC Architecture + +Above is a somewhat-complete representation of what-all is going on in software. + +Essentially, we load tiny programs (```modules/sub/modulename.js```) using node.js's *require* function. These programs each have inputs and outputs, and some state. Each also has a description (an example of a complete module is below). + +The UI serves a representation of this through a websocket. + +Pardon my at-the-moment brief explanation. # Writing New Modules - - whenever a menu is requested, the system searches ```modules/ * ``` for *anything*. include your .js of a new module there - - anything goes: you can run whatever code will run in node.js ... just follow these simple rules - - TODO: put example here, with comments +Whenever a menu is requested, the system searches ```modules/ * ``` for *anything*. include your .js of a new module there. + +These modules are written with objects inherited from ```lib/jsunit.js``` + +Here's an example. This is modules/ui/number.js. + +Besides Inputs, Outputs, a Description and State object, anything else goes. I.E. local functions, other Node.JS packages, etc. + +```JavaScript +// boilerplate rndmc header +const InOut = require('../../lib/jsunit.js') +let Input = InOut.Input +let Output = InOut.Output +let State = InOut.State +let Button = InOut.Button + +// a constructor, a fn, a javascript mess +function uiNum() { + + // this is the tiny program-as-and-object that we'll load into rundmc + // description / name is required to load successfully + var uinum = { + description: { + name: 'number-output', + alt: 'for clicking' + } + } + + // the State() object is what the system scrapes for ui variables / updates from the UI + // this includes things like Button('title', callback), which are unique state variables + // they can also be found in jsunit.js + uinum.state = State() + // alias ! + var state = uinum.state + + state.number = 10 + state.onChange('number', onNumberDesire) + + state.button = Button('WHAM', onNumberDesire) + + // inputs are required, and must be Input('type', callback) + uinum.inputs = { + thru: Input('any', onThruInput), // makes anything into num event + evt: Input('any', onNumberDesire) + } + + // outputs: Output('type') + uinum.outputs = { + out: Output('number') + } + + // here's our input callback, specified in the input constructor + function onThruInput(input){ + if(typeof input == 'number'){ + state.number = input + } else { + state.number = parseFloat(input) + } + onNumberDesire() + } + + function onNumberDesire(){ + // here's how we fire an output. + uinum.outputs.out.emit(state.number) + } + + // gotta give the program this thing we made + return uinum +} + +// this for node.js's require() function +module.exports = uiNum +``` # Writing Hardware Modules - - TODO: same, also including links / explanation to atk +Hardware Modules are identical to other modules, but they inherit a class that can be found and examined at ```lib/atkunit.js``` which subsequently calls hardware-interfacing classes from ```lib/atkroute.js``` and often use tools from ```lib/packets.js``` (packets.js is mostly about packing 64-bit information into byte-size units). # Development Notes diff --git a/doc/images/rndmc-architecture.png b/doc/images/rndmc-architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..45a0179f37cb2d226b6e455b4ce625c024954d1e Binary files /dev/null and b/doc/images/rndmc-architecture.png differ diff --git a/modules/ui/number.js b/modules/ui/number.js index 467d231b46c06e9819b18978543152bde87bbffa..bff0d2b803f7c2679e24b65c121afdfef1367de7 100644 --- a/modules/ui/number.js +++ b/modules/ui/number.js @@ -1,4 +1,4 @@ -// boilerplate atkapi header +// boilerplate rndmc header const InOut = require('../../lib/jsunit.js') let Input = InOut.Input let Output = InOut.Output @@ -8,14 +8,18 @@ let Button = InOut.Button // a constructor, a fn, a javascript mess function uiNum() { + // this is the tiny program-as-and-object that we'll load into rundmc + // description / name is required to load successfully var uinum = { - // descriptions are used in UI description: { - name: 'number output', + name: 'number-output', alt: 'for clicking' } } + // the State() object is what the system scrapes for ui variables / updates from the UI + // this includes things like Button('title', callback), which are unique state variables + // they can also be found in jsunit.js uinum.state = State() // alias ! var state = uinum.state @@ -25,15 +29,18 @@ function uiNum() { state.button = Button('WHAM', onNumberDesire) + // inputs are required, and must be Input('type', callback) uinum.inputs = { thru: Input('any', onThruInput), // makes anything into num event evt: Input('any', onNumberDesire) } + // outputs: Output('type') uinum.outputs = { out: Output('number') } + // here's our input callback, specified in the input constructor function onThruInput(input){ if(typeof input == 'number'){ state.number = input @@ -44,11 +51,13 @@ function uiNum() { } function onNumberDesire(){ + // here's how we fire an output. uinum.outputs.out.emit(state.number) } + // gotta give the program this thing we made return uinum } -// exports +// this for node.js's require() function module.exports = uiNum \ No newline at end of file