Abstractions
authorCameron Ball <c.ball1729@gmail.com>
Thu, 23 Apr 2015 09:29:04 +0000 (17:29 +0800)
committerCameron Ball <c.ball1729@gmail.com>
Thu, 23 Apr 2015 09:29:04 +0000 (17:29 +0800)
.gitignore
BaseRegistry.as [new file with mode: 0644]
ConfigParserRegistry.as [new file with mode: 0644]
IRegistry.as [new file with mode: 0644]
MusicBox.as
Overlay.as
Registry.as [new file with mode: 0644]
Util.as

index 95bd463..d8c3ba5 100644 (file)
@@ -1,3 +1,4 @@
 *.fla
 *.swf
-StreamInfo.txt
\ No newline at end of file
+StreamInfo.txt
+audio
\ No newline at end of file
diff --git a/BaseRegistry.as b/BaseRegistry.as
new file mode 100644 (file)
index 0000000..07a3cac
--- /dev/null
@@ -0,0 +1,40 @@
+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;
+               }
+       }
+}
diff --git a/ConfigParserRegistry.as b/ConfigParserRegistry.as
new file mode 100644 (file)
index 0000000..a30f486
--- /dev/null
@@ -0,0 +1,76 @@
+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();
+               }
+       }
+}
diff --git a/IRegistry.as b/IRegistry.as
new file mode 100644 (file)
index 0000000..1a4e4cc
--- /dev/null
@@ -0,0 +1,12 @@
+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;
+       }
+       
+}
index ebec49c..7d1a024 100644 (file)
@@ -1,21 +1,50 @@
 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;
+                               });
                        }
+                       
                }
        }
        
index d4d74a5..db74c99 100644 (file)
@@ -5,27 +5,30 @@
 
        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);
                }
 
        }
diff --git a/Registry.as b/Registry.as
new file mode 100644 (file)
index 0000000..b424963
--- /dev/null
@@ -0,0 +1,42 @@
+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);
+               }
+       }
+       
+}
diff --git a/Util.as b/Util.as
index 6f7fcae..b4074b6 100644 (file)
--- a/Util.as
+++ b/Util.as
@@ -1,6 +1,7 @@
 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) {
@@ -9,6 +10,63 @@
                        
                        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;
+               }
 
        }