Skip to content

Commit

Permalink
Merge pull request #2223 from dennisrijsdijk/effect-queues
Browse files Browse the repository at this point in the history
Effect Queues UI and API
  • Loading branch information
itsjesski authored Sep 15, 2023
2 parents 272b757 + e3e1617 commit e9cd08a
Show file tree
Hide file tree
Showing 9 changed files with 287 additions and 39 deletions.
6 changes: 3 additions & 3 deletions src/backend/effects/builtin/pause-resume-effect-queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ const model: EffectType<{
return false;
} else {
if (effect.action === "Pause") {
effectQueueRunner.pauseQueue(effect.effectQueue);
effectQueueManager.pauseQueue(effect.effectQueue);
} else if (effect.action === "Resume") {
effectQueueRunner.resumeQueue(effect.effectQueue);
effectQueueManager.resumeQueue(effect.effectQueue);
} else {
effectQueueRunner.toggleQueue(effect.effectQueue);
effectQueueManager.toggleQueue(effect.effectQueue);
}
}

Expand Down
96 changes: 96 additions & 0 deletions src/backend/effects/queues/effect-queue-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const effectQueueRunner = require("./effect-queue-runner");
* @prop {string} mode - the mode of the effect queue
* @prop {number} [interval] - the interval set for the interval mode
* @prop {string[]} sortTags - the tags for the effect queue
* @prop {boolean} active - the effect queue activity status
* @prop {number} length - amount of items currently in queue. don't save
* @prop {any[]} queue - effects queue. don't save
*/

/**
Expand All @@ -23,12 +26,35 @@ class EffectQueueManager extends JsonDbManager {
super("Effect Queue", "/effects/effectqueues");
}

/**
* @override
* @returns {void}
*/
loadItems() {
super.loadItems();
const queues = this.getAllItems();

let save = false;

for (const queue of queues) {
if (queue.active == null) {
queue.active = true;
save = true;
}
}
if (save) {
this.saveAllItems(queues);
}
}

/**
* @override
* @param {EffectQueue} effectQueue
* @returns {EffectQueue | null}
* */
saveItem(effectQueue) {
delete effectQueue.length;
delete effectQueue.queue;
const savedEffectQueue = super.saveItem(effectQueue);

if (savedEffectQueue) {
Expand All @@ -39,12 +65,76 @@ class EffectQueueManager extends JsonDbManager {
return null;
}

/**
* @override
* @param allItems - array of all effect queues
*/
saveAllItems(allItems) {
for (const item of allItems) {
delete item.length;
delete item.queue;
}
super.saveAllItems(allItems);
}

/**
* @override
*/
getAllItems() {
const items = JSON.parse(JSON.stringify(super.getAllItems()));
for (const item of items) {
item.length = effectQueueRunner.getQueue(item.id).length;
}
return items;
}

/**
* @override
* @param itemId
* @returns {T|null}
*/
getItem(itemId) {
const item = JSON.parse(JSON.stringify(super.getItem(itemId)));

item.queue = effectQueueRunner.getQueue(itemId);

return item;
}

/**
* @returns {void}
*/
triggerUiRefresh() {
frontendCommunicator.send("all-queues", this.getAllItems());
}

/** @private */
setQueueActivity(queue, status) {
queue.active = status;
this.saveItem(queue);
frontendCommunicator.send("updateQueueStatus", {id: queue.id, active: status});
}

pauseQueue(queueId) {
const queue = this.getItem(queueId);
if (queue != null && queue.active) {
this.setQueueActivity(queue, false);
}
}

resumeQueue(queueId) {
const queue = this.getItem(queueId);
if (queue != null && !queue.active) {
this.setQueueActivity(queue, true);
}
}

toggleQueue(queueId) {
const queue = this.getItem(queueId);
if (queue != null) {
this.setQueueActivity(queue, !queue.active);
}
}
}

const effectQueueManager = new EffectQueueManager();
Expand All @@ -61,4 +151,10 @@ frontendCommunicator.onAsync("saveAllEffectQueues",
frontendCommunicator.on("deleteEffectQueue",
(/** @type {string} */ effectQueueId) => effectQueueManager.deleteItem(effectQueueId));

frontendCommunicator.on("clearEffectQueue",
(/** @type {string} */ effectQueueId) => effectQueueRunner.removeQueue(effectQueueId));

frontendCommunicator.on("toggleEffectQueue",
(/** @type {string} */ effectQueueId) => effectQueueManager.toggleQueue(effectQueueId));

module.exports = effectQueueManager;
65 changes: 30 additions & 35 deletions src/backend/effects/queues/effect-queue-runner.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use strict";
const logger = require("../../logwrapper");
const effectRunner = require("../../common/effect-runner");
const frontendCommunicator = require("../../common/frontend-communicator");

/**
* Queue Entry
Expand All @@ -14,7 +15,7 @@ const effectRunner = require("../../common/effect-runner");
* Effect queue class
*/
class EffectQueue {
constructor(id, mode, interval = 0) {
constructor(id, mode, interval = 0, active = true) {
this.id = id;
this.mode = mode;
this.interval = interval;
Expand All @@ -24,10 +25,17 @@ class EffectQueue {
*/
this._queue = [];
this._running = false;
this._paused = false;
this._paused = !active;
this.canceled = false;
}

sendQueueLengthUpdate(lengthOverride = null) {
frontendCommunicator.send("updateQueueLength", {
id: this.id,
length: lengthOverride ?? this._queue.length
});
}

runQueue() {
return new Promise(resolve => {
if (this._queue.length === 0 || this.canceled || this._paused === true) {
Expand All @@ -42,6 +50,8 @@ class EffectQueue {

logger.debug(`Running next effects for queue ${this.id}. Mode=${this.mode}, Interval?=${this.interval}, Remaining queue length=${this._queue.length}`);

this.sendQueueLengthUpdate();

if (this.mode === "interval") {
effectRunner.runEffects(runEffectsContext)
.catch(err => {
Expand Down Expand Up @@ -94,6 +104,8 @@ class EffectQueue {

logger.debug(`Added more effects to queue ${this.id}. Current length=${this._queue.length}`);

this.sendQueueLengthUpdate();

this.processEffectQueue();
}

Expand Down Expand Up @@ -122,14 +134,6 @@ class EffectQueue {
this._paused = false;
this.processEffectQueue();
}

toggleQueue() {
if (this._paused) {
this.resumeQueue();
} else {
this.pauseQueue();
}
}
}

/**
Expand All @@ -144,7 +148,7 @@ function addEffectsToQueue(queueConfig, runEffectsContext, duration, priority) {
let queue = queues[queueConfig.id];
if (queue == null) {
logger.debug(`Creating queue ${queueConfig.id}...`);
queue = new EffectQueue(queueConfig.id, queueConfig.mode, queueConfig.interval);
queue = new EffectQueue(queueConfig.id, queueConfig.mode, queueConfig.interval, queueConfig.active);
queues[queueConfig.id] = queue;
}

Expand All @@ -159,27 +163,11 @@ function updateQueueConfig(queueConfig) {
if (queue != null) {
queue.mode = queueConfig.mode;
queue.interval = queueConfig.interval;
}
}

function pauseQueue(queueId) {
const queue = queues[queueId];
if (queue != null) {
queue.pauseQueue();
}
}

function resumeQueue(queueId) {
const queue = queues[queueId];
if (queue != null) {
queue.resumeQueue();
}
}

function toggleQueue(queueId) {
const queue = queues[queueId];
if (queue != null) {
queue.toggleQueue();
if (queueConfig.active) {
queue.resumeQueue();
} else {
queue.pauseQueue();
}
}
}

Expand All @@ -192,18 +180,25 @@ function removeQueue(queueId) {
if (queue != null) {
logger.debug(`Removing queue ${queue.id}`);
queue.canceled = true;
queue.sendQueueLengthUpdate(0);
delete queues[queueId];
}
}

function getQueue(queueId) {
const queue = queues[queueId];
if (queue == null) {
return [];
}
return queue._queue;
}

function clearAllQueues() {
Object.keys(queues).forEach(queueId => removeQueue(queueId));
}

exports.addEffectsToQueue = addEffectsToQueue;
exports.getQueue = getQueue;
exports.updateQueueConfig = updateQueueConfig;
exports.pauseQueue = pauseQueue;
exports.resumeQueue = resumeQueue;
exports.toggleQueue = toggleQueue;
exports.removeQueue = removeQueue;
exports.clearAllQueues = clearAllQueues;
18 changes: 18 additions & 0 deletions src/gui/app/controllers/effect-queues.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@
icon: "fa-clock",
cellTemplate: `{{(data.mode === 'interval' || data.mode === 'auto') ? (data.interval || 0) + 's' : 'n/a'}}`,
cellController: () => {}
},
{
name: "QUEUE LENGTH",
icon: "fa-tally",
cellTemplate: `{{data.length || 0}}`,
cellController: () => {}
}
];

Expand All @@ -52,6 +58,18 @@
effectQueuesService.showAddEditEffectQueueModal(item.id);
}
},
{
html: `<a href ><i class="far fa-toggle-off" style="margin-right: 10px;"></i> Toggle Enabled</a>`,
click: function () {
effectQueuesService.toggleEffectQueue(item);
}
},
{
html: `<a href ><i class="fad fa-minus-circle mr-4"></i> Clear Queue</a>`,
click: function () {
effectQueuesService.clearEffectQueue(item.id);
}
},
{
html: `<a href ><i class="far fa-clone mr-4"></i> Duplicate</a>`,
click: function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@
$ctrl.effectQueue = {
name: "",
mode: "custom",
sortTags: []
sortTags: [],
active: true,
length: 0
};

$ctrl.$onInit = () => {
Expand Down
23 changes: 23 additions & 0 deletions src/gui/app/services/effect-queues.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@
}
});

backendCommunicator.on("updateQueueLength", queue => {
const index = service.effectQueues.findIndex(eq => eq.id === queue.id);
if (service.effectQueues[index] != null) {
service.effectQueues[index].length = queue.length;
}
});

backendCommunicator.on("updateQueueStatus", queue => {
const index = service.effectQueues.findIndex(eq => eq.id === queue.id);
if (service.effectQueues[index] != null) {
service.effectQueues[index].active = queue.active;
}
});

service.queueModes = [
{
id: "custom",
Expand Down Expand Up @@ -73,6 +87,15 @@
return false;
};

service.toggleEffectQueue = (queue) => {
backendCommunicator.fireEvent("toggleEffectQueue", queue.id);
queue.active = !queue.active;
};

service.clearEffectQueue = (queueId) => {
backendCommunicator.fireEvent("clearEffectQueue", queueId);
};

service.saveAllEffectQueues = (effectQueues) => {
service.effectQueues = effectQueues;
backendCommunicator.fireEvent("saveAllEffectQueues", effectQueues);
Expand Down
1 change: 1 addition & 0 deletions src/gui/app/templates/_effect-queues.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@
no-data-message="No effect queues saved. You should make one! :)"
none-found-message="No effect queues found."
search-placeholder="Search effect queues"
status-field="active"
></firebot-item-table>
Loading

0 comments on commit e9cd08a

Please sign in to comment.