Last active
December 7, 2016 08:07
-
-
Save MindScriptAct/1a65ad746ec00d6d1fecc4f45efcedba to your computer and use it in GitHub Desktop.
As3 Enum class.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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