[macro] add ClassProvideMacro
This commit is contained in:
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
20
src/main/haxework/macro/ClassProvideMacro.hx
Normal file
20
src/main/haxework/macro/ClassProvideMacro.hx
Normal file
@@ -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<Field>):Array<Field> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -23,10 +23,7 @@ class DispatcherMacro extends ClassTypeMacro {
|
||||
override public function apply(classType:ClassType, fields:Array<Field>):Array<Field> {
|
||||
var result:Array<Field> = 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<Type> = switch field.type {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<String> {
|
||||
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<MetadataEntry> {
|
||||
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<MetadataEntry> {
|
||||
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<Field>, name:String):Null<Field> {
|
||||
return Lambda.find(fields, function(field:Field):Bool return field.name == name);
|
||||
}
|
||||
|
||||
public static function getExprClassType(expr:Expr):Null<ClassType> {
|
||||
var typeName = ExprTools.toString(expr);
|
||||
return switch Context.getType(typeName) {
|
||||
case TInst(t, _): t.get();
|
||||
case _: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package haxework.macro;
|
||||
|
||||
using haxework.macro.Util;
|
||||
using haxework.macro.MacroUtil;
|
||||
|
||||
class ResourceMacro extends FieldMacro {
|
||||
|
||||
|
||||
@@ -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<T> = {
|
||||
@@ -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());
|
||||
|
||||
@@ -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<Field>):Map<String, String> {
|
||||
var result:Map<String, String> = 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<Field>):Array<Field> {
|
||||
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";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package haxework.net.manage;
|
||||
|
||||
interface ILoaderManager {
|
||||
@:provide(LoaderManager) interface ILoaderManager {
|
||||
public var actives(default, null):Array<ILoader<Dynamic>>;
|
||||
public var queue(default, null):Array<ILoader<Dynamic>>;
|
||||
public var limit(default, default):Int;
|
||||
|
||||
@@ -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<ClassTypeMacro> = [
|
||||
new ClassProvideMacro(),
|
||||
new TemplateMacro(),
|
||||
new DispatcherMacro(),
|
||||
new StyleMacro(),
|
||||
|
||||
@@ -15,7 +15,7 @@ abstract KeyType<T>(String) {
|
||||
}
|
||||
}
|
||||
|
||||
class Provider {
|
||||
@:singleton class Provider {
|
||||
|
||||
private static function key<T>(i:KeyType<T>, ?type:Dynamic):String {
|
||||
var result:String = Std.string(i);
|
||||
@@ -23,22 +23,40 @@ class Provider {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static var factories:Map<String, Class<Dynamic>> = new Map();
|
||||
private static var args:Map<String, Array<Dynamic>> = new Map();
|
||||
private static var instances:Map<String, Dynamic> = new Map();
|
||||
public var factories:Map<String, Class<Dynamic>>;
|
||||
private var args:Map<String, Array<Dynamic>>;
|
||||
private var instances:Map<String, Dynamic>;
|
||||
|
||||
public static function setFactory<T>(i:KeyType<T>, clazz:Class<T>, ?type:Dynamic, ?args:Array<Dynamic>):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<T>(i:KeyType<T>, 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<T>(i:KeyType<T>, clazz:Class<T>, ?type:Dynamic, ?args:Array<Dynamic>):Void {
|
||||
var key = key(i, type);
|
||||
factories.set(key, clazz);
|
||||
if (args != null) this.args.set(key, args);
|
||||
}
|
||||
|
||||
public function set<T>(i:KeyType<T>, instance:T, ?type:Dynamic):Void {
|
||||
var key = key(i, type);
|
||||
instances.set(key, instance);
|
||||
}
|
||||
|
||||
public static function get<T>(i:KeyType<T>, ?type:Dynamic):T {
|
||||
public function get<T>(i:KeyType<T>, ?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<T>(i:Class<T>, ?type:Dynamic):T {
|
||||
public function build<T>(i:Class<T>, ?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<T>(i:Class<T>, field:String, value:Dynamic, ?type:Dynamic):Void {
|
||||
public function setProperty<T>(i:Class<T>, 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);
|
||||
|
||||
@@ -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<BitmapData>;
|
||||
public var color(default, null):ResMap<Int>;
|
||||
public var movie(default, null):ResMap<MovieClip>;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import haxework.animate.IAnimate;
|
||||
|
||||
typedef P = PopupView<Dynamic>;
|
||||
|
||||
class PopupManager {
|
||||
@:provide class PopupManager {
|
||||
|
||||
public var showAnimateFactory(default, default):IView<Dynamic> -> IAnimate;
|
||||
public var closeAnimateFactory(default, default):IView<Dynamic> -> IAnimate;
|
||||
|
||||
Reference in New Issue
Block a user