From 3ead2625a04225367750a6c582b29911f638852d Mon Sep 17 00:00:00 2001 From: Sebastien Benard Date: Mon, 9 Sep 2024 09:28:44 +0200 Subject: [PATCH] ADD AbstractEnumFlags --- src/dn/data/AbstractEnumFlags.hx | 91 ++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/dn/data/AbstractEnumFlags.hx diff --git a/src/dn/data/AbstractEnumFlags.hx b/src/dn/data/AbstractEnumFlags.hx new file mode 100644 index 00000000..84c1a778 --- /dev/null +++ b/src/dn/data/AbstractEnumFlags.hx @@ -0,0 +1,91 @@ +package dn.data; + +#if macro +import haxe.macro.Expr; +import haxe.macro.Context; +#end + +class AbstractEnumFlags { + var flagNames : Map; + var flagValues : Map = new Map(); + + function new(flagNames:Map) { + this.flagNames = flagNames; + } + + public inline function hasFlag(flag:T) { + return flagValues.exists(flag); + } + + public inline function setFlagOnce(flag:T) { + if( !hasFlag(flag) ) { + setFlag(flag); + return true; + } + else + return false; + } + + public inline function setFlag(flag:T, v=true) { + if( v ) + flagValues.set(flag,v); + else + flagValues.remove(flag); + } + + public inline function toggleFlag(flag:T) { + setFlag(flag, !hasFlag(flag)); + } + + public inline function getFlagValue(flag:T) { + return flagValues.exists(flag); + } + + public inline function removeFlag(flag:T) { + return flagValues.remove(flag); + } + + public function getActiveFlags() : Array { + var allFlags : Array = []; + for(f in flagValues.keys()) + allFlags.push(f); + return allFlags; + } + + public inline function getFlagName(flag:T) : String { + return flagNames.get(flag); + } + + public function clearAll() { + flagValues = new Map(); + } + + @:keep public function toString() : String { + var out = []; + for(f in flagValues.keys()) + out.push( getFlagName(f) ); + return "["+out.join(",")+"]"; + } + + + public static macro function createFromAbstractIntEnum(abstractEnumType:haxe.macro.Expr) { + var allValues = MacroTools.getAbstractEnumValuesForMacros(abstractEnumType); + + // Check enum underlying type + for(v in allValues) + switch v.valueExpr.expr { + case EConst(CInt(_)): + case _: Context.fatalError("Only abstract enum of Int is supported.", abstractEnumType.pos); + } + + // Build `0=>"ValueName"` expressions + var mapInitExprs = []; + for(v in allValues) + mapInitExprs.push( macro $e{v.valueExpr} => $v{v.name} ); + + // Build Map declaration as `[ 0=>"ValueName", 1=>"ValueName" ]` + var flagNamesExpr : Expr = { pos:Context.currentPos(), expr: EArrayDecl(mapInitExprs) } + return macro @:privateAccess new dn.data.AbstractEnumFlags( $flagNamesExpr ); + } + +} \ No newline at end of file