====== Les Enums en AS3 ======
{{tag>as3 flex}}
Il existe différentes implémentations possibles concernant les [[http://en.wikipedia.org/wiki/Enumerated_type|Enums]] en AS3, avec inconvenients et avantages.
Pour ma part, j'ai besoin de garder la possibilité de transférer cet Enum via une LocalConnection, ou de le garder dans un SharedObject, c'est primordial. Donc, dans mon cas, j'ai autorisé l'instanciation de ma classe Enum, pour pouvoir ensuite faire un toEnum dessus et recupérer la constante voulue, cependant comme vous allez le voir, c'est facile à changer.
J'ai volontairement déplacer une constante sous le constructeur, pour vous montrer que cela n'a aucun rapport avec le systeme d'Enum qui se sert de code en ligne durant la compilation de classe pour lancer une erreur dans le constructeur à un certain moment.
===== La Classe MyEnum =====
package nc.org.core.enum
{
import flash.errors.IllegalOperationError;
import flash.utils.Dictionary;
import nc.org.core.utils.ObjectUtils;
public final class MyEnum
{
public static const DOMINATING : MyEnum = new MyEnum ('dominating');
public static const GODLIKE : MyEnum = new MyEnum ('godlike');
private var _value : *;
public function MyEnum (value:*) : void
{
/*
if(ObjectUtils.hasConst(this)) throw new IllegalOperationError (this+' you cannot create new MyEnum');
*/
_value = value;
}
public static const MONSTERKILL : MyEnum = new MyEnum ('monsterkill');
public function get value () : *
{
return _value;
}
public function get isEnum () : Boolean
{
return !ObjectUtils.hasConst(this) && this in ObjectUtils.getConstsMap(this);
}
public function get toEnum () : MyEnum
{
return EnumUtils.getConstByValue(this);
}
}
}
===== La Classe ObjectUtils =====
package nc.org.core.utils
{
import flash.utils.*;
public final class ObjectUtils
{
private static const registry : Dictionary = new Dictionary (true);
public static function getConstsMap (value:*) : Dictionary
{
var c : Class = toClass(value);
if (registry[c] == null)
{
if (hasConst(c))
{
var x : XML = describeType(c),
d : Dictionary = new Dictionary (),
node : XML;
for each (node in x.constant)
{
d[value[node.@name]] = value[node.@name];
}
registry[value] = d;
}
}
return registry[c] == null ? new Dictionary () : registry[value] as Dictionary;
}
public static function getConstsArray (value:*) : Array
{
var a : Array = new Array (),
c : Class = toClass(value),
d : Dictionary = registry[c] == null ? getConstsMap(c) : registry[value] as Dictionary,
i : *;
if (d != null) for each (i in d) a.push(i);
return a;
}
public static function hasConst (value:*) : Boolean
{
var c : Class = toClass(value);
if(registry[c] != null) return true;
var x : XML = describeType(c),
node :XML,
n : int = 0;
for each (node in x.constant) n++;
return n != 0;
}
public static function toClass (value:*) : Class
{
return value is Class ? value as Class : getDefinitionByName(getQualifiedClassName(value)) as Class;
}
}
}
package nc.org.core.utils
{
import nc.org.core.enum.MyEnum;
import flash.utils.Dictionary;
public final class EnumUtils
{
private static const registry : Dictionary = new Dictionary (true);
public static function getConstByValue(instance:MyEnum) : MyEnum
{
var c : Class = ObjectUtils.toClass(instance);
if (registry[c] == null)
{
if (ObjectUtils.hasConst(c))
{
var d : Dictionary = ObjectUtils.getConstsMap(c),
e : Enum,
value : *,
r : Dictionary = new Dictionary (true);
for each (e in d) r[e.value] = e;
registry[c] = r;
return r[instance.value] as MyEnum;
}
} else {
return (registry[c] as Dictionary)[instance.value] as MyEnum;
}
return null;
}
}
}
===== Un Exemple =====
trace ('const : '+MyEnum.DOMINATING.isEnum);
var fake : MyEnum = new MyEnum ('dominating');
trace ('fake : '+fake.isEnum);
trace ('fake : '+(fake.toEnum == MyEnum.DOMINATING))
/*
const : true
fake :false
fake : true
*/
~~DISCUSSION~~