@Update – Please note that this post is considered deprecated – please refer to: http://www.jonnyreeves.co.uk/2008/06/actionscript-20-configuration-class/
I like all of my apps to be as flexible as possible; as a result I tend to make nearly every aspect configurable. There are quite a few approaches to Configuring your Flash app, with many programmers settling for putting _root variables on the first frame of the .fla file. Sure, this works, but it does not enable script type checking at run-time and it also means that you can’t feed values in as flashVars.
To combat these problems, I created a simple Configuration base class and a Factory method which allows you to access it as a singleton:
Config (Singleton) Class
/** * Config.as * John Reeves (www.jonnyreeves.co.uk) * * Actionscript 2.0 Singleton Configuration Class. This class will load * specified config and then allow you to read/write from it at run-time. */ import BaseConfig; class Config { /** * @var _instance * Instance of config, created only by load() method. */ private var _instance:Config; /** * Private constructor, as this class is a Singleton we don't * want instances to be be created outside of the Factory * method (load()). */ private function Config() { } /** * Factory method for loading the desired configuration instance. * Extend this method out if you intend to have multiple * Configurations accessible at compile time. * * @param config Configuration you wish to load. */ static public function load(config:String):Void { // Check if configuration has already loaded. if (_configuration !== undefined) { throw new Error('Config::load() -> Configuration' +' has already been loaded.'); } switch (config.toString()) { case 'base': _configuration = new BaseConfig(); break; default: throw new Error('Config::load() -> Invalid' + ' configuration requested'); } } /** * Read a configuration value from the loaded instance. * * @param key Property you wish to read from loaded instance. */ static public function read(key:String) { // Check user has loaded a config. if (_configuration == undefined) { throw new Error('Config::read() -> No configuration' +' loaded, please Config.load() one first.'); } // Using the Array access method. return _configuration[key]; } /** * Write to the currently loaded configuration instance. * * @param key Property you wish to write * @param value New value for above Property */ static public function write(key:String, value:Object) { if (_configuration == undefined) { throw new Error('Config::read() -> No configuration' +' loaded, please use Config.load() first.'); } // Only write values if the property exists in the Config's // Constructor, this is a nasty ActionScript 2.0 hack. if (_configuration.hasOwnProperty("_" + key)) { // Using array access method, will call custom setter. _configuration[key] = value; } // Refusing to write key, add any error handling here. else { trace ('Config.write() -> Invalid Property: ' +key.toString()); } } }
Example Configuration Class (set your values here)
/** * BaseConfiguration.as * John Reeves (www.jonnyreeves.co.uk) * * Base configuration class, should you need even more flexibility * at run-time you can extend this and add to the Factory Method in * the Config class. * * This file contains the actual configuration values for your application * complete with Strict Type Checking at both Compile and Run time. */ class BaseConfiguration { /** * @var _exampleProtectedString * This is an example string which has a default value but can't be * over-ridden at run time with a flashVar. (see Constructor) */ protected var _exampleProtectedString:String = 'default value'; /** * @var _exampleString * This is an example string, it doesn't have a default value but * can be over-ridden at run time with a flashVar. (see Constructor) */ private var _exampleString:String; /** * @var _exampleNumber * private var _examplePrivateNumber * This is an example number, it has a default value and can be * over-ridden by a flashVar at runtime. */ private var _exampleNumber:Number = 1234; /** * Constructor * Any properties defined here can be over-ridden at run-time by flashVars * embedded in the HTML. Any properties not defined will be "protected" */ public function BaseConfiguration() { // These props are modifiy-able at runtime with flashVars. exampleString = this._exampleString; exampleNumber = this._exampleNumber; // If the next line were un-commented, we would be able to // modify exampleProtectedString at runtime with a flashVar // exampleProtectedString = this._exampleProtectedString; } /** * Getter and Setter for exampleString */ public function get exampleString():String { return this._exampleString; } public function set exampleString(value:String):Void { // Run time type checking. if (value !== undefined || value !== null) { this._exampleString = value.toString(); } } /** * Getter and Setter for exampleProtectedString */ public function get exampleProtectedString():String { return this._exampleProtectedString; } public function set exampleProtectedString(value:String):Void { // Run time type checking. if (value !== undefined || value !== null) { this._exampleString = value.toString(); } } /** * Getter and Setter for exampleNumber */ public function get exampleNumber():Number { return this._exampleNumber; } public function set exampleNumber(value:Number):Void { // Run time type checking. if (!isNaN(value)) { this._exampleNumber = Number(value); } } }
Example Script which Reads and Writes from the Config
/** * Main.as * John Reeves (www.jonnyreeves.co.uk) * * Example application which will use our Config class to read a value * and write any flashVars which were passed in at run time. * * Please note that this is psudo code and probably wont' compile. */ import Config; class Main { /** * Constructor, just an example of using the config class. */ public function Main() { // Load 'base' config Config.load('base'); // Trace out exampleString trace(Config.read('exampleNumber'); // outputs "1234" // Set an example flashVar (_root), this can also be done // in the HTML using the flashVar param, or // using the URI param: move="main.swf?exampleNumber=4321" _root.exampleNumber = 4321 // Load in all flashVars from the _root and set them for (var flashVar in _root) { // Loop each _root var and set it in our config Config.write(flashVar, unescape(_root[flashVar])); } trace (Config.read('exampleNumber')); // outputs "4321" // And with a string (outputs "default Value") trace (Config.read('exampleProtectedString')) // try to over-write a "protected" value (one not set in the // BaseConfiguration constructor. _root.exampleProtectedString = "a new value"; // Load in all flashVars from _root again... for (var flashVar in _root) { // Loop each _root var and set it in our config Config.write(flashVar, unescape(_root[flashVar])); } // as it's protected, it won't have written it trace (Config.read('exampleProtectedString') // still outputs // "default value" } }
So, as I hope you can see, usage is pretty straight forward, and as the Config class is a singleton, and the read() and write() methods are both static, they can be accessed from anywhere in your code (as long as you import Config.as)
Download all 3 .as files above: Actionscript 2.0 Configuration Class .zip