ViewBuilder fileName
This commit is contained in:
@@ -7,22 +7,16 @@ import haxe.macro.Context;
|
||||
@:remove @:autoBuild(haxework.gui.ViewBuilderImpl.build())
|
||||
extern interface ViewBuilder {}
|
||||
|
||||
typedef BuildData = {
|
||||
var fields:Array<Field>;
|
||||
var exprs:Array<Expr>;
|
||||
var style:Dynamic;
|
||||
}
|
||||
|
||||
class ViewBuilderImpl {
|
||||
#if macro
|
||||
static function loadFile(path:String, json:Bool = true) {
|
||||
var p = Context.resolvePath(path);
|
||||
Context.registerModuleDependency(Context.getLocalModule(), p);
|
||||
var content = sys.io.File.getContent(p);
|
||||
private class BuilderUtil {
|
||||
|
||||
public static function loadFile(path:String, json:Bool = true) {
|
||||
Context.registerModuleDependency(Context.getLocalModule(), path);
|
||||
var content = sys.io.File.getContent(path);
|
||||
return json ? Json.parse(content) : content;
|
||||
}
|
||||
|
||||
private static function getMeta(key:String):Array<String> {
|
||||
public static function getMeta(key:String):Array<String> {
|
||||
var c = Context.getLocalClass().get();
|
||||
for (meta in c.meta.get()) {
|
||||
if (meta.name == key) {
|
||||
@@ -34,10 +28,45 @@ class ViewBuilderImpl {
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private static var i = 0;
|
||||
private class Builder {
|
||||
|
||||
private static function specialValue(data:BuildData, name:String, key:String, a:Array<String>):Dynamic {
|
||||
private var templateFile:String;
|
||||
private var templateKey:String;
|
||||
private var styleFile:String;
|
||||
|
||||
private var template:Dynamic;
|
||||
private var fields:Array<Field>;
|
||||
private var exprs:Array<Expr>;
|
||||
private var style:Dynamic;
|
||||
|
||||
private var i:Int;
|
||||
|
||||
public function new() {
|
||||
var templateMeta = BuilderUtil.getMeta(":template");
|
||||
var templatePath = templateMeta[0].split("@");
|
||||
templateFile = Context.resolvePath(templatePath[0]);
|
||||
templateKey = templatePath[1];
|
||||
|
||||
template = BuilderUtil.loadFile(templateFile);
|
||||
if (templateKey != null) template = Reflect.field(template, templateKey);
|
||||
|
||||
if (templateMeta[1] != null) {
|
||||
styleFile = Context.resolvePath(templateMeta[1]);
|
||||
style = BuilderUtil.loadFile(styleFile);
|
||||
}
|
||||
|
||||
fields = Context.getBuildFields();
|
||||
exprs = [];
|
||||
i = 0;
|
||||
}
|
||||
|
||||
private function getPosition():Position {
|
||||
return Context.makePosition({min:0, max:0, file:templateFile + (templateKey != null ? "@" + templateKey : "")});
|
||||
}
|
||||
|
||||
private function specialValue(name:String, key:String, a:Array<String>):Dynamic {
|
||||
return switch (a[0]) {
|
||||
case "asset":
|
||||
switch (a[1]) {
|
||||
@@ -49,7 +78,7 @@ class ViewBuilderImpl {
|
||||
case "res":
|
||||
var res = "haxework.provider.Provider.get(haxework.resources.IResources)." + a[1];
|
||||
var bindExpr = res + ".bind(\"" + a[2] + "\", " + name + ", \"" + key + "\")";
|
||||
data.exprs.push(Context.parse(bindExpr, Context.currentPos()));
|
||||
exprs.push(Context.parse(bindExpr, getPosition()));
|
||||
//res + ".get(\"" + a[2] + "\")";
|
||||
null;
|
||||
case "locale":
|
||||
@@ -57,8 +86,8 @@ class ViewBuilderImpl {
|
||||
case "class":
|
||||
a[1];
|
||||
case "layout":
|
||||
var template = loadFile(a[1]);
|
||||
return getValue(data, name, key, template);
|
||||
var template = BuilderUtil.loadFile(a[1]);
|
||||
return getValue(name, key, template);
|
||||
case "link":
|
||||
"(links == null) ? untyped this : Reflect.field(links, \"" + a[1] + "\")";
|
||||
case _:
|
||||
@@ -66,12 +95,12 @@ class ViewBuilderImpl {
|
||||
}
|
||||
}
|
||||
|
||||
private static function getValue(data:BuildData, name:String, key:String, value:Dynamic):Dynamic {
|
||||
private function getValue(name:String, key:String, value:Dynamic):Dynamic {
|
||||
return if (Std.is(value, Array)) {
|
||||
value.map(function(v) { return getValue(data, null, null, v); });
|
||||
value.map(function(v) { return getValue(null, null, v); });
|
||||
} else if (Std.is(value, String)) {
|
||||
if (value.charAt(0) == "@") {
|
||||
specialValue(data, name, key, value.substring(1, value.length).split(":"));
|
||||
specialValue(name, key, value.substring(1, value.length).split(":"));
|
||||
} else if (~/(0x|#)[A-Fa-f\d]{6}/.match(value)) {
|
||||
Std.parseInt(StringTools.replace(Std.string(value), "#", "0x"));
|
||||
} else {
|
||||
@@ -83,8 +112,8 @@ class ViewBuilderImpl {
|
||||
if (Reflect.hasField(value, "type")) {
|
||||
var n = "a" + i++;
|
||||
var type = Reflect.field(value, "type");
|
||||
data.exprs.push(Context.parse("var " + n + " = new " + type + "()", Context.currentPos()));
|
||||
createElement(data, value, n);
|
||||
exprs.push(Context.parse("var " + n + " = new " + type + "()", getPosition()));
|
||||
createElement(value, n);
|
||||
n;
|
||||
} else {
|
||||
value;
|
||||
@@ -94,9 +123,9 @@ class ViewBuilderImpl {
|
||||
}
|
||||
}
|
||||
|
||||
private static function createElement(data:BuildData, template:Dynamic, name:String):String {
|
||||
private function createElement(template:Dynamic, name:String):String {
|
||||
if (Reflect.hasField(template, "style")) {
|
||||
var s = Reflect.field(data.style, Reflect.field(template, "style"));
|
||||
var s = Reflect.field(style, Reflect.field(template, "style"));
|
||||
for (key in Reflect.fields(s)) if (!Reflect.hasField(template, key)) {
|
||||
Reflect.setField(template, key, Reflect.field(s, key));
|
||||
}
|
||||
@@ -105,47 +134,33 @@ class ViewBuilderImpl {
|
||||
if (Reflect.hasField(template, "id")) {
|
||||
var id = Reflect.field(template, "id");
|
||||
var type = Reflect.field(template, "type");
|
||||
var expr = Context.parse("var a:" + type, Context.currentPos());
|
||||
var expr = Context.parse("var a:" + type, getPosition());
|
||||
var type = switch (expr.expr) {
|
||||
case EVars(vars): vars[0].type;
|
||||
case _: null;
|
||||
}
|
||||
data.fields.push({
|
||||
fields.push({
|
||||
name: id,
|
||||
access: [APublic],
|
||||
pos: Context.currentPos(),
|
||||
pos: getPosition(),
|
||||
kind: FProp("default", "null", type)
|
||||
});
|
||||
data.exprs.push(Context.parse("this." + id + " = " + name, Context.currentPos()));
|
||||
exprs.push(Context.parse("this." + id + " = " + name, getPosition()));
|
||||
}
|
||||
|
||||
for (key in Reflect.fields(template)) {
|
||||
if (["type", "style"].indexOf(key) > -1) continue;
|
||||
var value = getValue(data, name, key, Reflect.field(template, key));
|
||||
var value = getValue(name, key, Reflect.field(template, key));
|
||||
if (value != null) {
|
||||
data.exprs.push(Context.parse(name + "." + key + " = cast " + value, Context.currentPos()));
|
||||
exprs.push(Context.parse(name + "." + key + " = cast " + value, getPosition()));
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public static function build() {
|
||||
//trace("Build: " + Context.getLocalClass().get().module);
|
||||
var templateMeta = getMeta(":template");
|
||||
var templatePath = templateMeta[0].split("@");
|
||||
var template = loadFile(templatePath[0]);
|
||||
if (templatePath[1] != null) template = Reflect.field(template, templatePath[1]);
|
||||
var style = templateMeta[1] == null ? {} : loadFile(templateMeta[1]);
|
||||
|
||||
var fields = Context.getBuildFields();
|
||||
|
||||
var data = {
|
||||
fields: fields,
|
||||
exprs: [],
|
||||
style: style
|
||||
};
|
||||
i = 0;
|
||||
createElement(data, template, "this");
|
||||
public function build():Array<Field> {
|
||||
createElement(template, "this");
|
||||
|
||||
var init = false;
|
||||
for (f in fields) if (f.name == "init") {
|
||||
@@ -156,33 +171,40 @@ class ViewBuilderImpl {
|
||||
fields.push({
|
||||
name: "build",
|
||||
access: [APublic],
|
||||
pos: Context.currentPos(),
|
||||
pos: getPosition(),
|
||||
kind: FFun({
|
||||
args: [{name:"links", type:TPath({name:"Dynamic", pack:[], params:[]}), opt:true, value:null}],
|
||||
expr: macro $b{data.exprs},
|
||||
expr: macro $b{exprs},
|
||||
params: [],
|
||||
ret: null
|
||||
})
|
||||
});
|
||||
|
||||
var contrExprs = [];
|
||||
contrExprs.push(macro super());
|
||||
contrExprs.push(macro build(links));
|
||||
if (init) contrExprs.push(macro init());
|
||||
var contstrExprs = [];
|
||||
contstrExprs.push(macro super());
|
||||
contstrExprs.push(macro build(links));
|
||||
if (init) contstrExprs.push(macro init());
|
||||
|
||||
fields.push({
|
||||
name: "new",
|
||||
access: [APublic],
|
||||
pos: Context.currentPos(),
|
||||
pos: getPosition(),
|
||||
kind: FFun({
|
||||
args: [{name:"links", type:TPath({name:"Dynamic", pack:[], params:[]}), opt:true, value:null}],
|
||||
expr: macro $b{contrExprs},
|
||||
expr: macro $b{contstrExprs},
|
||||
params: [],
|
||||
ret: null
|
||||
})
|
||||
});
|
||||
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
#end
|
||||
|
||||
class ViewBuilderImpl {
|
||||
#if macro
|
||||
public static function build() {
|
||||
return new Builder().build();
|
||||
}
|
||||
#end
|
||||
}
|
||||
Reference in New Issue
Block a user