diff --git a/plugins/qlab/cue.ejs b/plugins/qlab/cue.ejs
index b887359..12fcbc7 100644
--- a/plugins/qlab/cue.ejs
+++ b/plugins/qlab/cue.ejs
@@ -33,22 +33,20 @@
<% for(let i=cue.nestedGroupModes.length; i>0; i--){ %>
- <% let test = "" %>
-
<% if(cue.type=="Group" && i==1 && cue.cues.length==0){ %>
-
<%= test %> |
+ |
<% }else if(cue.type=="Group" && i==1){ %>
- <%= test %> |
+ |
<% }else if(cue.nestedGroupPosition[i-1]==0 && cue.nestedGroupPosition[i-2]==0){ %>
- <%= test %> |
+ |
<% }else if(i==1 && cue.nestedGroupPosition[i]==0){ %>
- <%= test %> |
+ |
<% }else{ %>
- <%= test %> |
+ |
<% } %>
diff --git a/plugins/qlab/main.js b/plugins/qlab/main.js
index de6e009..e001cde 100644
--- a/plugins/qlab/main.js
+++ b/plugins/qlab/main.js
@@ -3,6 +3,18 @@ const fs = require('fs');
const path = require('path');
let lastElapsedUpdate = Date.now();
+let interval = 5;
+let heartbeatCount = 0;
+
+const valuesForKeysString =
+'["uniqueID","number","name","listName","isBroken","isRunning","isLoaded","isFlagged",'
++ '"type","children","preWait","postWait","currentDuration","colorName","continueMode",'
++ '"mode","parent","cartRows","cartColumns","cartPosition","displayName","preWaitElapsed",'
++ '"actionElapsed","postWaitElapsed","isPaused"]';
+
+const cueTemplate = _.template(fs.readFileSync(path.join(__dirname, `cue.ejs`)));
+const tileTemplate = _.template(fs.readFileSync(path.join(__dirname, `tile.ejs`)));
+const cartTemplate = _.template(fs.readFileSync(path.join(__dirname, `cart.ejs`)));
exports.defaultName = 'QLab 4';
exports.connectionType = 'osc';
@@ -18,102 +30,82 @@ exports.ready = function ready(device) {
device.send('/workspaces');
};
-exports.data = function data(device, oscData) {
- const osc = oscData.address.split('/');
- osc.shift();
- const d = device;
-
- // console.log(oscData.address)
+exports.data = function data(_device, oscData) {
+ const device = _device;
- if(match(osc, ["reply", "version"])){
+ const oscAddressParts = oscData.address.split('/');
+ oscAddressParts.shift();
+ if(match(oscAddressParts, ["reply", "version"])){
const json = JSON.parse(oscData.args[0]);
- d.data.version = json.data;
+ device.data.version = json.data;
- this.deviceInfoUpdate(d, 'status', 'ok');
-
-
- }else if(match(osc, ["reply", "workspaces"])){
+ this.deviceInfoUpdate(device, 'status', 'ok');
+ }else if(match(oscAddressParts, ["reply", "workspaces"])){
const json = JSON.parse(oscData.args[0]);
- d.data.workspaces = {};
+ device.data.workspaces = {};
json.data.forEach(wksp => {
- d.data.workspaces[wksp.uniqueID] = {
+ device.data.workspaces[wksp.uniqueID] = {
uniqueID: wksp.uniqueID,
displayName: wksp.displayName,
cueLists: {},
cues: {}
}
-
- d.send(`/workspace/${wksp.uniqueID}/connect`);
-
+ device.send(`/workspace/${wksp.uniqueID}/connect`);
});
+ }else if(match(oscAddressParts, ["reply", "workspace", "*", "connect"])){
-
- }else if(match(osc, ["reply", "workspace", "*", "connect"])){
-
- d.send(`/workspace/${osc[2]}/updates`, [
+ device.send(`/workspace/${oscAddressParts[2]}/updates`, [
{ type: 'i', value: 1 },
]);
- d.send(`/workspace/${osc[2]}/cueLists`);
+ device.send(`/workspace/${oscAddressParts[2]}/cueLists`);
+ }else if(match(oscAddressParts, ["reply", "workspace", "*", "cueLists"])){
-
- }else if(match(osc, ["reply", "workspace", "*", "cueLists"])){
-
- this.deviceInfoUpdate(d, 'status', 'ok');
-
-
- const workspace = d.data.workspaces[osc[2]];
+ this.deviceInfoUpdate(device, 'status', 'ok');
+ const workspace = device.data.workspaces[oscAddressParts[2]];
const json = JSON.parse(oscData.args[0]);
workspace.cueLists = {};
workspace.cues = {};
-
- json.data.forEach(ql => {
- workspace.cueLists[ql.uniqueID] = ql;
- addChildrenToWorkspace(workspace, ql);
+ json.data.forEach(cueList => {
+ workspace.cueLists[cueList.uniqueID] = cueList;
+ addCueToWorkspace(workspace, cueList);
});
- d.draw();
-
+ device.draw();
setTimeout(() => {
json.data.forEach(ql => {
workspace.cueLists[ql.uniqueID] = ql;
- getValuesForKeys(d, json.workspace_id, ql);
+ getValuesForKeys(device, json.workspace_id, ql);
});
}, 0);
-
-
- }else if(match(osc, ["reply", "cue_id", "*", "children"])){
+ }else if(match(oscAddressParts, ["reply", "cue_id", "*", "children"])){
const json = JSON.parse(oscData.args[0]);
- const workspace = d.data.workspaces[json.workspace_id];
- const cueID = osc[2];
+ const workspace = device.data.workspaces[json.workspace_id];
+ const cueID = oscAddressParts[2];
const cue = workspace.cues[cueID];
if(!_.isEqual(cue.cues, json.data)){
workspace.cueLists[cueID].cues = json.data;
- addChildrenToWorkspace(workspace, workspace.cueLists[cueID]);
-
- d.draw();
-
- getValuesForKeys(d, json.workspace_id, cue);
+ addCueToWorkspace(workspace, workspace.cueLists[cueID]);
+ device.draw();
+ getValuesForKeys(device, json.workspace_id, cue);
}
-
- }else if(match(osc, ["reply", "cue_id", "*", "valuesForKeys"])){
+ }else if(match(oscAddressParts, ["reply", "cue_id", "*", "valuesForKeys"])){
const json = JSON.parse(oscData.args[0]);
const cueValues = json.data;
-
- const workspace = d.data.workspaces[json.workspace_id];
+ const workspace = device.data.workspaces[json.workspace_id];
let cue = workspace.cues[cueValues.uniqueID];
if(!cue){
@@ -149,6 +141,8 @@ exports.data = function data(device, oscData) {
const nestedGroupModes = [];
const nestedGroupPosition = [0];
+
+
let obj = cue;
while(obj.parent !== "[root group of cue lists]"){
@@ -157,120 +151,102 @@ exports.data = function data(device, oscData) {
let pos = _.findIndex(workspace.cues[obj.parent].cues, {uniqueID: obj.uniqueID});
pos = Math.abs(pos - workspace.cues[obj.parent].cues.length) - 1;
nestedGroupPosition.push(pos)
-
obj = workspace.cues[obj.parent];
}
cue.nestedGroupModes = nestedGroupModes;
cue.nestedGroupPosition = nestedGroupPosition;
- // console.log("draw "+cue.number)
+ device.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace});
- d.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace});
-
-
- }else if(match(osc, ["reply", "cue_id", "*", "preWaitElapsed"])){
+ }else if(match(oscAddressParts, ["reply", "cue_id", "*", "preWaitElapsed"])){
const json = JSON.parse(oscData.args[0]);
- const workspace = d.data.workspaces[json.workspace_id];
- const cue = workspace.cues[osc[2]];
+ const workspace = device.data.workspaces[json.workspace_id];
+ const cue = workspace.cues[oscAddressParts[2]];
cue.preWaitElapsed = json.data;
lastElapsedUpdate = Date.now();
- d.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace});
+ device.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace});
-
- }else if(match(osc, ["reply", "cue_id", "*", "actionElapsed"])){
+ }else if(match(oscAddressParts, ["reply", "cue_id", "*", "actionElapsed"])){
const json = JSON.parse(oscData.args[0]);
- const workspace = d.data.workspaces[json.workspace_id];
- const cue = workspace.cues[osc[2]];
+ const workspace = device.data.workspaces[json.workspace_id];
+ const cue = workspace.cues[oscAddressParts[2]];
cue.actionElapsed = json.data;
lastElapsedUpdate = Date.now();
- d.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace});
+ device.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace});
-
- }else if(match(osc, ["reply", "cue_id", "*", "postWaitElapsed"])){
+ }else if(match(oscAddressParts, ["reply", "cue_id", "*", "postWaitElapsed"])){
const json = JSON.parse(oscData.args[0]);
const workspace = device.data.workspaces[json.workspace_id];
- const cue = workspace.cues[osc[2]];
+ const cue = workspace.cues[oscAddressParts[2]];
cue.postWaitElapsed = json.data;
lastElapsedUpdate = Date.now();
- d.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace});
+ device.update("updateCueData", {'cue': cue, 'allCues': workspace.cues, 'workspace': workspace});
+ }else if(match(oscAddressParts, ["update", "workspace", "*", "cue_id", "*"])){
- }else if(match(osc, ["update", "workspace", "*", "cue_id", "*"])){
-
- const workspace = d.data.workspaces[osc[2]];
+ const workspace = device.data.workspaces[oscAddressParts[2]];
if(workspace){
const cueLists = Object.keys(workspace.cueLists);
- const cueID = osc[4];
+ const cueID = oscAddressParts[4];
if(cueID !== "[root group of cue lists"){
if(cueLists.includes(cueID)){
- d.send(`/workspace/${workspace.uniqueID}/cue_id/${cueID}/children`);
+ device.send(`/workspace/${workspace.uniqueID}/cue_id/${cueID}/children`);
}
- d.send(`/workspace/${osc[2]}/cue_id/${cueID}/valuesForKeys`, [
+ device.send(`/workspace/${oscAddressParts[2]}/cue_id/${cueID}/valuesForKeys`, [
{type: 's', value: valuesForKeysString}
]);
-
}
}
-
- }else if(match(osc, ["update", "workspace", "*"])){
+ }else if(match(oscAddressParts, ["update", "workspace", "*"])){
// occurs when cue lists are reordered or a list is deleted
- d.send(`/workspace/${osc[2]}/cueLists`);
+ device.send(`/workspace/${oscAddressParts[2]}/cueLists`);
-
- }else if(match(osc, ["update", "workspace", "*", "dashboard"])){
+ }else if(match(oscAddressParts, ["update", "workspace", "*", "dashboard"])){
// this workspace might be new, let's check
-
- if(d.data.workspaces[osc[2]]){
- //
- }else{
+ if(device.data.workspaces[oscAddressParts[2]] === undefined){
console.log("new workspace!");
- d.send('/workspaces');
+ device.send('/workspaces');
}
+ }else if(match(oscAddressParts, ["update", "workspace", "*", "cueList", "*", "playbackPosition"])){
- }else if(match(osc, ["update", "workspace", "*", "cueList", "*", "playbackPosition"])){
-
- const workspace = d.data.workspaces[osc[2]];
+ const workspace = device.data.workspaces[oscAddressParts[2]];
if(workspace){
const cue = workspace.cues[oscData.args[0]];
if(cue){
workspace.playbackPosition = oscData.args[0] ? cue.uniqueID : "";
- d.update("updatePlaybackPosition", {'cue': cue});
+ device.update("updatePlaybackPosition", {'cue': cue});
}
}
- }else if(match(osc, ["update", "workspace", "*", "disconnect"])){
+ }else if(match(oscAddressParts, ["update", "workspace", "*", "disconnect"])){
- delete d.data.workspaces[osc[2]];
- d.draw();
+ delete device.data.workspaces[oscAddressParts[2]];
+ device.draw();
}else{
// console.log(address)
}
-
-
};
-const cueTemplate = _.template(fs.readFileSync(path.join(__dirname, `cue.ejs`)));
-const tileTemplate = _.template(fs.readFileSync(path.join(__dirname, `tile.ejs`)));
-const cartTemplate = _.template(fs.readFileSync(path.join(__dirname, `cart.ejs`)));
+
exports.update = function update(device, doc, updateType, data){
@@ -286,7 +262,13 @@ exports.update = function update(device, doc, updateType, data){
$elem.outerHTML = cartTemplate({'tileTemplate': tileTemplate, 'cueList': data.cue, 'allCues': data.workspace.cues});
}else if(data.cue.cartPosition && data.cue.cartPosition[0] !== 0){
- $elem.outerHTML = tileTemplate(data);
+ // checking that the parent cue is a cart cue
+ const parentCue = data.workspace.cues[data.cue.parent];
+ if(parentCue && parentCue.type === "Cart"){
+ $elem.outerHTML = tileTemplate(data);
+ }else{
+ $elem.outerHTML = cueTemplate(data);
+ }
}else{
$elem.outerHTML = cueTemplate(data);
@@ -308,59 +290,45 @@ exports.update = function update(device, doc, updateType, data){
+function addCueToWorkspace(_workspace, cue){
+ const workspace = _workspace;
+ workspace.cues[cue.uniqueID] = cue;
+ workspace.cues[cue.uniqueID].nestedGroupModes = [];
+ workspace.cues[cue.uniqueID].nestedGroupPosition = [];
-
-
-
-
-
-const valuesForKeysString =
-'["uniqueID","number","name","listName","isBroken","isRunning","isLoaded","isFlagged",'
-+ '"type","children","preWait","postWait","currentDuration","colorName","continueMode",'
-+ '"mode","parent","cartRows","cartColumns","cartPosition","displayName","preWaitElapsed",'
-+ '"actionElapsed","postWaitElapsed","isPaused"]';
-
-function addChildrenToWorkspace(workspace, q){
- const w = workspace;
- w.cues[q.uniqueID] = q;
- w.cues[q.uniqueID].nestedGroupModes = [];
- w.cues[q.uniqueID].nestedGroupPosition = [];
-
- if(q.cues){
- q.cues.forEach(cue => {
- addChildrenToWorkspace(w, cue);
+ if(cue.cues){
+ // this cue has children so add them as well
+ cue.cues.forEach(childCue => {
+ addCueToWorkspace(workspace, childCue);
});
}
}
-
-function getValuesForKeys(device, workspaceID, q){
- device.send(`/workspace/${workspaceID}/cue_id/${q.uniqueID}/valuesForKeys`, [
+function getValuesForKeys(device, workspaceID, cue){
+ device.send(`/workspace/${workspaceID}/cue_id/${cue.uniqueID}/valuesForKeys`, [
{type: 's', value: valuesForKeysString}
]);
- if(q.cues){
- q.cues.forEach(cue => {
- getValuesForKeys(device, workspaceID, cue);
+ if(cue.cues){
+ cue.cues.forEach(childCue => {
+ getValuesForKeys(device, workspaceID, childCue);
});
}
}
-
-function match(osc, array){
+function match(testArray, patternArray){
let out = true;
- if(osc.length !== array.length){
+ if(testArray.length !== patternArray.length){
return false;
}
- array.forEach((m, i)=> {
- if(osc[i] !== m && m !== "*"){
+ patternArray.forEach((patternPart, i)=> {
+ if(testArray[i] !== patternPart && patternPart !== "*"){
out = false;
}
});
return out;
}
-let interval = 5;
-let heartbeatCount = 0;
+
exports.heartbeat = function heartbeat(device) {
heartbeatCount++;
@@ -375,8 +343,4 @@ exports.heartbeat = function heartbeat(device) {
device.send(`/cue/active/actionElapsed`);
device.send(`/cue/active/postWaitElapsed`);
}
-
-};
-
-
-
+};
\ No newline at end of file