Mscript update #1

Merged
sixteenmillimeter merged 21 commits from mscript into master 2018-06-17 03:25:21 +00:00
1 changed files with 296 additions and 411 deletions
Showing only changes of commit 5f736c0af4 - Show all commits

View File

@ -2,49 +2,8 @@
/** @module lib/mscript */ /** @module lib/mscript */
let fs; const BLACK = '0,0,0';
let input; const CMD = [
/** object mscript */
const mscript = {};
/**
* Check for the presence of specific arguments in process
* argv
*
* @param {string} shrt Short version of argument or flag
* @param {string} lng Long version of argument or flag
*
* @return {boolean} Is flag present
*/
mscript.arg = function arg (shrt, lng) {
if (process.argv.indexOf(shrt) !== -1 ||
process.argv.indexOf(lng) !== -1) {
return true;
}
return false;
};
/**
* Check for the position of specific arguments in process
* argv
*
* @param {string} shrt Short version of argument or flag
* @param {string} lng Long version of argument or flag
*
* @return {boolean} Position of arg or flag, for locating input
*/
mscript.arg_pos = function arg_pos (shrt, lng) {
var pos = -1;
pos = process.argv.indexOf(shrt);
if (pos === -1) {
pos = process.argv.indexOf(lng);
}
return pos;
};
mscript.black = '0,0,0';
mscript.cmd = [
'CF', 'CF',
'PF', 'PF',
'BF', 'BF',
@ -52,10 +11,10 @@ mscript.cmd = [
'PB', 'PB',
'BB' 'BB'
]; ];
mscript.alts = { const ALTS = {
'CF' : ['CAMERA FORWARD', 'CAM FORWARD'], 'CF' : ['CAMERA FORWARD', 'CAM FORWARD'],
'PF' : ['PROJECTOR FORWARD', 'PROJ FORWARD'], 'PF' : ['PROJECTOR FORWARD', 'PROJ FORWARD'],
'BF': ['BLACK FORWARD', 'BLACK', 'BLANK FORWARD', 'BLANK'], 'BF' : ['BLACK FORWARD', 'BLACK', 'BLANK FORWARD', 'BLANK'],
'CB' : ['CAMERA BACKWARD', 'CAM BACKWARD', 'CAMERA BACK', 'CAM BACK'], 'CB' : ['CAMERA BACKWARD', 'CAM BACKWARD', 'CAMERA BACK', 'CAM BACK'],
'PB' : ['PROJECTOR FORWARD', 'PROJ FORWARD', 'PROJECTOR BACK', 'PROJ BACK'], 'PB' : ['PROJECTOR FORWARD', 'PROJ FORWARD', 'PROJECTOR BACK', 'PROJ BACK'],
'BB' : ['BLACK BACKWARD', 'BLACK BACK', 'BLANK BACK'], 'BB' : ['BLACK BACKWARD', 'BLACK BACK', 'BLANK BACK'],
@ -63,290 +22,282 @@ mscript.alts = {
'F ' : ['FADE'] 'F ' : ['FADE']
}; };
mscript.state = {}; class Mscript {
constructor () {
this.output = {};
}
/** /**
* Clear the state object * Clear the state of the script
*/ */
mscript.state_clear = function state_clear () { clear () {
mscript.state = { this.cam = 0;
cam : 0, this.proj = 0;
proj : 0, this.color = '';
color : '', this.loops = [];
loops : [], this.rec = -1;
rec : -1 this.output = {};
};
};
/**
*
*/
mscript.alts_unique = function alts_unique () {
var ids = Object.keys(mscript.alts),
all = [];
for (var i = 0; i < ids.length; i++) {
if (all.indexOf(ids[i]) === -1) {
all.push(ids[i]);
} else {
mscript.fail("Can't compile");
} }
} /**
}; * Main function, accepts multi-line string, parses into lines
/** * and interprets the instructions from the text. Returns an array
* * of steps to be fed into the mcopy.
*/ */
mscript.interpret = function interpret (text, callback) { interpret (text, callback) {
mscript.state_clear(); this.clear()
if (typeof text === 'undefined') { if (typeof text === 'undefined') {
mscript.fail('No input'); return this.fail('No input');
} }
var lines = text.split('\n'),
two = '',
arr = [],
light = [],
target = 0,
dist = 0, //?
output = {};
for (var i = 0; i < lines.length; i++) {
lines[i] = lines[i].replace(/\t+/g, ""); //strip tabs
lines[i] = lines[i].trim(); //remove excess whitespace before and after command
two = lines[i].substring(0, 2);
if (mscript.cmd.indexOf(two) !== -1) {
if (mscript.state.loops.length > 0) { //split string into lines, each containing a command
let lines = text.split('\n');
let two = '';
let arr = [];
let light = [];
let target = 0;// move to target using CAM # or PROJ #
let dist = 0; //?
for (let line of lines) {
line = line.replace(/\t+/g, ""); //strip tabs
line = line.trim(); //remove excess whitespace before and after command
two = line.substring(0, 2);
if (CMD.indexOf(two) !== -1) {
if (this.loops.length > 0) {
//hold generated arr in state loop array //hold generated arr in state loop array
mscript.state.loops[mscript.state.rec].arr this.loops[this.rec].arr
.push.apply(mscript.state.loops[mscript.state.rec].arr, .push.apply(this.loops[this.rec].arr,
mscript.str_to_arr(lines[i], this.str_to_arr(line,
two)); two));
mscript.state.loops[mscript.state.rec].light this.loops[this.rec].light
.push.apply(mscript.state.loops[mscript.state.rec].light, .push.apply(this.loops[this.rec].light,
mscript.light_to_arr(lines[i], this.light_to_arr(line,
two)); two));
} else { } else {
arr.push.apply(arr, mscript.str_to_arr(lines[i], two)); arr.push.apply(arr, this.str_to_arr(line, two));
light.push.apply(light, mscript.light_to_arr(lines[i], two)) light.push.apply(light, this.light_to_arr(line, two))
} }
} else if (lines[i].substring(0, 4) === 'LOOP') { } else if (line.substring(0, 4) === 'LOOP') {
mscript.state.rec++; this.rec++;
mscript.state.loops[mscript.state.rec] = { this.loops[this.rec] = {
arr : [], arr : [],
light : [], light : [],
cam : 0, cam : 0,
proj : 0, proj : 0,
cmd : lines[i] + '' cmd : line + ''
}; };
} else if (lines[i].substring(0, 2) === 'L ') { } else if (line.substring(0, 2) === 'L ') {
mscript.light_state(lines[i]); this.light_state(line);
} else if (lines[i].substring(0, 3) === 'END') { } else if (line.substring(0, 3) === 'END') {
for (var x = 0; x < mscript.loop_count(mscript.state.loops[mscript.state.rec].cmd); x++) { for (var x = 0; x < this.loop_count(this.loops[this.rec].cmd); x++) {
if (mscript.state.rec === 0) { if (this.rec === 0) {
arr.push.apply(arr, mscript.state.loops[mscript.state.rec].arr); arr.push.apply(arr, this.loops[this.rec].arr);
light.push.apply(light, mscript.state.loops[mscript.state.rec].light); light.push.apply(light, this.loops[this.rec].light);
} else if (mscript.state.rec >= 1) { } else if (this.rec >= 1) {
mscript.state.loops[mscript.state.rec - 1].arr this.loops[this.rec - 1].arr
.push.apply(mscript.state.loops[mscript.state.rec - 1].arr, .push.apply(this.loops[this.rec - 1].arr,
mscript.state.loops[mscript.state.rec].arr); this.loops[this.rec].arr);
mscript.state.loops[mscript.state.rec - 1].light this.loops[this.rec - 1].light
.push.apply(mscript.state.loops[mscript.state.rec - 1].light, .push.apply(this.loops[this.rec - 1].light,
mscript.state.loops[mscript.state.rec].light); this.loops[this.rec].light);
} }
} }
mscript.state_update('END', mscript.loop_count(mscript.state.loops[mscript.state.rec].cmd)); this.update('END', this.loop_count(this.loops[this.rec].cmd));
delete mscript.state.loops[mscript.state.rec]; delete this.loops[this.rec];
mscript.state.rec--; this.rec--;
} else if (lines[i].substring(0, 3) === 'CAM') { //directly go to that frame (black?) } else if (line.substring(0, 3) === 'CAM') { //directly go to that frame (black?)
target = parseInt(lines[i].split('CAM ')[1]); target = parseInt(line.split('CAM ')[1]);
if (mscript.state.loops.length > 0) { if (this.loops.length > 0) {
if (target > mscript.state.cam) { if (target > this.cam) {
dist = target - mscript.state.cam; dist = target - this.cam;
for (var x = 0; x < dist; x++) { for (var x = 0; x < dist; x++) {
mscript.state.loops[mscript.state.rec].arr.push('BF'); this.loops[this.rec].arr.push('BF');
mscript.state.loops[mscript.state.rec].light.push(mscript.black); this.loops[this.rec].light.push(BLACK);
mscript.state_update('BF'); this.update('BF');
} }
} else { } else {
dist = mscript.state.cam - target; dist = this.cam - target;
for (var x = 0; x < dist; x++) { for (var x = 0; x < dist; x++) {
mscript.state.loops[mscript.state.rec].arr.push('BB'); this.loops[this.rec].arr.push('BB');
mscript.state.loops[mscript.state.rec].light.push(mscript.black); this.loops[this.rec].light.push(BLACK);
mscript.state_update('BB'); this.update('BB');
} }
} }
} else { } else {
if (target > mscript.state.cam) { if (target > this.cam) {
dist = target - mscript.state.cam; dist = target - this.cam;
for (var x = 0; x < dist; x++) { for (var x = 0; x < dist; x++) {
arr.push('BF'); arr.push('BF');
light.push(mscript.black); light.push(BLACK);
mscript.state_update('BF'); this.update('BF');
} }
} else { } else {
dist = mscript.state.cam - target; dist = this.cam - target;
for (var x = 0; x < dist; x++) { for (var x = 0; x < dist; x++) {
arr.push('BB'); arr.push('BB');
light.push(mscript.black); light.push(BLACK);
mscript.state_update('BB'); this.update('BB');
} }
} }
} }
} else if (lines[i].substring(0, 4) === 'PROJ') { //directly go to that frame } else if (line.substring(0, 4) === 'PROJ') { //directly go to that frame
target = parseInt(lines[i].split('PROJ ')[1]); target = parseInt(line.split('PROJ ')[1]);
if (mscript.state.loops.length > 0) { if (this.loops.length > 0) {
if (target > mscript.state.proj) { if (target > this.proj) {
dist = target - mscript.state.proj; dist = target - this.proj;
for (var x = 0; x < dist; x++) { for (var x = 0; x < dist; x++) {
mscript.state.loops[mscript.state.rec].arr.push('PF'); this.loops[this.rec].arr.push('PF');
mscript.state.loops[mscript.state.rec].light.push(''); this.loops[this.rec].light.push('');
mscript.state_update('PF'); this.update('PF');
} }
} else { } else {
dist = mscript.state.proj - target; dist = this.proj - target;
for (var x = 0; x < dist; x++) { for (var x = 0; x < dist; x++) {
mscript.state.loops[mscript.state.rec].arr.push('PB'); this.loops[this.rec].arr.push('PB');
mscript.state.loops[mscript.state.rec].light.push(''); this.loops[this.rec].light.push('');
mscript.state_update('PB'); this.update('PB');
} }
} }
} else { } else {
if (target > mscript.state.proj) { if (target > this.proj) {
dist = target - mscript.state.proj; dist = target - this.proj;
for (var x = 0; x < dist; x++) { for (var x = 0; x < dist; x++) {
arr.push('PF'); arr.push('PF');
light.push(''); light.push('');
mscript.state_update('PF'); this.update('PF');
} }
} else { } else {
dist = mscript.state.proj - target; dist = this.proj - target;
for (var x = 0; x < dist; x++) { for (var x = 0; x < dist; x++) {
arr.push('PB'); arr.push('PB');
light.push(''); light.push('');
mscript.state_update('PB'); this.update('PB');
} }
} }
} }
} else if (lines[i].substring(0, 3) === 'SET') { //set that state } else if (line.substring(0, 3) === 'SET') { //set that state
if (lines[i].substring(0, 7) === 'SET CAM') { if (line.substring(0, 7) === 'SET CAM') {
mscript.state.cam = parseInt(lines[i].split('SET CAM')[1]); this.cam = parseInt(line.split('SET CAM')[1]);
} else if (lines[i].substring(0, 8) === 'SET PROJ') { } else if (line.substring(0, 8) === 'SET PROJ') {
mscript.state.proj = parseInt(lines[i].split('SET PROJ')[1]); this.proj = parseInt(line.split('SET PROJ')[1]);
} }
} else if (lines[i].substring(0, 1) === '#' || lines[i].substring(0, 2) === '//') { } else if (line.substring(0, 1) === '#' || line.substring(0, 2) === '//') {
//comments //comments
//ignore while parsing //ignore while parsing
} }
} }
output.success = true;
output.arr = arr;
output.light = light; this.output.success = true;
output.cam = mscript.state.cam; this.output.arr = arr; //all instructions
output.proj = mscript.state.proj; this.output.light = light; //all light instructions
this.output.cam = this.cam;
this.output.proj = this.proj;
if (typeof callback !== 'undefined') { if (typeof callback !== 'undefined') {
//should only be invoked by running mscript.tests() //should only be invoked by running mscript.tests()
callback(output); callback(this.output);
} else {
return mscript.output(output);
} }
}; }
/** last_loop () {
* return this.loops[this.loops.length - 1];
}
parent_loop () {
return this.loops[this.loops.length - 2];
}
loop_count (str) {
return parseInt(str.split(' ')[1]);
}
fade_count (str) {
return parseInt(str.split(' ')[1]);
}
/**
* Increase the state of a specific object, such as the camera/projector,
* by the value defined in val
*/ */
mscript.last_loop = function last_loop () { update (cmd, val = 1) {
return mscript.state.loops[mscript.state.loops.length - 1];
};
/**
*
*/
mscript.parent_loop = function parent_loop () {
return mscript.state.loops[mscript.state.loops.length - 2];
};
/**
*
*/
mscript.state_update = function state_update (cmd, val) {
if (cmd === 'END') { if (cmd === 'END') {
for (var i = 0; i < val; i++) { //I don't understand this loop
if (mscript.state.rec === 0) { for (let i = 0; i < val; i++) {
mscript.state.cam += mscript.state.loops[mscript.state.rec].cam; if (this.rec === 0) {
mscript.state.proj += mscript.state.loops[mscript.state.rec].proj; this.cam += this.loops[this.rec].cam;
} else if (mscript.state.rec >= 1) { this.proj += this.loops[this.rec].proj;
mscript.state.loops[mscript.state.rec - 1].cam += mscript.state.loops[mscript.state.rec].cam; } else if (this.rec >= 1) {
mscript.state.loops[mscript.state.rec - 1].proj += mscript.state.loops[mscript.state.rec].proj; this.loops[this.rec - 1].cam += this.loops[this.rec].cam;
this.loops[this.rec - 1].proj += this.loops[this.rec].proj;
} }
} }
} else if (cmd === 'CF') { } else if (cmd === 'CF') {
if (mscript.state.loops.length < 1) { if (this.loops.length < 1) {
mscript.state.cam++; this.cam += val;
} else { } else {
mscript.state.loops[mscript.state.rec].cam++; this.loops[this.rec].cam += val;
} }
} else if (cmd === 'CB') { } else if (cmd === 'CB') {
if (mscript.state.loops.length < 1) { if (this.loops.length < 1) {
mscript.state.cam--; this.cam -= val;
} else { } else {
mscript.state.loops[mscript.state.rec].cam--; this.loops[this.rec].cam--;
} }
} else if (cmd === 'PF') { } else if (cmd === 'PF') {
if (mscript.state.loops.length < 1) { if (this.loops.length < 1) {
mscript.state.proj++; this.proj += val;
} else { } else {
mscript.state.loops[mscript.state.rec].proj++; this.loops[this.rec].proj += val;
} }
} else if (cmd === 'PB') { } else if (cmd === 'PB') {
if (mscript.state.loops.length < 1) { if (this.loops.length < 1) {
mscript.state.proj--; this.proj -= val;
} else { } else {
mscript.state.loops[mscript.state.rec].proj--; this.loops[this.rec].proj--;
} }
} else if (cmd === 'BF') { } else if (cmd === 'BF') {
if (mscript.state.loops.length < 1) { if (this.loops.length < 1) {
mscript.state.cam++; this.cam += val;
} else { } else {
mscript.state.loops[mscript.state.rec].cam++; this.loops[this.rec].cam += val;
} }
} else if (cmd === 'BB') { } else if (cmd === 'BB') {
if (mscript.state.loops.length < 1) { if (this.loops.length < 1) {
mscript.state.cam--; this.cam -= val;
} else { } else {
mscript.state.loops[mscript.state.rec].cam++; this.loops[this.rec].cam -= val;
} }
} else if (cmd === 'L ') { } else if (cmd === 'L ') {
} }
}; }
/** /**
* * Split string on command, extract any integers from string
*/ */
mscript.str_to_arr = function str_to_arr (str, cmd) { str_to_arr (str, cmd) {
var cnt = str.split(cmd), const cnt = str.split(cmd);
c = parseInt(cnt[1]), let c = parseInt(cnt[1]);
arr = []; let arr = [];
if (cnt[1] === '') { if (cnt[1] === '') {
c = 1; c = 1;
} else { } else {
c = parseInt(cnt[1]); c = parseInt(cnt[1]);
} }
for (var i = 0; i < c; i++) { arr = new Array(c).fill(cmd);
arr.push(cmd); this.update(cmd, c);
mscript.state_update(cmd);
}
return arr; return arr;
}; }
/** /**
* *
*/ */
mscript.light_state = function light_state (str) { light_to_arr (str, cmd) {
//add parsers for other color spaces const cnt = str.split(cmd);
var color = str.replace('L ', '').trim(); let c = parseInt(cnt[1]);
mscript.state.color = color; let arr = [];
};
/**
*
*/
mscript.light_to_arr = function light_to_arr (str, cmd) {
var cnt = str.split(cmd),
c = parseInt(cnt[1]),
arr = [];
if (cnt[1] === '') { if (cnt[1] === '') {
c = 1; c = 1;
} else { } else {
@ -355,100 +306,34 @@ mscript.light_to_arr = function light_to_arr (str, cmd) {
for (var i = 0; i < c; i++) { for (var i = 0; i < c; i++) {
if (cmd === 'CF' if (cmd === 'CF'
|| cmd === 'CB') { || cmd === 'CB') {
arr.push(mscript.state.color); arr.push(this.color);
} else if (cmd === 'BF' } else if (cmd === 'BF'
|| cmd === 'BB') { || cmd === 'BB') {
arr.push(mscript.black); arr.push(BLACK);
} else { } else {
arr.push(''); arr.push('');
} }
} }
return arr; return arr;
}; }
/** /**
* *
*/ */
mscript.loop_count = function loop_count (str) { light_state (str) {
return parseInt(str.split(' ')[1]); //add parsers for other color spaces
}; const color = str.replace('L ', '').trim();
mscript.fade_count = function fade_count (str) { this.color = color;
return parseInt(str.split(' ')[1]); }
/**
*
*/
fail (msg) {
throw new Error(msg);
}
} }
/**
*
*/
mscript.fail = function fail (reason) {
console.error(JSON.stringify({success: false, error: true, msg : reason}));
if (process) process.exit();
};
/**
*
*/
mscript.output = function output (data) {
var json = true; //default
if (mscript.arg('-j', '--json')) {
json = true;
}
if (mscript.arg('-t', '--text')) { module.exports = Mscript;
json = false;
}
if (json) {
console.log(JSON.stringify(data));
} else {
var ids = Object.keys(data);
for (var i = 0; i < ids.length; i++) {
console.log(ids[i] + ': ' + data[ids[i]]);
}
}
};
/**
*
*/
mscript.init = function init () {
if (mscript.arg('-t', '--tests')) {
return mscript.tests();
}
if (mscript.arg('-v', '--verbose')) {
console.time('mscript');
}
if (mscript.arg('-c', '--cam')) {
mscript.state.cam = parseInt(process.argv[mscript.arg_pos('-c', '--cam') + 1]);
}
if (mscript.arg('-p', '--proj')) {
mscript.state.proj = parseInt(process.argv[mscript.arg_pos('-p', '--proj') + 1]);
}
if (mscript.arg('-f', '--file')) {
input = process.argv[mscript.arg_pos('-f', '--file') + 1];
mscript.interpret(fs.readFileSync(input, 'utf8'));
} else {
mscript.interpret(input);
}
if (mscript.arg('-v', '--verbose')) {
console.timeEnd('mscript');
}
};
if (typeof document === 'undefined'
&& typeof module !== 'undefined'
&& !module.parent) {
//node script
fs = require('fs');
input = process.argv[2];
mscript.init();
} else if (typeof module !== 'undefined' && module.parent) {
//module
fs = require('fs');
module.exports = mscript;
} else {
//web
}
/* /*