From bd08b718f1404b220f897baf6d91a286464013ea Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Fri, 18 Nov 2022 09:37:48 -0600 Subject: [PATCH 1/3] start on QLab cleanup --- plugins/qlab/main.js | 210 +++++++++++++++++-------------------------- 1 file changed, 84 insertions(+), 126 deletions(-) diff --git a/plugins/qlab/main.js b/plugins/qlab/main.js index de6e009..3d0d176 100644 --- a/plugins/qlab/main.js +++ b/plugins/qlab/main.js @@ -18,102 +18,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){ @@ -163,107 +143,92 @@ exports.data = function data(device, oscData) { 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) } - - }; @@ -286,7 +251,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); @@ -306,53 +277,44 @@ exports.update = function update(device, doc, updateType, data){ } } - - - - - - - - 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 = []; +function addCueToWorkspace(_workspace, cue){ + const workspace = _workspace; + workspace.cues[cue.uniqueID] = cue; + workspace.cues[cue.uniqueID].nestedGroupModes = []; + workspace.cues[cue.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; } }); @@ -375,8 +337,4 @@ exports.heartbeat = function heartbeat(device) { device.send(`/cue/active/actionElapsed`); device.send(`/cue/active/postWaitElapsed`); } - -}; - - - +}; \ No newline at end of file From 0f31a7910542b50cde1bded12ae8efc06a47a48b Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sat, 19 Nov 2022 10:25:34 -0600 Subject: [PATCH 2/3] cleanup qlab template --- plugins/qlab/cue.ejs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) 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 %> + <% } %> From e4ba6f35482cb188884db2ea6eecaede8340d3e4 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sat, 19 Nov 2022 10:25:52 -0600 Subject: [PATCH 3/3] move global variables to start of file --- plugins/qlab/main.js | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/plugins/qlab/main.js b/plugins/qlab/main.js index 3d0d176..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'; @@ -129,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]"){ @@ -137,7 +151,6 @@ 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; @@ -233,9 +246,7 @@ exports.data = function data(_device, oscData) { }; -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){ @@ -277,11 +288,7 @@ exports.update = function update(device, doc, updateType, data){ } } -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 addCueToWorkspace(_workspace, cue){ const workspace = _workspace; @@ -321,8 +328,7 @@ function match(testArray, patternArray){ return out; } -let interval = 5; -let heartbeatCount = 0; + exports.heartbeat = function heartbeat(device) { heartbeatCount++;