mirror of
https://github.com/sexybiggetje/pixdisp.git
synced 2024-12-04 19:21:03 +01:00
Add preliminary support for writing sandboxed javascript for animation purposes. Renders a single frame now.
This commit is contained in:
parent
485c34bbdc
commit
b755b5dbb3
8 changed files with 117 additions and 14 deletions
|
@ -2,15 +2,19 @@
|
||||||
|
|
||||||
class ApiController {
|
class ApiController {
|
||||||
|
|
||||||
constructor( server, driver ) {
|
constructor( server, driver, vmcontroller ) {
|
||||||
|
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.driver = driver;
|
this.driver = driver;
|
||||||
|
this.vmcontroller = vmcontroller;
|
||||||
|
|
||||||
this.server.post( { path: '/api/writecanvas' }, this.writeCanvas.bind( this ) );
|
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/write' }, this.write.bind( this ) );
|
||||||
this.server.get( { path: '/api/getdisplaysize' }, this.getDisplaySize.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/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();
|
this.driver.clearMatrix();
|
||||||
|
|
||||||
resource.setHeader( 'Access-Control-Allow-Origin', '*' );
|
|
||||||
|
|
||||||
let data = JSON.parse( request.params.data );
|
let data = JSON.parse( request.params.data );
|
||||||
|
|
||||||
for ( let obj of data) {
|
for ( let obj of data) {
|
||||||
|
@ -36,8 +38,6 @@ class ApiController {
|
||||||
|
|
||||||
write( request, resource, next ) {
|
write( request, resource, next ) {
|
||||||
|
|
||||||
resource.setHeader( 'Access-Control-Allow-Origin', '*' );
|
|
||||||
|
|
||||||
let buffer = this.driver.getBuffer();
|
let buffer = this.driver.getBuffer();
|
||||||
this.driver.write( buffer );
|
this.driver.write( buffer );
|
||||||
|
|
||||||
|
@ -48,8 +48,6 @@ class ApiController {
|
||||||
|
|
||||||
getDisplaySize( request, resource, next ) {
|
getDisplaySize( request, resource, next ) {
|
||||||
|
|
||||||
resource.setHeader( 'Access-Control-Allow-Origin', '*' );
|
|
||||||
|
|
||||||
resource.json( 200, this.driver.getSize() );
|
resource.json( 200, this.driver.getSize() );
|
||||||
return next();
|
return next();
|
||||||
|
|
||||||
|
@ -57,8 +55,6 @@ class ApiController {
|
||||||
|
|
||||||
setPixel( request, resource, next ) {
|
setPixel( request, resource, next ) {
|
||||||
|
|
||||||
resource.setHeader( 'Access-Control-Allow-Origin', '*' );
|
|
||||||
|
|
||||||
this.driver.setPixel(
|
this.driver.setPixel(
|
||||||
request.params.x,
|
request.params.x,
|
||||||
request.params.y,
|
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;
|
exports.ApiController = ApiController;
|
75
controllers/vmcontroller.js
Normal file
75
controllers/vmcontroller.js
Normal file
|
@ -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;
|
|
@ -202,7 +202,7 @@ class Driver {
|
||||||
/**
|
/**
|
||||||
* Write output to the device. Implement at driver level.
|
* 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' );
|
console.log( 'Driver should implement this' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ class Dummy extends Driver {
|
||||||
this.silence = false;
|
this.silence = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
write( buffer ) {
|
write( buffer = false ) {
|
||||||
if ( this.silence !== true ) {
|
if ( this.silence !== true ) {
|
||||||
console.log( buffer );
|
console.log( buffer );
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ class PimoroniUnicorn extends Driver {
|
||||||
this.spi = false;
|
this.spi = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
write( buffer ) {
|
write( buffer = false ) {
|
||||||
if ( this.spi === false) {
|
if ( this.spi === false) {
|
||||||
if ( fs.existsSync( '/dev/spidev0.0' ) ) {
|
if ( fs.existsSync( '/dev/spidev0.0' ) ) {
|
||||||
let SPI = require( 'pi-spi' );
|
let SPI = require( 'pi-spi' );
|
||||||
|
@ -22,6 +22,10 @@ class PimoroniUnicorn extends Driver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( buffer === false ) {
|
||||||
|
buffer = this.getBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
this.spi.write(
|
this.spi.write(
|
||||||
Buffer.concat(
|
Buffer.concat(
|
||||||
[
|
[
|
||||||
|
|
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -5385,6 +5385,11 @@
|
||||||
"extsprintf": "1.3.0"
|
"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": {
|
"walker": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pi-spi": "^1.0.2",
|
"pi-spi": "^1.0.2",
|
||||||
"restify": "^6.3.4"
|
"restify": "^6.3.4",
|
||||||
|
"vm2": "^3.5.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^4.15.0",
|
"eslint": "^4.15.0",
|
||||||
|
|
|
@ -4,6 +4,7 @@ let fs = require( 'fs' );
|
||||||
let os = require( 'os' );
|
let os = require( 'os' );
|
||||||
|
|
||||||
let config,
|
let config,
|
||||||
|
vmcontroller,
|
||||||
api,
|
api,
|
||||||
contents;
|
contents;
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ let driver;
|
||||||
let { DriverFactory } = require( './drivers/driverfactory' );
|
let { DriverFactory } = require( './drivers/driverfactory' );
|
||||||
let driverFactory = new DriverFactory();
|
let driverFactory = new DriverFactory();
|
||||||
|
|
||||||
|
let { VMController } = require( './controllers/vmcontroller' );
|
||||||
let { ApiController } = require( './controllers/apicontroller' );
|
let { ApiController } = require( './controllers/apicontroller' );
|
||||||
|
|
||||||
let restify = require( 'restify' );
|
let restify = require( 'restify' );
|
||||||
|
@ -57,7 +59,8 @@ server.use( restify.plugins.throttle(
|
||||||
driver = driverFactory.createFromConfig( config );
|
driver = driverFactory.createFromConfig( config );
|
||||||
driver.write( driver.getBuffer() );
|
driver.write( driver.getBuffer() );
|
||||||
|
|
||||||
api = new ApiController( server, driver );
|
vmcontroller = new VMController( driver );
|
||||||
|
api = new ApiController( server, driver, vmcontroller );
|
||||||
|
|
||||||
server.get(/.*/, restify.plugins.serveStatic({
|
server.get(/.*/, restify.plugins.serveStatic({
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue