Skip to content

Instantly share code, notes, and snippets.

@MindScriptAct
Last active December 7, 2016 08:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MindScriptAct/1a65ad746ec00d6d1fecc4f45efcedba to your computer and use it in GitHub Desktop.
Save MindScriptAct/1a65ad746ec00d6d1fecc4f45efcedba to your computer and use it in GitHub Desktop.
As3 Enum class.
package utils.data {
import flash.utils.Dictionary;
import flash.utils.getQualifiedClassName;
/**
* Base class for creation of enumerable type-safe constants. (Similar to Enum in c++)
*
* @Example:
*
* package {
* import utils.data.Enum;
* public class MyEnum extends Enum {
* {Enum.initEnum(MyEnum);}
*
* public static const MY_CONSTANT:MyEnum = new MyEnum();
*
* }}
*
* @author Modified by Raimundas Banevicius, Created by Scott Bilas (http://scottbilas.com/blog/ultimate-as3-fake-enums/)
*/
public class Enum {
// store enum definitions by type.
private static var enumRegister:Dictionary = new Dictionary(); //* EnumConstants by typename */
// stores enum objects constructed
private static var pendingRegister:Dictionary = new Dictionary(); //* Vector.<Enum> by typename */
// Enum constant name
private var _name:String = null;
// Enum constant index
private var _index:int = -1;
/**
* Base clas yoru yoru custom Enum constant collections.
* @param index Index of your contant enum class. (Pass -1 to automatically assign next index.)
*/
public function Enum(index:int = -1) {
var typeName:String = getQualifiedClassName(this);
// Enum should not be used with new, outside of enum class.
if (enumRegister[typeName] != null) {
throw new Error("Enum constants should only be constructed as static consts in their own enum class (type=’" + typeName + "’)");
}
var constants:Vector.<Enum> = pendingRegister[typeName];
if (constants == null) {
constants = new <Enum>[];
pendingRegister[typeName] = constants;
}
if (index >= 0) {
while (pendingRegister.length <= index) {
pendingRegister.push(null);
}
if (constants[index] != null) {
throw Error("You cant creat more then one Enum constant with same index in class " + typeName);
}
_index = index;
constants[index] = this;
} else {
_index = constants.length;
constants.push(this);
}
}
public function get name():String {
return _name;
}
public function get index():int {
return _index;
}
public function toString():String {
return String(_index);
}
//#######################
//####### STATIC
//#######################
/**
* Get all enum constants by type
* @param enumClass Enum class type
* @return vector with all enums.
*/
public static function getAll(enumClass:Class):Vector.<Enum> {
var constants:EnumConstants = enumRegister[getQualifiedClassName(enumClass)];
if (constants != null) {
// return a copy to prevent caller modifications
return constants.allEnums.slice();
}
return null;
}
/**
* Get constant by its class and name.
* @param enumClass Enum class.
* @param name Enum name
* @return Enum object.
*/
public static function getByName(enumClass:Class, name:String):* {
var constants:EnumConstants = enumRegister[getQualifiedClassName(enumClass)];
if (constants != null) {
return constants.enumByName[name];
}
return null;
}
/**
* Get constant by its class and index.
* @param enumClass Enum class.
* @param index Enum index
* @return Enum object.
*/
public static function getByIndex(enumClass:Class, index:int):* {
var constants:EnumConstants = enumRegister[getQualifiedClassName(enumClass)];
if (constants != null) {
if (constants.allEnums.length > index) {
return constants.allEnums[index];
}
}
return null;
}
/**
* Initialize Enum class. In your custom class use static constructor : {initEnum(MyEnum);}
* @param enumClass Enum class.
*/
protected static function initEnum(enumClass:Class):void {
var typeName:String = getQualifiedClassName(enumClass);
// check if type is not already initialized.
if (enumRegister[typeName] != null) {
trace("WARNING: Enum initialized twice (type=’" + typeName + "’)");
} else {
var constants:Vector.<Enum> = pendingRegister[typeName];
if (constants == null) {
// no constant defined.
trace("WARNING: Enum " + typeName + " hase no constants!");
} else {
// process constants
var type:XML = flash.utils.describeType(enumClass);
for each (var constant:XML in type.constant) {
// this will fail to coerce if the type isn’t inherited from Enum
var enumConstant:Enum = enumClass[constant.@name];
// check if type matches.
var enumConstantType:* = Object(enumConstant).constructor;
if (enumConstantType != enumClass) {
throw new Error("Constant type " + enumConstantType + "does not match it's enum class " + enumClass);
}
enumConstant._name = constant.@name;
}
// now seal it
delete pendingRegister[typeName];
enumRegister[typeName] = new EnumConstants(constants);
}
}
}
}
}
import flash.utils.Dictionary;
import utils.data.Enum;
// private support class
class EnumConstants {
public var allEnums:Vector.<Enum>;
public var enumByName:Dictionary = new Dictionary();
public function EnumConstants(allEnums:Vector.<Enum>) {
this.allEnums = allEnums;
for (var i:int = 0; i < allEnums.length; ++i) {
var enumConstant:Enum = allEnums[i];
enumByName[enumConstant.name] = enumConstant;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment