Mscript #2
|
@ -2497,8 +2497,6 @@ const mse = require('./lib/ui/mscript.js');
|
||||||
const Mscript = require('./lib/mscript');
|
const Mscript = require('./lib/mscript');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******
|
/******
|
||||||
State shared by ALL interfaces
|
State shared by ALL interfaces
|
||||||
*******/
|
*******/
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
# TODO - mscript
|
# TODO - mscript
|
||||||
|
|
||||||
* Add variables and simple evaluation
|
* Add variables and simple evaluation
|
||||||
* Add "Fade" feature
|
|
||||||
* Add "Light" feature
|
* Add "Light" feature
|
||||||
|
|
||||||
|
Bash-like variables?
|
||||||
|
Similar to LESS/SASS?
|
||||||
|
Makes a tokenization easier
|
||||||
|
|
||||||
|
@ is better than $
|
|
@ -23,6 +23,21 @@ const ALTS = {
|
||||||
'F ' : ['FADE']
|
'F ' : ['FADE']
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** helper functions */
|
||||||
|
|
||||||
|
/** startswith function from lodash, do not want the entire lib for this */
|
||||||
|
function startsWith(string, target, position) {
|
||||||
|
const { length } = string;
|
||||||
|
position = position == null ? 0 : position;
|
||||||
|
if (position < 0) {
|
||||||
|
position = 0;
|
||||||
|
} else if (position > length) {
|
||||||
|
position = length;
|
||||||
|
}
|
||||||
|
target = `${target}`;
|
||||||
|
return string.slice(position, position + target.length) == target;
|
||||||
|
}
|
||||||
|
|
||||||
/** class Mscript */
|
/** class Mscript */
|
||||||
class Mscript {
|
class Mscript {
|
||||||
constructor () {
|
constructor () {
|
||||||
|
@ -32,6 +47,8 @@ class Mscript {
|
||||||
* Clear the state of the script
|
* Clear the state of the script
|
||||||
*/
|
*/
|
||||||
clear () {
|
clear () {
|
||||||
|
this.lines = [];
|
||||||
|
|
||||||
this.cam = 0;
|
this.cam = 0;
|
||||||
this.proj = 0;
|
this.proj = 0;
|
||||||
this.color = '';
|
this.color = '';
|
||||||
|
@ -44,6 +61,8 @@ class Mscript {
|
||||||
this.target = 0; //move to target using CAM # or PROJ #
|
this.target = 0; //move to target using CAM # or PROJ #
|
||||||
this.dist = 0;
|
this.dist = 0;
|
||||||
|
|
||||||
|
this.variables = {};
|
||||||
|
|
||||||
this.output = {};
|
this.output = {};
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -59,30 +78,36 @@ class Mscript {
|
||||||
}
|
}
|
||||||
|
|
||||||
//split string into lines, each containing a command
|
//split string into lines, each containing a command
|
||||||
let lines = text.split('\n');
|
this.lines = text.split('\n');
|
||||||
|
|
||||||
for (let line of lines) {
|
this.lines = this.lines.map(line => {
|
||||||
line = line.replace(/\t+/g, ""); //strip tabs
|
line = line.replace(/\t+/g, ''); //strip tabs
|
||||||
line = line.trim(); //remove excess whitespace before and after command
|
line = line.trim(); //remove excess whitespace before and after command
|
||||||
line = line.toUpperCase();
|
line = line.toUpperCase();
|
||||||
|
return line;
|
||||||
|
})
|
||||||
|
|
||||||
|
for (let line of this.lines) {
|
||||||
this.two = line.substring(0, 2);
|
this.two = line.substring(0, 2);
|
||||||
if (CMD.indexOf(this.two) !== -1) {
|
if (CMD.indexOf(this.two) !== -1) {
|
||||||
this.basic_cmd(line);
|
this.basic_cmd(line);
|
||||||
} else if (line.substring(0, 4) === 'LOOP') {
|
} else if (startsWith(line, '@') || line.indexOf('@') !== -1) {
|
||||||
|
this.variable(line);
|
||||||
|
} else if (startsWith(line, 'LOOP')) {
|
||||||
this.new_loop(line);
|
this.new_loop(line);
|
||||||
} else if (line.substring(0, 2) === 'L ') {
|
} else if (startsWith(line, 'L ')) {
|
||||||
this.light_state(line);
|
this.light_state(line);
|
||||||
} else if (line.substring(0, 2) === 'F ') {
|
} else if (startsWith(line, 'F ')) {
|
||||||
this.new_loop(line, true);
|
this.new_loop(line, true);
|
||||||
} else if (line.substring(0, 3) === 'END') {
|
} else if (startsWith(line, 'END')) {
|
||||||
this.end_loop(line);
|
this.end_loop(line);
|
||||||
} else if (line.substring(0, 3) === 'CAM') { //directly go to that frame (black?)
|
} else if (startsWith(line, 'CAM')) { //directly go to that frame (black?)
|
||||||
this.move_cam(line);
|
this.move_cam(line);
|
||||||
} else if (line.substring(0, 4) === 'PROJ') { //directly go to that frame
|
} else if (startsWith(line, 'PROJ')) { //directly go to that frame
|
||||||
this.move_proj(line);
|
this.move_proj(line);
|
||||||
} else if (line.substring(0, 3) === 'SET') { //set that state
|
} else if (startsWith(line, 'SET')) { //set that state
|
||||||
this.set_state(line);
|
this.set_state(line);
|
||||||
} else if (line.substring(0, 1) === '#' || line.substring(0, 2) === '//') {
|
} else if (startsWith(line, '#') || startsWith(line, '//')) {
|
||||||
//comments
|
//comments
|
||||||
//ignore while parsing
|
//ignore while parsing
|
||||||
}
|
}
|
||||||
|
@ -98,6 +123,46 @@ class Mscript {
|
||||||
//should only be invoked by running mscript.tests()
|
//should only be invoked by running mscript.tests()
|
||||||
callback(this.output);
|
callback(this.output);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
variable (line) {
|
||||||
|
let parts = line.split('=');
|
||||||
|
let key = parts[0];
|
||||||
|
let value = parts[1];
|
||||||
|
let update = false;
|
||||||
|
|
||||||
|
if (value && value.indexOf('#') !== -1) {
|
||||||
|
value = value.split('#')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value && value.indexOf('//') !== -1) {
|
||||||
|
value = value.split('//')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value && value.indexOf('+') !== -1) {
|
||||||
|
if (value)
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.indexOf('-') !== -1) {
|
||||||
|
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.indexOf(',') === -1) { //if not color string
|
||||||
|
try {
|
||||||
|
value = parseInt(value);
|
||||||
|
} catch (err) {
|
||||||
|
//supress parsing error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//console.dir(parts)
|
||||||
|
if (!this.variables[key] || update) {
|
||||||
|
this.variables[key] = value;
|
||||||
|
}
|
||||||
|
console.dir(this.variables)
|
||||||
|
}
|
||||||
|
variable_replace(line) {
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Apply a basic two character command
|
* Apply a basic two character command
|
||||||
|
@ -252,9 +317,9 @@ class Mscript {
|
||||||
* Set the state of either the cam or projector
|
* Set the state of either the cam or projector
|
||||||
*/
|
*/
|
||||||
set_state (line) {
|
set_state (line) {
|
||||||
if (line.substring(0, 7) === 'SET CAM') {
|
if (startsWith(line, 'SET CAM')) {
|
||||||
this.cam = parseInt(line.split('SET CAM')[1]);
|
this.cam = parseInt(line.split('SET CAM')[1]);
|
||||||
} else if (line.substring(0, 8) === 'SET PROJ') {
|
} else if (startsWith(line, 'SET PROJ')) {
|
||||||
this.proj = parseInt(line.split('SET PROJ')[1]);
|
this.proj = parseInt(line.split('SET PROJ')[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,7 +531,7 @@ END LOOP - (or END) closes loop
|
||||||
|
|
||||||
L #RGB - sets light to rgb value
|
L #RGB - sets light to rgb value
|
||||||
|
|
||||||
FADE
|
FADE 24 0,0,0 255,255,255
|
||||||
|
|
||||||
CF - Camera forwards
|
CF - Camera forwards
|
||||||
PF - Projector forwards
|
PF - Projector forwards
|
||||||
|
|
|
@ -47,7 +47,19 @@ mse.mscript.fromSequence = function () {
|
||||||
tmp = tmp.map(line => {
|
tmp = tmp.map(line => {
|
||||||
return `${line.cmd} ${line.num}`
|
return `${line.cmd} ${line.num}`
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (mcopy.loop > 1) {
|
||||||
|
tmp.map(line => {
|
||||||
|
return ` ${line}`;
|
||||||
|
})
|
||||||
|
tmp.reverse();
|
||||||
|
tmp.push(`LOOP ${mcopy.loop}`);
|
||||||
|
tmp.reverse();
|
||||||
|
tmp.push('END');
|
||||||
|
}
|
||||||
|
|
||||||
str = tmp.join('\n');
|
str = tmp.join('\n');
|
||||||
|
|
||||||
nav.change('script');
|
nav.change('script');
|
||||||
cont = confirm(`Are you sure you want to over-write the current sequence?`);
|
cont = confirm(`Are you sure you want to over-write the current sequence?`);
|
||||||
if (cont) {
|
if (cont) {
|
||||||
|
|
|
@ -23,8 +23,6 @@ const mse = require('./lib/ui/mscript.js');
|
||||||
const Mscript = require('./lib/mscript');
|
const Mscript = require('./lib/mscript');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******
|
/******
|
||||||
State shared by ALL interfaces
|
State shared by ALL interfaces
|
||||||
*******/
|
*******/
|
||||||
|
|
|
@ -6,18 +6,15 @@ const mscript = new Mscript();
|
||||||
QUnit.test(`Basic functions`, (assert) => {
|
QUnit.test(`Basic functions`, (assert) => {
|
||||||
const script1 = 'CF\nPF\nCB\nPB\nBF\nBB';
|
const script1 = 'CF\nPF\nCB\nPB\nBF\nBB';
|
||||||
const script2 = `CF 3\nPF 3`
|
const script2 = `CF 3\nPF 3`
|
||||||
assert.expect( 2 );
|
assert.expect( 5 );
|
||||||
|
|
||||||
mscript.interpret(script1, (obj) => {
|
mscript.interpret(script1, (obj) => {
|
||||||
let pass = false;
|
assert.ok(obj.success, `Simple script1 compiles`)
|
||||||
if (obj.success === true
|
assert.equal(obj.cam, 0, 'Camera gets equaled out');
|
||||||
&& obj.cam === 0
|
assert.equal(obj.proj, 0, 'Projector gets cancelled out');
|
||||||
&& obj.proj === 0
|
assert.equal(obj.arr.length, 6, 'Generate sequence of 6 steps');
|
||||||
&& obj.arr.length === 6) {
|
|
||||||
pass = true;
|
|
||||||
}
|
|
||||||
assert.ok(pass, `Simple script1 compiles`)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
mscript.interpret(script2, (obj) => {
|
mscript.interpret(script2, (obj) => {
|
||||||
let pass = false;
|
let pass = false;
|
||||||
if (obj.success === true
|
if (obj.success === true
|
||||||
|
@ -149,3 +146,53 @@ QUnit.test('Light', (assert) => {
|
||||||
assert.ok(pass, 'Basic light');
|
assert.ok(pass, 'Basic light');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('Fade', (assert) => {
|
||||||
|
assert.expect(13);
|
||||||
|
const script1 =
|
||||||
|
`F 72 0,0,0 10,20,30
|
||||||
|
CF
|
||||||
|
END
|
||||||
|
PF 10`
|
||||||
|
mscript.interpret(script1, (obj) => {
|
||||||
|
//console.dir(obj)
|
||||||
|
assert.ok(obj.success, 'Basic fade compiles');
|
||||||
|
assert.equal(obj.cam, 72, `Camera moves forward 72 frames`);
|
||||||
|
assert.equal(obj.proj, 10, 'Projector moves forward 10 frames');
|
||||||
|
assert.equal(obj.arr.length, 82, 'Generates 82 steps');
|
||||||
|
assert.equal(obj.light[0], '0,0,0', 'Fade starts with starting color');
|
||||||
|
assert.equal(obj.light[71], '10,20,30', 'Fade ends with ending color');
|
||||||
|
assert.equal(obj.light[72], '', 'Frame after fade is default color');
|
||||||
|
});
|
||||||
|
|
||||||
|
const script2 =
|
||||||
|
`
|
||||||
|
F 24 25,255,125 225,125,10
|
||||||
|
CF
|
||||||
|
END
|
||||||
|
L 225,125,10
|
||||||
|
CF 10`
|
||||||
|
mscript.interpret(script2, (obj) => {
|
||||||
|
//console.dir(obj)
|
||||||
|
assert.ok(obj.success, 'Mscript labeled output success');
|
||||||
|
assert.equal(obj.cam, 34, 'There are 34 camera frames');
|
||||||
|
assert.equal(obj.arr.length, 34, 'There are 34 steps in the script');
|
||||||
|
assert.equal(obj.light[0], '25,255,125', 'First frame is equal to start color');
|
||||||
|
assert.equal(obj.light[23], '225,125,10', 'Last frame in fade is equal to end color');
|
||||||
|
assert.equal(obj.light[24], '225,125,10', 'First frame after fade is set using Light command');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
QUnit.test('Variables', (assert) => {
|
||||||
|
const script1 =
|
||||||
|
`@LIGHT=200,200,200
|
||||||
|
@COUNT=1
|
||||||
|
CF 20
|
||||||
|
PF
|
||||||
|
@COUNT++
|
||||||
|
`
|
||||||
|
mscript.interpret(script1, obj => {
|
||||||
|
//console.dir(obj)
|
||||||
|
assert.ok(true)
|
||||||
|
})
|
||||||
|
})
|
|
@ -31,7 +31,7 @@ boolean cam_dir = true;
|
||||||
const int PROJECTOR = 8;
|
const int PROJECTOR = 8;
|
||||||
const int PROJECTOR_FWD = 9;
|
const int PROJECTOR_FWD = 9;
|
||||||
const int PROJECTOR_BWD = 10;
|
const int PROJECTOR_BWD = 10;
|
||||||
const int PROJECTOR_MOMENT = 240;
|
const int PROJECTOR_MOMENT = 200;
|
||||||
const int PROJECTOR_FRAME = 950;
|
const int PROJECTOR_FRAME = 950;
|
||||||
//PROJECTOR VARIABLES
|
//PROJECTOR VARIABLES
|
||||||
boolean proj_dir = true;
|
boolean proj_dir = true;
|
||||||
|
|
Loading…
Reference in New Issue