Actionscript 2.0 Configuration Class (read/write)
11th February, 2008 – 10:54 pm@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