AS 3 Settings Utility

Looking for a good utility for loading in xml config files and keeping variable’s natively typed? Well, I thought I would share this class also based on the same concept as my XML Proxy Class adapted from the AS 3 Design Patterns by Joey Lott and Danny Patterson.

Here is the class itself, and below is a sample of the xml structure as well as how to implement it.

package {

        import flash.events.Event;
        import flash.events.EventDispatcher;
        import flash.events.IEventDispatcher;
        import flash.net.URLLoader;
        import flash.net.URLRequest;
        import flash.utils.Proxy;
        import flash.utils.flash_proxy;

        dynamic public class Settings extends Proxy implements IEventDispatcher {

                public static const INIT:String = "init";
                private static var __instance:Settings;
                private var eventDispatcher:EventDispatcher;
                private var data:XML;
                private var urlLoader:URLLoader;

                public function get isLoaded():Boolean {
                        return data != null;
                }

                public function Settings(enforcer:SingletonEnforcer) {
                        eventDispatcher = new EventDispatcher();
                }

                private function onXMLDataLoaded(event:Event):void {
                        data = XML(urlLoader.data);
                        dispatchEvent(new Event(Settings.INIT, true, true));
                }

                public static function get instance ():Settings{
                        if(Settings.__instance == null) {
                                Settings.__instance = new Settings(new SingletonEnforcer());
                        }
                        return Settings.__instance;
                }

                /**
                 * @depricated
                 **/

                public static function getInstance():Settings {
                        return instance;
                }

                flash_proxy override function getProperty(name:*):* {
                        var temp_data:XMLList = data.property.(@id == String(name));
                        switch(temp_data.@type.toString())
                        {
                            case "string":
                                return temp_data.toString();
                                break;
                            case "number":
                                return Number(temp_data);
                                break;
                            case "array":
                                var temp_array:Array = temp_data.toString().split(",");
                                return temp_array;
                                break;
                            default:
                                return temp_data;
                                break;
                        }
                }

                public function loadSettings(url:String):void {
                        var urlRequest:URLRequest = new URLRequest(url);
                        urlLoader = new URLLoader();
                        urlLoader.addEventListener(Event.COMPLETE, onXMLDataLoaded);
                        urlLoader.load(urlRequest);
                }

                public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, weakRef:Boolean = false):void {
                        eventDispatcher.addEventListener(type, listener, useCapture, priority, weakRef);
                }

                public function dispatchEvent(event:Event):Boolean {
                        return eventDispatcher.dispatchEvent(event);
                }

                public function hasEventListener(type:String):Boolean {
                        return eventDispatcher.hasEventListener(type);
                }

                public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void {
                        eventDispatcher.removeEventListener(type, listener, useCapture);
                }

                public function willTrigger(type:String):Boolean {
                        return eventDispatcher.willTrigger(type);
                }

        }

}

class SingletonEnforcer {}

So how does this thing work? Well its simple, you start with an xml file that looks like this:

< ?xml version="1.0" encoding="UTF-8"?>
<settings>
        <property id="version" type="string">< ![CDATA[1.0.0]]></property>
        <property id="debug" type="boolean">false</property>
        <property id="timer" type="number" >8000</property>
        <property id="list" type="array" >< ![CDATA[item1,item2,item3]]></property>
</settings>

Notice how I am typing the variables. This class will handle String, Number, Array (Converts Strings into Array) and XML (Default Type). Here is a sample of how to load a config file and get a setting’s value:

import Settings;

Settings.instance.loadSettings(config_xml);
Settings.instance.addEventListener(Settings.INIT, load_team_code);

function settings_loaded(event:Event):void{
        trace("Settings Loaded");
        trace("Version "+Settings.instance.version;
}

See how easy that was!

  • good one
  • thank you.
  • In production code I add in custom error events and listeners. Since most of this stuff on this site represents sketches of my classes I don't really put that stuff in. Also, in most projects the error handling is custom I tend to extend these base classes and write my error checking on top of the extended class. Hope that helps, let me know if you have specific ares of error checking you need in this class?
  • Dave
    Nice work. I was having problems converting my AS2 config utility to AS3, so this is much appreciated. Thanks!

    However, how do you handle errors? What happens if there is a load error or something?
  • What else would you like me to go over? I actually use this class in all my projects now and have not changed the code at all. Maybe I can do a post on how I use it to configure stuff inside the application?
  • I would like to see a continuation of the topic
blog comments powered by Disqus