*.fla
*.swf
-StreamInfo.txt
\ No newline at end of file
+StreamInfo.txt
+audio
\ No newline at end of file
--- /dev/null
+package {
+ import flash.events.Event;
+ import flash.events.EventDispatcher;
+
+ public class BaseRegistry extends EventDispatcher implements IRegistry {
+
+ private var stage:Object;
+ private var head:Object;
+ private var lastUpdated:Array;
+
+ public static const REGISTRY_UPDATE = "registry_update";
+
+ public function BaseRegistry() {
+ this.stage = {};
+ this.head = {};
+ this.lastUpdated = new Array();
+ }
+
+ public function add(obj:Object):void {
+ this.stage = Util.extend(this.stage, obj);
+ }
+
+ public function commit():void {
+ if(!Util.objectIsEmpty(this.stage)) {
+ this.head = Util.extend(this.head, this.stage);
+ this.lastUpdated = Util.toPropertyChains(this.stage);
+ this.stage = {};
+ this.dispatchEvent(new Event(REGISTRY_UPDATE));
+ }
+ }
+
+ public function get(propChain:String):* {
+ return Util.resolvePropertyChain(propChain, this.head);
+ }
+
+ public function getLastUpdated():Array {
+ return this.lastUpdated;
+ }
+ }
+}
--- /dev/null
+package {
+ import flash.events.Event;
+ import flash.events.EventDispatcher;
+ import flash.net.*
+
+ public class ConfigParserRegistry extends BaseRegistry {
+ private var request:URLRequest;
+ private var loader:URLLoader;
+ private var fileLock:Boolean;
+ private var loadCallback:Function;
+
+
+ public function ConfigParserRegistry(fileName:String) {
+ this.fileLock = false;
+ this.request = new URLRequest(fileName);
+ this.loader = new URLLoader();
+ }
+
+ public function parse() {
+ if(!this.fileLock) {
+ this.loadCallback = this.onLoaded(this);
+
+ loader.addEventListener(Event.COMPLETE, this.loadCallback);
+ this.fileLock = true;
+ this.loader.load(this.request);
+ } else {
+ trace("Lock active, not doing anything.");
+ }
+ }
+
+ private function releaseLock() {
+ this.fileLock = false;
+ }
+
+ private function onLoaded(configParser:ConfigParserRegistry):Function {
+ return function(e:Event):void {
+ //Deal with windows style line endings, and tabs.
+ var lines = configParser.loader.data.replace(/(\t|\r)/gi, "").split("\n");
+ configParser.parseVars(lines);
+ configParser.releaseLock();
+ configParser.loader.removeEventListener(Event.COMPLETE, configParser.loadCallback);
+ }
+ }
+
+ private function parseVars(lines:Array) {
+ var section:String = null;
+ var matches:Array;
+ var keyValue:Array;
+ var dotDelim:String;
+
+ for each(var line in lines) {
+ // I'm gonna hate myself for this in a few weeks
+ section = ((matches = line.match(/\[(\w+)\]/)) && matches[1]) || section;
+ keyValue = line.split("=", 2).map(Util.trim);
+
+ if(keyValue.length == 2) {
+ dotDelim = section ? section + "." + keyValue[0] : keyValue[0];
+ if(this.get(dotDelim) != keyValue[1]) {
+ var obj:Object = {};
+ if(section) {
+ obj[section] = new Object();
+ obj[section][keyValue[0]] = keyValue[1];
+
+ } else {
+ obj[keyValue[0]] = keyValue[1];
+ }
+
+ this.add(obj);
+ }
+ }
+ }
+
+ this.commit();
+ }
+ }
+}
--- /dev/null
+package {
+ import flash.events.IEventDispatcher;
+
+ public interface IRegistry extends IEventDispatcher
+ {
+ function add(obj:Object):void;
+ function commit():void;
+ function get(propChain:String):*;
+ function getLastUpdated():Array;
+ }
+
+}
package {
+ import flash.media.Sound;
+ import flash.media.SoundChannel;
+ import flash.net.URLRequest;
import flash.events.Event;
public class MusicBox {
private var streamInfo:StreamInfo;
- private var trackNames:Array;
-
+ private var tracks:Array;
+ private var playing:Boolean;
+ private var looping:Boolean;
+ private var shuffling:Boolean;
+
public function MusicBox(streamInfo:StreamInfo) {
this.streamInfo = streamInfo;
+ this.tracks = new Array();
+ this.playing = false;
+ this. looping = false;
+ this.shuffling = false;
this.streamInfo.addEventListener(StreamInfo.INFO_UPDATE, this.setTrackNames);
}
+
+ public function play() {
+ this.playing = true;
+ }
private function setTrackNames(e:Event) {
- this.trackNames = this.streamInfo.getStreamParameter("MusicBoxTracks").split(',').map(Util.trim);
- for(var i in this.trackNames) {
- trace(i + " " + this.trackNames[i]);
+ var trackNames = this.streamInfo.getStreamParameter("MusicBoxTracks").split(',').map(Util.trim);
+ for each(var trackName in trackNames) {
+ var track:Object = {name: trackName, sound: false}
+ this.tracks.push(track);
+ }
+
+ this.loadTracks();
+ }
+
+ private function loadTracks() {
+ for each(var track in this.tracks) {
+ var snd:Sound = new Sound();
+ snd.load(new URLRequest(this.streamInfo.getStreamParameter("MusicBoxBase") + "/" + track.name));
+
+ snd.addEventListener(Event.COMPLETE, function(e:Event) {
+ track.sound = snd;
+ });
}
+
}
}
public class Overlay extends flash.display.MovieClip {
- private var streamInfo:StreamInfo;
- private var musicBox:MusicBox;
+ private var conf:ConfigParserRegistry;
+ //private var musicBox:MusicBox;
/*
* After doing some science, 50ms seems to be roughly the time it takes
* for a request to complete and for the locking to not happen.
*/
- private const REFRESH_RATE = 50;
+ private const REFRESH_RATE = 1000;
public function Overlay() {
- this.streamInfo = new StreamInfo("Cam", REFRESH_RATE);
- this.musicBox = new MusicBox(this.streamInfo);
+ this.conf = new ConfigParserRegistry("StreamInfo.txt");
+ setInterval(this.conf.parse, REFRESH_RATE);
+ this.conf.addEventListener(BaseRegistry.REGISTRY_UPDATE, this.updated);
- this.streamInfo.addEventListener(StreamInfo.INFO_UPDATE, this.streamInfoUpdated);
+
+ //this.streamInfo = new StreamInfo("Cam", REFRESH_RATE);
+ //this.musicBox = new MusicBox(this.streamInfo);
+
+ //this.streamInfo.addEventListener(StreamInfo.INFO_UPDATE, this.streamInfoUpdated);
}
- private function streamInfoUpdated(e:Event) {
- test.text = "hello";
- for each(var i in this.streamInfo.getLastUpdated()) {
- test.text += i + " has been updated to " + this.streamInfo.getStreamParameter(i) + "\n";
- }
+ private function updated(e:Event) {
+ var cam:Object = this.conf.get('Cam');
+ trace(cam.MusicBoxBase);
}
}
--- /dev/null
+package {
+
+ import flash.events.EventDispatcher;
+ import flash.sampler.Sample;
+
+ public class Registry implements IRegistry extends EventDispatcher {
+
+ private var stage:Object;
+ private var head:Object;
+ private var lastUpdated:Array;
+
+ public static const REGISTRY_UPDATE = "registry_update";
+
+ public function Registry() {
+ this.stage = {};
+ this.head = {};
+ }
+
+ public function add(obj:Object):void {
+ this.stage = Util.merge(this.stage, obj);
+ }
+
+ public function commit():void {
+ this.head = Util.extend(this.head, this.stage);
+ this.lastUpdated = Util.toPropertyChains(this.stage);
+ this.stage = {};
+ }
+
+ public function get(propChain:String):* {
+ return Util.resolvePropertyChain(propChain, this.head);
+ }
+
+ public function getLastUpdated():Array {
+ return this.lastUpdated;
+ }
+
+ public function get(member:String) {
+ return Util.resolvePropertyChain(member, this.head);
+ }
+ }
+
+}
package {
+ import flash.sampler.StackFrame;
- public class Util {
+ public final class Util {
public static function trim(str:String, index:int, array:Array):String {
if(str == null) {
return str.replace(/^\s+|\s+$/g, "");
}
+
+ //Might be better making an abstract class with this method and extending my objs
+ //Extend A with Bs properties. Properties in A will be over written with properties
+ //in B if they exist in both.
+ public static function extend(objA:Object, objB:Object):Object {
+ objA = objA || {};
+ for(var prop:String in objB) {
+ if(typeof(objB[prop]) === "object") {
+ objA[prop] = extend(objA[prop], objB[prop]);
+ } else {
+ objA[prop] = objB[prop];
+ }
+ }
+
+ return objA;
+ }
+
+ //Might be better making an abstract class with this method and extending my objs
+ public static function resolvePropertyChain(dotDelimited:String, obj:Object):* {
+ var properties:Array = dotDelimited.split('.');
+ //var field:String = properties.pop();
+ for each(var prop:String in properties) {
+ obj = obj.hasOwnProperty(prop) && obj[prop];
+ }
+
+ return obj;
+ }
+
+ public static function toPropertyChains(obj:Object):Array {
+ function chainFrom(chain:Array, obj:Object, atEnd:Function) {
+ if(typeof(obj) === "object") {
+ for(var prop:String in obj) {
+ chain.push(prop);
+ chainFrom(chain, obj[prop], atEnd);
+ --chain.length;
+ }
+ } else {
+ atEnd(chain);
+ }
+ }
+
+ var res:Array = [];
+ chainFrom([], obj, function(chain:Array) {
+ res.push(chain.join("."));
+ });
+
+ return res;
+ }
+
+ //Might be better making an abstract class with this method and extending my objs
+ public static function objectIsEmpty(obj:Object):Boolean {
+ for(var s:String in obj) {
+ return false;
+ }
+
+ return true;
+ }
}