-
-
Save jonongjs/133e5d99f3d3d47d4b44 to your computer and use it in GitHub Desktop.
Macro based entity.
This file contains 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; | |
import haxe.macro.Expr; | |
#if macro | |
using haxe.macro.Context; | |
using haxe.macro.Tools; | |
#end | |
class Entity { | |
#if macro | |
static var counter = 0; | |
static var mapping = new Map(); | |
static function getId(type:haxe.macro.Type) { | |
var name = type.toString(); | |
if (!mapping.exists(name)) | |
mapping[name] = counter++; | |
return mapping[name]; | |
} | |
#end | |
var registry:Map<Int, Dynamic>; | |
public function new() { | |
this.registry = new Map(); | |
} | |
macro public function add(ethis:Expr, component:Expr) { | |
var id = getId(component.typeof()); | |
return macro @:pos(component.pos) { | |
var entity = $ethis, | |
component = $component; | |
@:privateAccess (entity.registry[$v{id}] = component); | |
entity; | |
}; | |
} | |
macro public function get<T>(ethis:Expr, component:ExprOf<Class<T>>):ExprOf<T> { | |
var type = (macro @:pos(component.pos) { | |
function ___<T>(c:Class<T>):T return null; | |
___($component); | |
}).typeof(); | |
var id = getId(type), | |
ct = type.toComplexType(); | |
return macro @:pos(component.pos) (@:privateAccess ($ethis).registry[$v{id}] : $ct); | |
} | |
} |
This file contains 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
typedef FruitBasket = Entity | |
class Fruit { | |
public function new() {} | |
} | |
class Apple extends Fruit { | |
static public var name = 'apple'; | |
// other vars | |
public var someAppleVar = 'defaultApple'; | |
} | |
class Pear extends Fruit { | |
static public var name = 'pear'; | |
// other vars | |
public var somePearVar = 'defaultPear'; | |
} | |
class FruitBasketTest { | |
static function main() { | |
var fruitBasket = new FruitBasket(); | |
fruitBasket.add(new Apple()); | |
fruitBasket.add(new Pear()); | |
trace(fruitBasket.get(Apple).someAppleVar); | |
trace(fruitBasket.get(Pear).somePearVar); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment