Skip to content

Commit

Permalink
Iss84 SHOW - Allow infinite looping of sequences
Browse files Browse the repository at this point in the history
* Add checkbox to allow for infinite looping of shows
* Add functionality to infinite loop sequences
* Fix element length bug in case that sequence does not have audio file.
* Change sendDMX.js functions into a module for more flexible use.
* Rename sendDMX.js to ShowRunner.js to accurately describe functions.
  • Loading branch information
Byron Ambright committed Apr 25, 2019
1 parent 0ccf913 commit b6b23ad
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 117 deletions.
4 changes: 2 additions & 2 deletions app/html/show.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
<button id='addElement'>Add element</button>
<br><br>
<button id='runShow' value='notPlaying'>Play</button>
<span>Loop show continuously?</span>
<input type="checkbox" id="repeatPlay">

<br><br><br><br>
<button id='patchShow'>Patch Show</button>
Expand All @@ -44,7 +46,5 @@

</script>
<script type="text/javascript" src="../js/patchShow.js"></script>
<script type="text/javascript" src="../js/sendDMX.js"></script>
<script type="text/javascript" src="../js/show.js"></script>

</html>
133 changes: 133 additions & 0 deletions app/js/ShowRunner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
const fs = parent.require('fs');
const NanoTimer = parent.require('nanotimer');
const ShowElementConstructor = parent.require('./js/ShowElement.js');

function ShowRunner() {
this.canPlay = false; // bool check for if should go to next sequence
this.repeat = false;
this.showElements = [];
this.showLength = 0;
}

ShowRunner.prototype.setupShowRunner = async function (sequencePathArray) {
// create show elements with sequence json path
for (let i = 0; i < sequencePathArray.length; i += 1) {
this.showElements.push(new ShowElementConstructor());
this.showElements[i].setSequenceJson(sequencePathArray[i]);
// TODO make this a promise or something, so we can set up all asyncronously
// eslint-disable-next-line no-await-in-loop
const duration = await this.showElements[i].setUpSequence();
this.showElements[i].setElementLength(duration);
}

const elementsLength = this.showElements.map(x => x.elementLength);
this.showLength = elementsLength.reduce((total, elementLength) => total + elementLength, 0);
};


ShowRunner.prototype.setCanPlay = function (canPlay) {
this.canPlay = canPlay;
};

ShowRunner.prototype.setRepeat = function (repeat) {
this.repeat = repeat;
};

ShowRunner.prototype.stopPlaying = function (showElement) {
// only stop audio if there is audio
if (showElement.getAudio()) {
showElement.getAudio().stop();
}
showElement.getTimer().clearInterval();
};

ShowRunner.prototype.stopAllShowElements = function () {
for (let j = 0; j < this.showElements.length; j += 1) {
this.stopPlaying(this.showElements[j]);
}
};

ShowRunner.prototype.update = function (showElement) {
const index = Math.ceil((new Date() - showElement.getStartTime()) / showElement.getInterval());
parent.parent.universe.update(showElement.getSequenceData()[index]);
if (index > showElement.getSequenceData().length) { // check for end of song
this.stopPlaying(showElement);
}
};

ShowRunner.prototype.playSequence = function (showElement) {
if (showElement.audioPath) {
showElement.getAudio().play();
}
showElement.setTimer(new NanoTimer());
showElement.setStartTime(new Date());
showElement.getTimer().setInterval(this.update, [showElement], '20m');
};

ShowRunner.prototype.checkAudioFinish = function (showElement) {
const index = Math.ceil((new Date() - showElement.getStartTime()) / 50);
if (showElement.getElementLength()) {
if (index > showElement.getElementLength()) { // check for end of song
this.stopPlaying(showElement);
}
}
};

ShowRunner.prototype.playAudio = function (showElement) {
if (showElement.audioPath) {
showElement.getAudio().play();
}
parent.parent.universe.updateAll(0);
showElement.setTimer(new NanoTimer());
showElement.setStartTime(new Date());
showElement.getTimer().setInterval(this.checkAudioFinish, [showElement], '20m');
};

ShowRunner.prototype.playElement = function (showElement) {
const sequenceJSON = JSON.parse(fs.readFileSync(showElement.getSequenceJson()));
if (sequenceJSON['Sequence Data Json'].length === 0) {
this.playAudio(showElement);
} else {
this.playSequence(showElement);
}
};

ShowRunner.prototype.repeatShow = function (showElement) {

};

ShowRunner.prototype.triggerShow = function () {
const i = 1;
this.playElement(this.showElements[0]);
// recursively waits and plays elements of the show
function playSequenceInShow(ind) {
let k = ind;
if (this.canPlay) {
setTimeout(() => {
if (this.canPlay) {
if (k < elements.length) {
this.playElement(this.showElements[k]);
k += 1;
playShowInSequence(k);
}
}
}, this.showElements[k - 1].getElementLength());
}
}
playSequenceInShow(i);
};

ShowRunner.prototype.playShow = async function () {
if (this.repeat && this.canPlay) {
setTimeout(() => {
this.setCanPlay(false);
this.stopAllShowElements();
this.setCanPlay(true);
this.playShow(this.showElements);
}, this.showLength);
}

this.triggerShow();
};

module.exports = ShowRunner;
86 changes: 0 additions & 86 deletions app/js/sendDMX.js

This file was deleted.

43 changes: 16 additions & 27 deletions app/js/show.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
const ShowRunnerConstructor = parent.require('./js/ShowRunner.js');
const ShowRunner = new ShowRunnerConstructor();

const table = document.getElementById('tableBody');
table.value = [];
const playButton = document.getElementById('runShow');
const ShowElementConstructor = parent.require('./js/showElement.js');
let showElements = [];

const repeat = document.getElementById('repeatPlay');

// directory of the current show contained in the iframe.value attribute
const showDir = window.parent.document.getElementById('frame').value;
const showDataPath = path.join(showDir, 'show.json');

// the json file containing the playlist of the show
const showData = JSON.parse(fse.readFileSync(showDataPath));

const playlistElements = showData.Playlist;

// push all playlist items (and associated audio if applicable)
// names onto table to be rendered for each show
table.value = [];
for (let i = 0; i < playlistElements.length; i += 1) {
let filename = playlistElements[i].split(path.sep);
filename = filename[filename.length - 1];
Expand Down Expand Up @@ -45,38 +45,27 @@ for (let i = 0; i < playlistElements.length; i += 1) {
table.appendChild(tableItem);
}

function stopAllShowElements() {
for (let j = 0; j < showElements.length; j += 1) {
stopPlaying(showElements[j]);
}
}

playButton.onclick = async function () {
// value property contains the boolean isPlaying
ShowRunner.setupShowRunner(table.value);

if (playButton.value === 'notPlaying') {
playButton.innerText = 'Stop';
playButton.value = 'playing';
playButton.style.backgroundColor = 'red';
playButton.style.borderColor = 'red';
// create show elements with sequence json path
showElements = [];
for (let k = 0; k < table.rows.length; k += 1) {
showElements.push(new ShowElementConstructor());
showElements[k].setSequenceJson(table.value[k]);
// TODO make this a promise or something, so we can set up all asyncronously
// eslint-disable-next-line no-await-in-loop
const duration = await showElements[k].setUpSequence();
showElements[k].setElementLength(duration * 1000);
}
startCanPlay(); // lock to determine ability to play
playShow(showElements);

ShowRunner.setCanPlay(true); // lock to determine ability to play
ShowRunner.setRepeat(repeat.checked);
ShowRunner.playShow();
} else {
playButton.innerText = 'Play';
playButton.value = 'notPlaying';
playButton.style.backgroundColor = 'green';
playButton.style.borderColor = 'green';
stopCanPlay(); // lock to stop play of show
stopAllShowElements();

ShowRunner.setCanPlay(false); // lock to stop play of show
ShowRunner.stopAllShowElements();
}
};
window.parent.document.getElementById('frame').onload = stopAllShowElements;

window.parent.document.getElementById('frame').onload = ShowRunner.stopAllShowElements();
Loading

0 comments on commit b6b23ad

Please sign in to comment.