Convert UI to callbacks - reduce dependency on the Core.

master
William Toohey 10 years ago
parent 7a7bbd2b39
commit a7c021e9cf
  1. 123
      js/HuesCore.js
  2. 107
      js/HuesUI.js

@ -37,6 +37,60 @@ function HuesCore(defaults) {
this.loopCount = 0; this.loopCount = 0;
this.doBuildup = true; this.doBuildup = true;
this.userInterface = null; this.userInterface = null;
this.eventListeners = {
/* callback time(hundredths)
*
* When the song time is updated - 0 for buildup, integer 10ths
* of a second otherwise
*/
time : [],
/* callback blurUpdate(xPercent, yPercent)
*
* The current blur amounts, in percent of full blur
*/
blurupdate : [],
/* callback newsong(song)
*
* Called on song change, whether user triggered or autosong.
* Song object is passed.
*/
newsong : [],
/* callback newimage(image)
*
* Called on image change, whether user triggered or FULL AUTO mode.
* Image object is passed.
*/
newimage : [],
/* callback newimage(image)
*
* Called on colour change.
* Colour object is passed.
*/
newcolour : [],
/* callback newmode(mode)
*
* Called on mode change.
* Mode is passed as a boolean.
*/
newmode : [],
/* callback beat(beatString, beatIndex)
*
* Called on every new beat.
* beatString is a 256 char long array of current and upcoming beat chars
* beatIndex is a "safe to display" beat index. 0 during buildups,
* index % beatmap length otherwise.
*/
beat : [],
/* callback invert(isInverted)
*
* Called whenever the invert state changes.
* Invert state is passed as a boolean.
*/
invert : []
};
var that = this; var that = this;
window.onerror = function(msg, url, line, col, error) { window.onerror = function(msg, url, line, col, error) {
@ -118,6 +172,33 @@ function HuesCore(defaults) {
this.animationLoop(); this.animationLoop();
} }
HuesCore.prototype.callEventListeners = function(ev) {
var args = Array.prototype.slice.call(arguments, 1);
this.eventListeners[ev].forEach(function(callback) {
callback.apply(null, args);
});
}
HuesCore.prototype.addEventListener = function(ev, callback) {
ev = ev.toLowerCase();
if (typeof(this.eventListeners[ev]) !== "undefined") {
this.eventListeners[ev].push(callback);
} else {
throw Error("Unknown event: " + ev);
}
};
HuesCore.prototype.removeEventListener = function(ev, callback) {
ev = ev.toLowerCase();
if (typeof(this.eventListeners[ev]) !== "undefined") {
this.eventListeners[ev] = this.eventListeners[ev].filter(function(a) {
return (a !== callback);
});
} else {
throw Error("Unknown event: " + ev);
}
};
HuesCore.prototype.resizeVisualiser = function() { HuesCore.prototype.resizeVisualiser = function() {
this.soundManager.initVisualiser(this.visualiser.width/2); this.soundManager.initVisualiser(this.visualiser.width/2);
} }
@ -169,9 +250,9 @@ HuesCore.prototype.animationLoop = function() {
this.updateVisualiser(); this.updateVisualiser();
var now = this.soundManager.currentTime(); var now = this.soundManager.currentTime();
if(now < 0) { if(now < 0) {
this.userInterface.updateTime(0); this.callEventListeners("time", 0);
} else { } else {
this.userInterface.updateTime(this.soundManager.displayableTime()); this.callEventListeners("time", this.soundManager.displayableTime());
if(this.doBuildup) { if(this.doBuildup) {
this.currentSong.buildupPlayed = true; this.currentSong.buildupPlayed = true;
} }
@ -184,10 +265,6 @@ HuesCore.prototype.animationLoop = function() {
requestAnimationFrame(function() {that.animationLoop();}); requestAnimationFrame(function() {that.animationLoop();});
}; };
HuesCore.prototype.getCurrentMode = function() {
return this.isFullAuto ? "FULL AUTO" : "NORMAL";
};
HuesCore.prototype.getSafeBeatIndex = function() { HuesCore.prototype.getSafeBeatIndex = function() {
if(!this.soundManager.playing) { if(!this.soundManager.playing) {
return 0; return 0;
@ -200,7 +277,7 @@ HuesCore.prototype.getSafeBeatIndex = function() {
}; };
HuesCore.prototype.blurUpdated = function(x, y) { HuesCore.prototype.blurUpdated = function(x, y) {
this.userInterface.blurUpdated(x, y); this.callEventListeners("blurupdate", x, y);
}; };
HuesCore.prototype.nextSong = function() { HuesCore.prototype.nextSong = function() {
@ -237,7 +314,7 @@ HuesCore.prototype.setSong = function(index) {
this.currentSong = {"name":"None", "title":"None", "rhythm":".", "source":null, "crc":"none", "sound":null, "enabled":true, "filename":"none"}; this.currentSong = {"name":"None", "title":"None", "rhythm":".", "source":null, "crc":"none", "sound":null, "enabled":true, "filename":"none"};
} }
console.log("Next song:", this.songIndex, this.currentSong); console.log("Next song:", this.songIndex, this.currentSong);
this.userInterface.setSongText(); this.callEventListeners("newsong", this.currentSong);
this.loopCount = 0; this.loopCount = 0;
if (this.currentSong.buildup) { if (this.currentSong.buildup) {
switch (localStorage["playBuildups"]) { switch (localStorage["playBuildups"]) {
@ -340,8 +417,8 @@ HuesCore.prototype.doAutoSong = function() {
HuesCore.prototype.songDataUpdated = function() { HuesCore.prototype.songDataUpdated = function() {
if (this.currentSong) { if (this.currentSong) {
this.beatLength = 0; this.beatLength = 0;
this.userInterface.setSongText(); this.callEventListeners("newsong", this.currentSong);
this.userInterface.setImageText(); this.callEventListeners("newimage", this.currentImage);
} else { } else {
this.beatLength = -1; this.beatLength = -1;
} }
@ -385,7 +462,7 @@ HuesCore.prototype.setImage = function(index) {
this.lastImageArray = []; this.lastImageArray = [];
} }
this.renderer.setImage(this.currentImage); this.renderer.setImage(this.currentImage);
this.userInterface.setImageText(); this.callEventListeners("newimage", this.currentImage);
}; };
HuesCore.prototype.setImageByName = function(name) { HuesCore.prototype.setImageByName = function(name) {
@ -428,8 +505,9 @@ HuesCore.prototype.randomColour = function(isFade) {
HuesCore.prototype.setColour = function(index, isFade) { HuesCore.prototype.setColour = function(index, isFade) {
this.colourIndex = index; this.colourIndex = index;
this.renderer.setColour(this.colours[this.colourIndex].c, isFade); var colour = this.colours[this.colourIndex];
this.userInterface.setColourText(); this.renderer.setColour(colour.c, isFade);
this.callEventListeners("newcolour", colour);
}; };
HuesCore.prototype.getBeat = function(index) { HuesCore.prototype.getBeat = function(index) {
@ -441,7 +519,7 @@ HuesCore.prototype.getBeat = function(index) {
}; };
HuesCore.prototype.beater = function(beat) { HuesCore.prototype.beater = function(beat) {
this.userInterface.beat(); this.callEventListeners("beat", this.getBeatString(), this.getSafeBeatIndex());
this.renderer.beat(); this.renderer.beat();
switch(beat) { switch(beat) {
case 'X': case 'X':
@ -536,7 +614,7 @@ HuesCore.prototype.getBeatString = function(length) {
HuesCore.prototype.setIsFullAuto = function(auto) { HuesCore.prototype.setIsFullAuto = function(auto) {
this.isFullAuto = auto; this.isFullAuto = auto;
if (this.userInterface) { if (this.userInterface) {
this.userInterface.modeUpdated(); this.callEventListeners("newmode", this.isFullAuto);
} }
}; };
@ -553,7 +631,7 @@ HuesCore.prototype.setInvert = function(invert) {
document.documentElement.style.filter = ""; document.documentElement.style.filter = "";
document.documentElement.style.webkitFilter = ""; document.documentElement.style.webkitFilter = "";
} }
this.userInterface.invert(invert); this.callEventListeners("invert", invert);
} }
HuesCore.prototype.toggleInvert = function() { HuesCore.prototype.toggleInvert = function() {
@ -567,15 +645,16 @@ HuesCore.prototype.respackLoaded = function() {
HuesCore.prototype.changeUI = function(index) { HuesCore.prototype.changeUI = function(index) {
if (index >= 0 && this.uiArray.length > index && this.userInterface != this.uiArray[index]) { if (index >= 0 && this.uiArray.length > index && this.userInterface != this.uiArray[index]) {
this.hideLists(); this.hideLists();
if(this.userInterface) if(this.userInterface) {
this.userInterface.disconnect(); this.userInterface.disconnect();
}
this.userInterface = this.uiArray[index]; this.userInterface = this.uiArray[index];
this.userInterface.connectCore(this); this.userInterface.connectCore(this);
this.userInterface.setSongText(); this.callEventListeners("newmode", this.isFullAuto);
this.userInterface.setImageText(); this.callEventListeners("newsong", this.currentSong);
this.userInterface.setColourText(this.colourIndex); this.callEventListeners("newimage", this.currentImage);
this.userInterface.beat(); this.callEventListeners("newcolour", this.colours[this.colourIndex]);
this.userInterface.modeUpdated(); this.callEventListeners("beat", this.getBeatString(), this.getSafeBeatIndex());
} }
}; };

@ -55,6 +55,11 @@ function HuesUI(parent) {
this.settingsToggle = null; this.settingsToggle = null;
this.hideToggle = null; this.hideToggle = null;
// To deregister on UI hide we need to keep track of these
// Each callback is { name : "callbackname", func : function }
// Add using this.addCoreCallback
this.callbacks = [];
// Put this near the links to song/image lists/ Bottom right alignment // Put this near the links to song/image lists/ Bottom right alignment
this.listContainer = null; this.listContainer = null;
@ -66,6 +71,10 @@ function HuesUI(parent) {
this.initUI(); this.initUI();
} }
HuesUI.prototype.addCoreCallback = function(name, func) {
this.callbacks.push({name : name, func : func});
}
HuesUI.prototype.initUI = function() { HuesUI.prototype.initUI = function() {
var that = this; var that = this;
@ -119,7 +128,7 @@ HuesUI.prototype.initUI = function() {
this.timer.textContent = "T=$0x0000"; this.timer.textContent = "T=$0x0000";
this.beatCount = document.createElement("div"); this.beatCount = document.createElement("div");
this.beatCount.textContent = "B=$0x000"; this.beatCount.textContent = "B=$0x0000";
this.xBlur = document.createElement("div"); this.xBlur = document.createElement("div");
this.xBlur.textContent = "X=$0x00"; this.xBlur.textContent = "X=$0x00";
@ -143,9 +152,12 @@ HuesUI.prototype.initUI = function() {
this.listContainer = document.createElement("div"); this.listContainer = document.createElement("div");
this.visualiserContainer = document.createElement("div"); this.visualiserContainer = document.createElement("div");
this.resizeHandler = function() { this.addCoreCallback("newsong", this.newSong.bind(this));
that.resize(); this.addCoreCallback("newimage", this.newImage.bind(this));
}; this.addCoreCallback("newcolour", this.newColour.bind(this));
this.addCoreCallback("blurupdate", this.blurUpdated.bind(this));
this.addCoreCallback("time", this.updateTime.bind(this));
this.resizeHandler = this.resize.bind(this);
}; };
HuesUI.prototype.connectCore = function(core) { HuesUI.prototype.connectCore = function(core) {
@ -156,6 +168,9 @@ HuesUI.prototype.connectCore = function(core) {
} }
this.visualiserContainer.appendChild(this.core.visualiser); this.visualiserContainer.appendChild(this.core.visualiser);
this.callbacks.forEach(function(callback) {
core.addEventListener(callback.name, callback.func);
});
window.addEventListener('resize', this.resizeHandler); window.addEventListener('resize', this.resizeHandler);
this.resizeHandler(); this.resizeHandler();
}; };
@ -169,7 +184,10 @@ HuesUI.prototype.disconnect = function() {
while (this.visualiserContainer.firstElementChild) { while (this.visualiserContainer.firstElementChild) {
this.visualiserContainer.removeChild(this.visualiserContainer.firstElementChild); this.visualiserContainer.removeChild(this.visualiserContainer.firstElementChild);
} }
this.callbacks.forEach(function(callback) {
core.removeEventListener(callback.name, callback.func);
});
window.removeEventListener('resize', this.resizeHandler); window.removeEventListener('resize', this.resizeHandler);
}; };
@ -192,16 +210,10 @@ HuesUI.prototype.toggleHide = function() {
} }
}; };
// May do nothing, may scale elements if needed etc etc
HuesUI.prototype.resize = function() {}; HuesUI.prototype.resize = function() {};
HuesUI.prototype.modeUpdated = function() {};
HuesUI.prototype.beat = function() {};
HuesUI.prototype.updateVolume = function(vol) {}; HuesUI.prototype.updateVolume = function(vol) {};
HuesUI.prototype.invert = function(invert) {};
HuesUI.prototype.setSongText = function() {
var song = this.core.currentSong;
HuesUI.prototype.newSong = function(song) {
if(!song) { if(!song) {
return; return;
} }
@ -210,9 +222,7 @@ HuesUI.prototype.setSongText = function() {
this.songLink.href = song.source; this.songLink.href = song.source;
}; };
HuesUI.prototype.setImageText = function() { HuesUI.prototype.newImage = function(image) {
var image = this.core.currentImage;
if(!image) { if(!image) {
return; return;
} }
@ -223,9 +233,7 @@ HuesUI.prototype.setImageText = function() {
this.imageLink.href = image.source ? image.source : ""; this.imageLink.href = image.source ? image.source : "";
}; };
HuesUI.prototype.setColourText = function() { HuesUI.prototype.newColour = function(colour) {
var colour = this.core.colours[this.core.colourIndex];
this.hueName.textContent = colour.n.toUpperCase(); this.hueName.textContent = colour.n.toUpperCase();
}; };
@ -357,6 +365,9 @@ RetroUI.prototype.initUI = function() {
this.visualiserContainer.className = "hues-r-visualisercontainer"; this.visualiserContainer.className = "hues-r-visualisercontainer";
this.root.appendChild(this.visualiserContainer); this.root.appendChild(this.visualiserContainer);
this.addCoreCallback("beat", this.beat.bind(this));
this.addCoreCallback("newmode", this.newMode.bind(this));
}; };
RetroUI.prototype.toggleHide = function(stylename) { RetroUI.prototype.toggleHide = function(stylename) {
@ -379,16 +390,13 @@ RetroUI.prototype.connectCore = function(core) {
HuesUI.prototype.connectCore.call(this, core); HuesUI.prototype.connectCore.call(this, core);
this.version.textContent = "V=$" + core.version; this.version.textContent = "V=$" + core.version;
this.modeUpdated();
}; };
RetroUI.prototype.modeUpdated = function() { RetroUI.prototype.newMode = function(isAuto) {
this.mode.textContent = "M=" + this.core.getCurrentMode(); this.mode.textContent = "M=" + (isAuto ? "FULL AUTO" : "NORMAL");
}; };
RetroUI.prototype.setImageText = function() { RetroUI.prototype.newImage = function(image) {
var image = this.core.currentImage;
if(!image) { if(!image) {
return; return;
} }
@ -397,19 +405,16 @@ RetroUI.prototype.setImageText = function() {
this.imageLink.href = image.source; this.imageLink.href = image.source;
}; };
RetroUI.prototype.setColourText = function(colour) { RetroUI.prototype.newColour = function(colour) {
HuesUI.prototype.setColourText.call(this, colour); HuesUI.prototype.newColour.call(this, colour);
this.colourIndex.textContent = "C=" + this.intToHex2(this.core.colourIndex); this.colourIndex.textContent = "C=" + this.intToHex2(this.core.colourIndex);
}; };
RetroUI.prototype.beat = function() { RetroUI.prototype.beat = function(beats, index) {
var beats = this.core.getBeatString();
var rest = beats.slice(1); var rest = beats.slice(1);
this.beatBar.textContent = ">>" + rest; this.beatBar.textContent = ">>" + rest;
this.beatCount.textContent = "B=" + this.intToHex3(index);
this.beatCount.textContent = "B=" + this.intToHex3(this.core.getSafeBeatIndex());
}; };
RetroUI.prototype.resize = function() { RetroUI.prototype.resize = function() {
@ -465,14 +470,13 @@ WeedUI.prototype.toggleHide = function() {
RetroUI.prototype.toggleHide.call(this, 'w'); RetroUI.prototype.toggleHide.call(this, 'w');
}; };
WeedUI.prototype.beat = function() { WeedUI.prototype.beat = function(beats, index) {
var beats = this.core.getBeatString();
var rest = beats.slice(1); var rest = beats.slice(1);
this.beatLeft.textContent = rest; this.beatLeft.textContent = rest;
this.beatRight.textContent = rest; this.beatRight.textContent = rest;
this.beatCount.textContent = "B=" + this.intToHex3(this.core.getSafeBeatIndex()); this.beatCount.textContent = "B=" + this.intToHex3(index);
if(["x", "o", "X", "O"].indexOf(beats[0]) != -1) { if(["x", "o", "X", "O"].indexOf(beats[0]) != -1) {
var beatCenter = document.createElement("div"); var beatCenter = document.createElement("div");
@ -684,6 +688,9 @@ ModernUI.prototype.initUI = function() {
this.listContainer.className = "hues-m-listcontainer"; this.listContainer.className = "hues-m-listcontainer";
this.root.appendChild(this.listContainer); this.root.appendChild(this.listContainer);
this.addCoreCallback("beat", this.beat.bind(this));
this.addCoreCallback("newmode", this.newMode.bind(this));
}; };
ModernUI.prototype.toggleHide = function() { ModernUI.prototype.toggleHide = function() {
@ -713,17 +720,15 @@ ModernUI.prototype.updateVolume = function(vol) {
} }
}; };
ModernUI.prototype.modeUpdated = function() { ModernUI.prototype.newMode = function(isAuto) {
if(this.core.isFullAuto) { if(isAuto) {
this.imageMode.innerHTML = '<i class="fa fa-pause"></i>'; // PAUSE; this.imageMode.innerHTML = '<i class="fa fa-pause"></i>'; // PAUSE;
} else { } else {
this.imageMode.innerHTML = "&#9654;"; // PLAY this.imageMode.innerHTML = "&#9654;"; // PLAY
} }
}; };
ModernUI.prototype.beat = function() { ModernUI.prototype.beat = function(beats, index) {
var beats = this.core.getBeatString();
this.currentBeat = beats[0]; this.currentBeat = beats[0];
var rest = beats.slice(1); var rest = beats.slice(1);
@ -739,7 +744,7 @@ ModernUI.prototype.beat = function() {
span.textContent = this.currentBeat; span.textContent = this.currentBeat;
this.beatCenter.appendChild(span); this.beatCenter.appendChild(span);
} }
this.beatCount.textContent = "B=" + this.intToHex4(this.core.getSafeBeatIndex()); this.beatCount.textContent = "B=" + this.intToHex4(index);
}; };
ModernUI.prototype.resize = function() { ModernUI.prototype.resize = function() {
@ -767,20 +772,20 @@ ModernUI.prototype.resizeImage = function() {
this.resizeElement(this.imageLink, this.imageName); this.resizeElement(this.imageLink, this.imageName);
}; };
ModernUI.prototype.setSongText = function() { ModernUI.prototype.newSong = function(song) {
HuesUI.prototype.setSongText.call(this); HuesUI.prototype.newSong.call(this, song);
if(!this.core.currentSong) { if(!song) {
return; return;
} }
this.resizeSong(); this.resizeSong();
}; };
ModernUI.prototype.setImageText = function() { ModernUI.prototype.newImage = function(image) {
HuesUI.prototype.setImageText.call(this); HuesUI.prototype.newImage.call(this, image);
if(!this.core.currentImage) { if(!image) {
return; return;
} }
@ -913,8 +918,8 @@ XmasUI.prototype.newLight = function(l, parent) {
return light; return light;
}; };
XmasUI.prototype.beat = function() { XmasUI.prototype.beat = function(beats, index) {
ModernUI.prototype.beat.call(this); ModernUI.prototype.beat.call(this, beats, index);
if(this.currentBeat != ".") { if(this.currentBeat != ".") {
this.lights.forEach(function(light, i, a) { this.lights.forEach(function(light, i, a) {
switch(this.currentBeat) { switch(this.currentBeat) {
@ -932,7 +937,7 @@ XmasUI.prototype.beat = function() {
} }
}; };
XmasUI.prototype.setColourText = function(colour) {}; XmasUI.prototype.newColour = function(colour) {};
XmasUI.prototype.blurUpdated = function(x, y) {}; XmasUI.prototype.blurUpdated = function(x, y) {};
XmasUI.prototype.updateTime = function(time) {}; XmasUI.prototype.updateTime = function(time) {};
@ -1012,8 +1017,8 @@ HalloweenUI.prototype.initUI = function() {
this.root.appendChild(this.vignette); this.root.appendChild(this.vignette);
} }
HalloweenUI.prototype.beat = function() { HalloweenUI.prototype.beat = function(beats, index) {
ModernUI.prototype.beat.call(this); ModernUI.prototype.beat.call(this, beats, index);
if (this.currentBeat != ".") { if (this.currentBeat != ".") {
var eyes = this.beatCenter.ownerDocument.createElement("div"); var eyes = this.beatCenter.ownerDocument.createElement("div");

Loading…
Cancel
Save