diff --git a/demo/src/demo/Demo.hx b/demo/src/demo/Demo.hx index 146a858..50a0d6d 100644 --- a/demo/src/demo/Demo.hx +++ b/demo/src/demo/Demo.hx @@ -1,5 +1,6 @@ package demo; +import haxework.provider.Provider; import demo.dispatch.DemoDispatcher; import demo.popup.ColorPopup; import demo.popup.FontPopup; @@ -45,6 +46,8 @@ class Demo extends App implements DemoListener { public static function main() { L.push(new TraceLogger()); + trace("!", Provider.instance.factories); + var app = new Demo(new AppTheme()); app.resources.image.put("logo", HaxeLogo.resolve()); app.start(new DemoView()); diff --git a/src/main/haxework/App.hx b/src/main/haxework/App.hx index 7e866da..11996c8 100644 --- a/src/main/haxework/App.hx +++ b/src/main/haxework/App.hx @@ -4,10 +4,6 @@ import flash.Lib; import haxework.animate.Animate; import haxework.animate.FadeAnimate; import haxework.animate.UnFadeAnimate; -import haxework.net.manage.ILoaderManager; -import haxework.net.manage.LoaderManager; -import haxework.resources.IResources; -import haxework.resources.Resources; import haxework.view.IView; import haxework.view.popup.PopupManager; import haxework.view.Root; @@ -17,15 +13,10 @@ class App { @:provide var app:App; @:provide var theme:ITheme; - @:provide var resources:IResources; - @:provide var loaderManager:ILoaderManager; @:provide var popupManager:PopupManager; public function new(?theme:ITheme) { this.theme = theme; - resources = new Resources(); - loaderManager = new LoaderManager(); - popupManager = new PopupManager(); popupManager.showAnimateFactory = function(v) return new UnFadeAnimate(v); popupManager.closeAnimateFactory = function(v) return new FadeAnimate(v); app = this; diff --git a/src/main/haxework/macro/ClassProvideMacro.hx b/src/main/haxework/macro/ClassProvideMacro.hx new file mode 100644 index 0000000..55108e9 --- /dev/null +++ b/src/main/haxework/macro/ClassProvideMacro.hx @@ -0,0 +1,20 @@ +package haxework.macro; + +import haxe.macro.Expr; +import haxe.macro.Type; + +class ClassProvideMacro extends ClassTypeMacro { + + public static var bundle(default, null):Array<{key: ClassType, value: ClassType}> = []; + + public function new() { + super(":provide"); + } + + override public function apply(classType:ClassType, fields:Array):Array { + var meta = MacroUtil.getClassMeta(classType, metaName); + var valueType = meta.params.length == 0 ? classType : MacroUtil.getExprClassType(meta.params[0]); + bundle.push({key: classType, value: valueType}); + return super.apply(classType, fields); + } +} diff --git a/src/main/haxework/macro/DispatcherMacro.hx b/src/main/haxework/macro/DispatcherMacro.hx index 6f2dc4f..da47f81 100644 --- a/src/main/haxework/macro/DispatcherMacro.hx +++ b/src/main/haxework/macro/DispatcherMacro.hx @@ -23,10 +23,7 @@ class DispatcherMacro extends ClassTypeMacro { override public function apply(classType:ClassType, fields:Array):Array { var result:Array = fields.slice(0); var typeName = ExprTools.toString(classType.meta.extract(metaName)[0].params[0]); - var type:ClassType = switch Context.getType(typeName) { - case TInst(t, _): t.get(); - case _: null; - } + var type:ClassType = MacroUtil.getExprClassType(classType.meta.extract(metaName)[0].params[0]); var fields = type.fields.get(); for (field in fields) { var argsTypes:Array = switch field.type { diff --git a/src/main/haxework/macro/FieldMacro.hx b/src/main/haxework/macro/FieldMacro.hx index 0948554..946ba6e 100644 --- a/src/main/haxework/macro/FieldMacro.hx +++ b/src/main/haxework/macro/FieldMacro.hx @@ -2,7 +2,7 @@ package haxework.macro; import haxe.macro.Expr; -using haxework.macro.Util; +using haxework.macro.MacroUtil; class FieldMacro { public var metaName(default, null):String; diff --git a/src/main/haxework/macro/Util.hx b/src/main/haxework/macro/MacroUtil.hx similarity index 67% rename from src/main/haxework/macro/Util.hx rename to src/main/haxework/macro/MacroUtil.hx index 697f006..780ebb8 100644 --- a/src/main/haxework/macro/Util.hx +++ b/src/main/haxework/macro/MacroUtil.hx @@ -1,9 +1,11 @@ package haxework.macro; +import haxe.macro.Context; +import haxe.macro.ExprTools; import haxe.macro.Expr; import haxe.macro.Type; -class Util { +class MacroUtil { public static function getMetaParams(meta:MetadataEntry):Array { return meta.params.map(function(param:Expr) return switch param.expr { @@ -17,15 +19,21 @@ class Util { } public static function getClassMeta(classType:ClassType, metaName:String):Null { - for (md in classType.meta.get()) if (md.name == metaName) { - return md; + for (meta in classType.meta.get()) { + if (meta.name == metaName) { + return meta; + } } return null; } public static function getFieldMeta(field:Field, metaName:String):Null { - for (md in field.meta) if (md.name == metaName) { - return md; + if (field.meta != null) { + for (meta in field.meta) { + if (meta.name == metaName) { + return meta; + } + } } return null; } @@ -48,4 +56,12 @@ class Util { public static function getField(fields:Array, name:String):Null { return Lambda.find(fields, function(field:Field):Bool return field.name == name); } + + public static function getExprClassType(expr:Expr):Null { + var typeName = ExprTools.toString(expr); + return switch Context.getType(typeName) { + case TInst(t, _): t.get(); + case _: null; + } + } } diff --git a/src/main/haxework/macro/ProvideMacro.hx b/src/main/haxework/macro/ProvideMacro.hx index ec395a5..2c1a1e1 100644 --- a/src/main/haxework/macro/ProvideMacro.hx +++ b/src/main/haxework/macro/ProvideMacro.hx @@ -3,7 +3,7 @@ package haxework.macro; import haxe.macro.Context; import haxe.macro.Expr; -using haxework.macro.Util; +using haxework.macro.MacroUtil; class ProvideMacro extends FieldMacro { @@ -22,7 +22,7 @@ class ProvideMacro extends FieldMacro { case TPath(p): p.name; default: null; } - var provideType:String = meta.params.length == 0 ? null : Util.getExprString(meta.params[0].expr); + var provideType:String = meta.params.length == 0 ? null : MacroUtil.getExprString(meta.params[0].expr); var isStatic = Lambda.exists(field.access, function(a: Access) return a == AStatic); field.kind = FProp('get', 'set', type); var access = [APrivate, AInline]; @@ -35,7 +35,7 @@ class ProvideMacro extends FieldMacro { pos: field.pos, kind: FFun({ args: [], - expr: Context.parse('return haxework.provider.Provider.get(${args.join(',')})', field.pos), + expr: Context.parse('return haxework.provider.Provider.instance.get(${args.join(',')})', field.pos), params: [], ret: type, }) @@ -47,7 +47,7 @@ class ProvideMacro extends FieldMacro { pos: field.pos, kind: FFun({ args: [{name: 'value', type: type}], - expr: Context.parse('{haxework.provider.Provider.set(${args.join(',')}); return value;}', field.pos), + expr: Context.parse('{haxework.provider.Provider.instance.set(${args.join(',')}); return value;}', field.pos), params: [], ret: type, }) diff --git a/src/main/haxework/macro/ResourceMacro.hx b/src/main/haxework/macro/ResourceMacro.hx index f6abb7d..09fb1a1 100644 --- a/src/main/haxework/macro/ResourceMacro.hx +++ b/src/main/haxework/macro/ResourceMacro.hx @@ -1,6 +1,6 @@ package haxework.macro; -using haxework.macro.Util; +using haxework.macro.MacroUtil; class ResourceMacro extends FieldMacro { diff --git a/src/main/haxework/macro/StyleMacro.hx b/src/main/haxework/macro/StyleMacro.hx index 819ef00..d3a8325 100644 --- a/src/main/haxework/macro/StyleMacro.hx +++ b/src/main/haxework/macro/StyleMacro.hx @@ -5,7 +5,7 @@ import haxe.macro.Expr; import haxe.macro.Type; using haxe.macro.ComplexTypeTools; -using haxework.macro.Util; +using haxework.macro.MacroUtil; using haxe.macro.MacroStringTools; typedef TProperty = { @@ -162,11 +162,11 @@ class StyleMacro extends ClassTypeMacro { } for (field in properties) { var propertyName = 'theme_${field.name}'; - expr.push(macro $i{propertyName} = haxework.provider.Provider.get(haxework.view.theme.ITheme).resolve((styleKey!=null?(styleKey+"."):"")+$v{field.name}, style)); + expr.push(macro $i{propertyName} = haxework.provider.Provider.instance.get(haxework.view.theme.ITheme).resolve((styleKey!=null?(styleKey+"."):"")+$v{field.name}, style)); } for (field in styleds) { var propertyName = '${field.name}'; - expr.push(macro $i{propertyName} = haxework.provider.Provider.get(haxework.view.theme.ITheme).resolve((styleKey!=null?(styleKey+"."):"")+$v{field.name}, style)); + expr.push(macro $i{propertyName} = haxework.provider.Provider.instance.get(haxework.view.theme.ITheme).resolve((styleKey!=null?(styleKey+"."):"")+$v{field.name}, style)); } if (hasOnStyle) { expr.push(macro onStyle()); diff --git a/src/main/haxework/macro/TemplateMacro.hx b/src/main/haxework/macro/TemplateMacro.hx index 1268a08..98d794d 100644 --- a/src/main/haxework/macro/TemplateMacro.hx +++ b/src/main/haxework/macro/TemplateMacro.hx @@ -6,7 +6,7 @@ import haxe.macro.Type; import haxework.macro.PositionJsonParser; import Lambda; -using haxework.macro.Util; +using haxework.macro.MacroUtil; class TemplateMacro extends ClassTypeMacro { @@ -46,7 +46,7 @@ class TemplateMacro extends ClassTypeMacro { a[2]; } case "resource" | "r": - var bindExpr = 'haxework.provider.Provider.get(haxework.resources.IResources).${a[1]}.bind("${a[2]}", ${name}, "${key}")'; + var bindExpr = 'haxework.provider.Provider.instance.get(haxework.resources.IResources).${a[1]}.bind("${a[2]}", ${name}, "${key}")'; exprs.push(Context.parse(bindExpr, getPosition(position))); null; case "translate" | "t": @@ -182,12 +182,11 @@ class TemplateMacro extends ClassTypeMacro { private static function findViewsBindings(fields:Array):Map { var result:Map = new Map(); - for (field in fields) if (field.meta != null) { - for (meta in field.meta) { - if (meta.name == ':view') { - var viewId:String = meta.params.length == 0 ? field.name : Util.getExprString(meta.params[0].expr); - result.set(viewId, field.name); - } + for (field in fields) { + var viewMeta = field.getFieldMeta(":view"); + if (viewMeta != null) { + var viewId:String = viewMeta.params.length == 0 ? field.name : MacroUtil.getExprString(viewMeta.params[0].expr); + result.set(viewId, field.name); } } return result; @@ -196,7 +195,7 @@ class TemplateMacro extends ClassTypeMacro { override public function apply(classType:ClassType, fields:Array):Array { i = 0; var meta = classType.getClassMeta(metaName); - var params = Util.getMetaParams(meta); + var params = MacroUtil.getMetaParams(meta); var filePath = params[0]; if (filePath == null) { filePath = classType.pack.join("/") + "/" + classType.name + ".yaml"; diff --git a/src/main/haxework/net/manage/ILoaderManager.hx b/src/main/haxework/net/manage/ILoaderManager.hx index a06f679..43bfbe4 100755 --- a/src/main/haxework/net/manage/ILoaderManager.hx +++ b/src/main/haxework/net/manage/ILoaderManager.hx @@ -1,10 +1,10 @@ package haxework.net.manage; -interface ILoaderManager { +@:provide(LoaderManager) interface ILoaderManager { public var actives(default, null):Array>; public var queue(default, null):Array>; public var limit(default, default):Int; public function add(loader:ILoader):Void; public function release(loader:ILoader):Void; -} \ No newline at end of file +} diff --git a/src/main/haxework/parser/Parser.hx b/src/main/haxework/parser/Parser.hx index 635f28d..ed00214 100644 --- a/src/main/haxework/parser/Parser.hx +++ b/src/main/haxework/parser/Parser.hx @@ -4,6 +4,7 @@ import haxe.macro.Context; import haxe.macro.Expr; import haxe.macro.Type; import haxe.macro.TypeTools; +import haxework.macro.ClassProvideMacro; import haxework.macro.ClassTypeMacro; import haxework.macro.DispatcherMacro; import haxework.macro.FieldMacro; @@ -16,6 +17,7 @@ import haxework.macro.TemplateMacro; class Parser { private static var classTypeMacros:Array = [ + new ClassProvideMacro(), new TemplateMacro(), new DispatcherMacro(), new StyleMacro(), diff --git a/src/main/haxework/provider/Provider.hx b/src/main/haxework/provider/Provider.hx index 6b73c3d..6e18cf5 100755 --- a/src/main/haxework/provider/Provider.hx +++ b/src/main/haxework/provider/Provider.hx @@ -15,7 +15,7 @@ abstract KeyType(String) { } } -class Provider { +@:singleton class Provider { private static function key(i:KeyType, ?type:Dynamic):String { var result:String = Std.string(i); @@ -23,22 +23,40 @@ class Provider { return result; } - private static var factories:Map> = new Map(); - private static var args:Map> = new Map(); - private static var instances:Map = new Map(); + public var factories:Map>; + private var args:Map>; + private var instances:Map; - public static function setFactory(i:KeyType, clazz:Class, ?type:Dynamic, ?args:Array):Void { - var key = key(i, type); - factories.set(key, clazz); - if (args != null) Provider.args.set(key, args); + public function new() { + factories = new Map(); + args = new Map(); + instances = new Map(); + resolveDefaultFactories(); } - public static function set(i:KeyType, instance:T, ?type:Dynamic):Void { + macro static function resolveDefaultFactories() { + var result = []; + for (item in haxework.macro.ClassProvideMacro.bundle) { + // ToDo: ClassType to Expr? + var k = haxe.macro.Context.parse(haxe.macro.MacroStringTools.toDotPath(item.key.pack, item.key.name), haxe.macro.Context.currentPos()); + var v = haxe.macro.Context.parse(haxe.macro.MacroStringTools.toDotPath(item.value.pack, item.value.name), haxe.macro.Context.currentPos()); + result.push(macro setFactory(${k}, ${v})); + } + return macro $b{result}; + } + + public function setFactory(i:KeyType, clazz:Class, ?type:Dynamic, ?args:Array):Void { + var key = key(i, type); + factories.set(key, clazz); + if (args != null) this.args.set(key, args); + } + + public function set(i:KeyType, instance:T, ?type:Dynamic):Void { var key = key(i, type); instances.set(key, instance); } - public static function get(i:KeyType, ?type:Dynamic):T { + public function get(i:KeyType, ?type:Dynamic):T { var key = key(i, type); if (instances.exists(key)) { return instances.get(key); @@ -52,7 +70,7 @@ class Provider { } } - public static function build(i:Class, ?type:Dynamic):T { + public function build(i:Class, ?type:Dynamic):T { var key = key(i, type); if (factories.exists(key)) { var instance:T = Type.createInstance(factories.get(key), args.exists(key) ? args.get(key) : []); @@ -62,7 +80,7 @@ class Provider { } } - public static function setProperty(i:Class, field:String, value:Dynamic, ?type:Dynamic):Void { + public function setProperty(i:Class, field:String, value:Dynamic, ?type:Dynamic):Void { var o:Dynamic = get(i, type); if (o != null && Reflect.hasField(o, field)) { Reflect.setProperty(o, field, value); diff --git a/src/main/haxework/resources/IResources.hx b/src/main/haxework/resources/IResources.hx index fc15542..6de6612 100755 --- a/src/main/haxework/resources/IResources.hx +++ b/src/main/haxework/resources/IResources.hx @@ -2,9 +2,9 @@ package haxework.resources; import flash.display.BitmapData; import flash.display.MovieClip; -import haxework.resources.Resources.ResMap; +import haxework.resources.Resources; -interface IResources { +@:provide(Resources) interface IResources { public var image(default, null):ResMap; public var color(default, null):ResMap; public var movie(default, null):ResMap; diff --git a/src/main/haxework/view/Root.hx b/src/main/haxework/view/Root.hx index 31b2c77..b8eda94 100755 --- a/src/main/haxework/view/Root.hx +++ b/src/main/haxework/view/Root.hx @@ -30,7 +30,7 @@ class Root { this.autoSize = autoSize; Lib.current.addChild(view.content); if (Std.is(view, IGroupView)) { - Provider.set(IGroupView, cast view); + Provider.instance.set(IGroupView, cast view); } var content:DisplayObject = view.content; if (content.stage == null) { diff --git a/src/main/haxework/view/popup/PopupManager.hx b/src/main/haxework/view/popup/PopupManager.hx index 1b873ea..c62aa6e 100755 --- a/src/main/haxework/view/popup/PopupManager.hx +++ b/src/main/haxework/view/popup/PopupManager.hx @@ -5,7 +5,7 @@ import haxework.animate.IAnimate; typedef P = PopupView; -class PopupManager { +@:provide class PopupManager { public var showAnimateFactory(default, default):IView -> IAnimate; public var closeAnimateFactory(default, default):IView -> IAnimate;