diff --git a/controllers/apicontroller.js b/controllers/apicontroller.js index 63add59..b2138a7 100644 --- a/controllers/apicontroller.js +++ b/controllers/apicontroller.js @@ -2,15 +2,19 @@ class ApiController { - constructor( server, driver ) { + constructor( server, driver, vmcontroller ) { this.server = server; this.driver = driver; + this.vmcontroller = vmcontroller; this.server.post( { path: '/api/writecanvas' }, this.writeCanvas.bind( this ) ); + this.server.post( { path: '/api/runcode' }, this.runCode.bind( this ) ); + this.server.get( { path: '/api/write' }, this.write.bind( this ) ); this.server.get( { path: '/api/getdisplaysize' }, this.getDisplaySize.bind( this ) ); this.server.get( { path: '/api/setpixel/:x/:y/:r/:g/:b' }, this.setPixel.bind( this ) ); + this.server.get( { path: '/api/getcode' }, this.getCode.bind( this ) ); } @@ -18,8 +22,6 @@ class ApiController { this.driver.clearMatrix(); - resource.setHeader( 'Access-Control-Allow-Origin', '*' ); - let data = JSON.parse( request.params.data ); for ( let obj of data) { @@ -36,8 +38,6 @@ class ApiController { write( request, resource, next ) { - resource.setHeader( 'Access-Control-Allow-Origin', '*' ); - let buffer = this.driver.getBuffer(); this.driver.write( buffer ); @@ -48,8 +48,6 @@ class ApiController { getDisplaySize( request, resource, next ) { - resource.setHeader( 'Access-Control-Allow-Origin', '*' ); - resource.json( 200, this.driver.getSize() ); return next(); @@ -57,8 +55,6 @@ class ApiController { setPixel( request, resource, next ) { - resource.setHeader( 'Access-Control-Allow-Origin', '*' ); - this.driver.setPixel( request.params.x, request.params.y, @@ -72,6 +68,25 @@ class ApiController { } + getCode( request, resource, next ) { + + resource.send( this.vmcontroller.runningCode ); + return next(); + + } + + runCode( request, resource, next ) { + + this.runningCode = request.params.code; + + this.vmcontroller.compileScript( this.runningCode ); + this.vmcontroller.runScript(); + + resource.json( 200, { 'msg': 'Ok' } ); + return next(); + + } + } exports.ApiController = ApiController; \ No newline at end of file diff --git a/controllers/vmcontroller.js b/controllers/vmcontroller.js new file mode 100644 index 0000000..d1cc134 --- /dev/null +++ b/controllers/vmcontroller.js @@ -0,0 +1,75 @@ +'use strict'; + +class VMController +{ + constructor( driver ) { + + this.driver = driver; + this.runningCode = ';'; + this.runningVmScript = false; + this.previousTime = 0; + this.delta = 0; + this.sandbox = {}; + this.vm = null; + + } + + getRunningCode() { + return this.runningCode; + } + + compileScript( script ) { + + let { NodeVM, VMScript } = require( 'vm2' ); + + this.resetSandbox(); + this.runningCode = script; + this.vm = new NodeVM( { + 'console': 'inherit', + 'sandbox': this.sandbox + } ); + + this.runningVmScript = new VMScript( this.runningCode ); + + } + + resetSandbox() { + this.sandbox = { + 'matrix': this.driver, + 'delta': this.getDelta.bind( this ) + }; + } + + runScript( ) { + + let delta = 0; + let tmd = this.getTimeData(); + + if ( this.previousTime === 0 ) { + this.previousTime = tmd; + } else { + delta = tmd - this.previousTime; + this.previousTime = tmd; + } + + this.delta = delta; + + this.vm.run( this.runningVmScript, 'pixdisp-sandbox.js' ); + + } + + getTimeData() { + let hrTime = process.hrtime(); + return hrTime[ 0 ] * 1000000 + hrTime[ 1 ] / 1000; + } + + getDriver() { + return this.driver; + } + + getDelta() { + return this.delta; + } +} + +exports.VMController = VMController; \ No newline at end of file diff --git a/drivers/driver.js b/drivers/driver.js index fd4cabe..cf5b7e9 100644 --- a/drivers/driver.js +++ b/drivers/driver.js @@ -202,7 +202,7 @@ class Driver { /** * Write output to the device. Implement at driver level. */ - write( buffer ) { //eslint-disable-line no-unused-vars + write( buffer = false ) { //eslint-disable-line no-unused-vars console.log( 'Driver should implement this' ); } diff --git a/drivers/dummy.js b/drivers/dummy.js index bdfeb1e..16b37e6 100644 --- a/drivers/dummy.js +++ b/drivers/dummy.js @@ -9,7 +9,7 @@ class Dummy extends Driver { this.silence = false; } - write( buffer ) { + write( buffer = false ) { if ( this.silence !== true ) { console.log( buffer ); } diff --git a/drivers/pimoroniunicorn.js b/drivers/pimoroniunicorn.js index 7ab2c78..61b5415 100644 --- a/drivers/pimoroniunicorn.js +++ b/drivers/pimoroniunicorn.js @@ -11,7 +11,7 @@ class PimoroniUnicorn extends Driver { this.spi = false; } - write( buffer ) { + write( buffer = false ) { if ( this.spi === false) { if ( fs.existsSync( '/dev/spidev0.0' ) ) { let SPI = require( 'pi-spi' ); @@ -22,6 +22,10 @@ class PimoroniUnicorn extends Driver { } } + if ( buffer === false ) { + buffer = this.getBuffer(); + } + this.spi.write( Buffer.concat( [ diff --git a/package-lock.json b/package-lock.json index 2cdd8e1..60ff537 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5385,6 +5385,11 @@ "extsprintf": "1.3.0" } }, + "vm2": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.5.2.tgz", + "integrity": "sha512-imsgTODim0/3fSDA0g4SeYBF9oAuJnYXpILnA6GJ7rglNPLOv1s+CfgE7pqzOHFEKrJsogIxupE5fW2DI65rIg==" + }, "walker": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", diff --git a/package.json b/package.json index 948ea95..20bcd96 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "license": "MIT", "dependencies": { "pi-spi": "^1.0.2", - "restify": "^6.3.4" + "restify": "^6.3.4", + "vm2": "^3.5.2" }, "devDependencies": { "eslint": "^4.15.0", diff --git a/pixdisp.js b/pixdisp.js index 7f7722e..8885814 100644 --- a/pixdisp.js +++ b/pixdisp.js @@ -4,6 +4,7 @@ let fs = require( 'fs' ); let os = require( 'os' ); let config, + vmcontroller, api, contents; @@ -29,6 +30,7 @@ let driver; let { DriverFactory } = require( './drivers/driverfactory' ); let driverFactory = new DriverFactory(); +let { VMController } = require( './controllers/vmcontroller' ); let { ApiController } = require( './controllers/apicontroller' ); let restify = require( 'restify' ); @@ -57,7 +59,8 @@ server.use( restify.plugins.throttle( driver = driverFactory.createFromConfig( config ); driver.write( driver.getBuffer() ); -api = new ApiController( server, driver ); +vmcontroller = new VMController( driver ); +api = new ApiController( server, driver, vmcontroller ); server.get(/.*/, restify.plugins.serveStatic({