From 97b76866949cd327c5a07f87b2baa8e8192581a3 Mon Sep 17 00:00:00 2001 From: shmyga Date: Thu, 15 Feb 2018 23:56:46 +0300 Subject: [PATCH] [gui] support yaml in builder style --- haxelib.json | 2 +- src/main/haxework/gui/build/Builder.hx | 354 +++++++++++---------- src/main/haxework/gui/build/BuilderUtil.hx | 77 +++-- 3 files changed, 223 insertions(+), 210 deletions(-) diff --git a/haxelib.json b/haxelib.json index 1963469..27ce23f 100755 --- a/haxelib.json +++ b/haxelib.json @@ -4,7 +4,7 @@ "license": "BSD", "tags": ["flash", "openfl"], "description": "Framework.", - "version": "0.7.0", + "version": "0.7.1", "releasenote": "Update.", "contributors": ["shmyga"], "classPath": "src/main", diff --git a/src/main/haxework/gui/build/Builder.hx b/src/main/haxework/gui/build/Builder.hx index 93e2368..de8e594 100755 --- a/src/main/haxework/gui/build/Builder.hx +++ b/src/main/haxework/gui/build/Builder.hx @@ -1,6 +1,7 @@ package haxework.gui.build; #if macro +import haxework.gui.build.BuilderUtil; import haxe.macro.Context; import haxework.gui.build.PositionJsonParser; import haxe.macro.Expr; @@ -8,201 +9,204 @@ import haxe.macro.Expr.Field; class Builder { - private var templateFile:String; - private var templateKey:String; - private var styleFile:String; + private var templateFile:String; + private var templateKey:String; + private var styleFile:String; - private var template:Dynamic; - private var fields:Array; - private var exprs:Array; - private var style:Dynamic; + private var template:Dynamic; + private var fields:Array; + private var exprs:Array; + private var style:Dynamic; - private var i:Int; + 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]; + public function new() { + var templateMeta = BuilderUtil.getMeta(":template"); + var templatePath = templateMeta[0].split("@"); + templateFile = Context.resolvePath(templatePath[0]); + templateKey = templatePath[1]; - var ext = templateFile.split('.').pop(); - template = switch(ext) { - case 'json': BuilderUtil.loadJsonFile(templateFile); - case 'yml' | 'yaml': BuilderUtil.loadYamlFile(templateFile); - case x: throw 'Unsupported template format: "${x}"'; - } - if (templateKey != null) template = Reflect.field(template, templateKey); + template = BuilderUtil.loadFile(templateFile); + if (templateKey != null) template = Reflect.field(template, templateKey); - if (templateMeta[1] != null) { - styleFile = Context.resolvePath(templateMeta[1]); - style = BuilderUtil.loadJsonFile(styleFile); - } - - fields = Context.getBuildFields(); - exprs = []; - i = 0; - } - - private function getPosition(?position:JsonKeyPosition):Position { - var min = position == null ? 1 : position.min + 32; // :-( - var max = position == null ? 1 : position.max + 32; - var file = position == null || position.file == null ? templateFile : position.file; - return Context.makePosition({min:min, max:max, file:file}); - } - - private function specialValue(name:String, key:String, a:Array, position:JsonKeyPosition):Dynamic { - return switch (a[0]) { - case "asset": - switch (a[1]) { - case "image": - "openfl.Assets.getBitmapData(\"" + a[2] + "\")"; - case _: - a[2]; + if (templateMeta[1] != null) { + styleFile = Context.resolvePath(templateMeta[1]); + style = BuilderUtil.loadFile(styleFile); } - case "res": - var res = "haxework.provider.Provider.get(haxework.resources.IResources)." + a[1]; - var bindExpr = res + ".bind(\"" + a[2] + "\", " + name + ", \"" + key + "\")"; - exprs.push(Context.parse(bindExpr, getPosition(position))); -//res + ".get(\"" + a[2] + "\")"; - null; - case "locale": - "new haxework.locale.LString(\"" + a[1] + "\")"; - case "class": - a[1]; - case "layout": - var template = BuilderUtil.loadJsonFile(a[1]); - return getValue(name, key, template, position); - case "link": - "(links == null) ? untyped this : Reflect.field(links, \"" + a[1] + "\")"; - case _: - Context.error("Unsupported prefix \"" + a[0] + "\"", getPosition(position)); + + fields = Context.getBuildFields(); + exprs = []; + i = 0; } - } - private function getType(value:Dynamic, position:Position):String { - if (Reflect.hasField(value, "@type")) { - return Reflect.field(value, "@type"); - } else if (Reflect.hasField(value, "$type")) { - return Reflect.field(value, "$type"); - } else { - Context.error("Need @type field", position); - return null; - } - } - - private function getValue(name:String, key:String, value:Dynamic, position:JsonKeyPosition):Dynamic { - return if (Std.is(value, Array)) { - value.map(function(v) { - return getValue(null, null, v, position); - }); - } else if (Std.is(value, String)) { - if (value.charAt(0) == "@") { - specialValue(name, key, value.substring(1, value.length).split(":"), position); - } else if (~/(0x|#)[A-Fa-f\d]{6}/.match(value)) { - Std.parseInt(StringTools.replace(Std.string(value), "#", "0x")); - } else { - "\"" + value + "\""; - } - } else if (Std.is(value, Float) || (Std.is(value, Bool))) { - value; - } else if (value != null) { - var type = getType(value, getPosition(position)); - if (type != null) { - var n = "a" + i++; - if (type == "Dynamic") { - //ToDo: - exprs.push(Context.parse("var " + n + " = cast {}", getPosition(position))); + private static function getSpecField(object:Dynamic, field:String):Dynamic { + if (Reflect.hasField(object, "@" + field)) { + return Reflect.field(object, "@" + field); + } else if (Reflect.hasField(object, "$" + field)) { + return Reflect.field(object, "$" + field); } else { - exprs.push(Context.parse("var " + n + " = new " + type + "()", getPosition(position))); + return null; } - createElement(value, n); - n; - } else { - null; - } - } else { - value; } - } - private function createElement(template:Dynamic, name:String):String { - if (Reflect.hasField(template, "@style")) { - var s = Reflect.field(style, Reflect.field(template, "@style")); - for (key in Reflect.fields(s)) { - if (key.charAt(0) != "$" && !Reflect.hasField(template, key)) { - Reflect.setField(template, key, Reflect.field(s, key)); - Reflect.setField(template, "$" + key, Reflect.field(s, "$" + key)); + private function getPosition(?position:JsonKeyPosition):Position { + var min = position == null ? 1 : position.min + 32; // :-( + var max = position == null ? 1 : position.max + 32; + var file = position == null || position.file == null ? templateFile : position.file; + return Context.makePosition({min:min, max:max, file:file}); + } + + private function specialValue(name:String, key:String, a:Array, position:JsonKeyPosition):Dynamic { + return switch (a[0]) { + case "asset": + switch (a[1]) { + case "image": + "openfl.Assets.getBitmapData(\"" + a[2] + "\")"; + case _: + a[2]; + } + case "res": + var res = "haxework.provider.Provider.get(haxework.resources.IResources)." + a[1]; + var bindExpr = res + ".bind(\"" + a[2] + "\", " + name + ", \"" + key + "\")"; + exprs.push(Context.parse(bindExpr, getPosition(position))); + //res + ".get(\"" + a[2] + "\")"; + null; + case "locale": + "new haxework.locale.LString(\"" + a[1] + "\")"; + case "class": + a[1]; + case "layout": + var template = BuilderUtil.loadJsonFile(a[1]); + return getValue(name, key, template, position); + case "link": + "(links == null) ? untyped this : Reflect.field(links, \"" + a[1] + "\")"; + case _: + Context.error("Unsupported prefix \"" + a[0] + "\"", getPosition(position)); } - } } - if (Reflect.hasField(template, "id")) { - var id = Reflect.field(template, "id"); - var type = getType(template, getPosition()); - var expr = Context.parse("var a:" + type, getPosition()); - var complexType = switch (expr.expr) { - case EVars(vars): vars[0].type; - case _: null; - } - fields.push({ - name: id, - access: [APublic], - pos: getPosition(), - kind: FProp("default", "null", complexType) - }); - exprs.push(Context.parse("this." + id + " = " + name, getPosition())); + private static function getType(value:Dynamic, position:Position):String { + var type:String = getSpecField(value, "type"); + if (type == null) { + Context.error("Need @type field", position); + } + return type; } - for (key in Reflect.fields(template)) { - if (key.charAt(0) == "$" || key.charAt(0) == "@") continue; - var position = Reflect.field(template, "$" + key); - var value = getValue(name, key, Reflect.field(template, key), position); - if (value != null) { - exprs.push(Context.parse(name + "." + key + " = " + value, getPosition(position))); - } - } - return name; - } - - - public function build():Array { - createElement(template, "this"); - - var init = false; - for (f in fields) if (f.name == "init") { - init = true; - break; + private function getValue(name:String, key:String, value:Dynamic, position:JsonKeyPosition):Dynamic { + return if (Std.is(value, Array)) { + value.map(function(v) { + return getValue(null, null, v, position); + }); + } else if (Std.is(value, String)) { + if (value.charAt(0) == "@" || value.charAt(0) == "$") { + specialValue(name, key, value.substring(1, value.length).split(":"), position); + } else if (~/(0x|#)[A-Fa-f\d]{6}/.match(value)) { + Std.parseInt(StringTools.replace(Std.string(value), "#", "0x")); + } else { + "\"" + value + "\""; + } + } else if (Std.is(value, Float) || (Std.is(value, Bool))) { + value; + } else if (value != null) { + var type = getType(value, getPosition(position)); + if (type != null) { + var n = "a" + i++; + if (type == "Dynamic") { + //ToDo: + exprs.push(Context.parse("var " + n + " = cast {}", getPosition(position))); + } else { + exprs.push(Context.parse("var " + n + " = new " + type + "()", getPosition(position))); + } + createElement(value, n); + n; + } else { + null; + } + } else { + value; + } } - fields.push({ - name: "build", - access: [APublic], - pos: getPosition(), - kind: FFun({ - args: [{name:"links", type:TPath({name:"Dynamic", pack:[], params:[]}), opt:true, value:null}], - expr: macro $b{exprs}, - params: [], - ret: null - }) - }); + private function createElement(template:Dynamic, name:String):String { + var s = getSpecField(template, "style"); + if (s != null) { + var s = Reflect.field(style, s); + for (key in Reflect.fields(s)) { + if (key.charAt(0) != "$" && !Reflect.hasField(template, key)) { + Reflect.setField(template, key, Reflect.field(s, key)); + Reflect.setField(template, "$" + key, Reflect.field(s, "$" + key)); + } + } + } - var contstrExprs = []; - contstrExprs.push(macro super()); - contstrExprs.push(macro build(links)); - if (init) contstrExprs.push(macro init()); + if (Reflect.hasField(template, "id")) { + var id = Reflect.field(template, "id"); + var type = getType(template, getPosition()); + var expr = Context.parse("var a:" + type, getPosition()); + var complexType = switch (expr.expr) { + case EVars(vars): vars[0].type; + case _: null; + } + fields.push({ + name: id, + access: [APublic], + pos: getPosition(), + kind: FProp("default", "null", complexType) + }); + exprs.push(Context.parse("this." + id + " = " + name, getPosition())); + } - fields.push({ - name: "new", - access: [APublic], - pos: getPosition(), - kind: FFun({ - args: [{name:"links", type:TPath({name:"Dynamic", pack:[], params:[]}), opt:true, value:null}], - expr: macro $b{contstrExprs}, - params: [], - ret: null - }) - }); - return fields; - } + for (key in Reflect.fields(template)) { + if (key.charAt(0) == "$" || key.charAt(0) == "@") continue; + var position = Reflect.field(template, "$" + key); + var value = getValue(name, key, Reflect.field(template, key), position); + if (value != null) { + exprs.push(Context.parse(name + "." + key + " = " + value, getPosition(position))); + } + } + return name; + } + + + public function build():Array { + createElement(template, "this"); + + var init = false; + for (f in fields) if (f.name == "init") { + init = true; + break; + } + + fields.push({ + name: "build", + access: [APublic], + pos: getPosition(), + kind: FFun({ + args: [{name:"links", type:TPath({name:"Dynamic", pack:[], params:[]}), opt:true, value:null}], + expr: macro $b{exprs}, + params: [], + ret: null + }) + }); + + var contstrExprs = []; + contstrExprs.push(macro super()); + contstrExprs.push(macro build(links)); + if (init) contstrExprs.push(macro init()); + + fields.push({ + name: "new", + access: [APublic], + pos: getPosition(), + kind: FFun({ + args: [{name:"links", type:TPath({name:"Dynamic", pack:[], params:[]}), opt:true, value:null}], + expr: macro $b{contstrExprs}, + params: [], + ret: null + }) + }); + return fields; + } } #end \ No newline at end of file diff --git a/src/main/haxework/gui/build/BuilderUtil.hx b/src/main/haxework/gui/build/BuilderUtil.hx index 07380bb..0ca7c9b 100755 --- a/src/main/haxework/gui/build/BuilderUtil.hx +++ b/src/main/haxework/gui/build/BuilderUtil.hx @@ -9,44 +9,53 @@ import haxe.macro.Expr.ExprDef; class BuilderUtil { - public static function loadJsonFile(path:String) { - Context.registerModuleDependency(Context.getLocalModule(), path); - var content = sys.io.File.getContent(path); - var json = null; - try { - json = PositionJsonParser.parse(content, path); - } catch(error:Dynamic) { - Context.error(error, Context.makePosition({min:0, max:0, file:path})); + public static function loadJsonFile(path:String):Dynamic { + Context.registerModuleDependency(Context.getLocalModule(), path); + var content = sys.io.File.getContent(path); + var json = null; + try { + json = PositionJsonParser.parse(content, path); + } catch (error:Dynamic) { + Context.error(error, Context.makePosition({min:0, max:0, file:path})); + } + Context.parse(content, Context.makePosition({min:0, max:0, file:path})); + return json; } - Context.parse(content, Context.makePosition({min:0, max:0, file:path})); - return json; - } - public static function loadYamlFile(path:String) { - Context.registerModuleDependency(Context.getLocalModule(), path); - var content = sys.io.File.getContent(path); - var result = null; - try { - // ToDo: extract poisiton info - result = Yaml.parse(content, Parser.options().useObjects()); - } catch(error:Dynamic) { - Context.error(error, Context.makePosition({min:0, max:0, file:path})); + public static function loadYamlFile(path:String):Dynamic { + Context.registerModuleDependency(Context.getLocalModule(), path); + var content = sys.io.File.getContent(path); + var result = null; + try { + // ToDo: extract poisiton info + result = Yaml.parse(content, Parser.options().useObjects()); + } catch (error:Dynamic) { + Context.error(error, Context.makePosition({min:0, max:0, file:path})); + } + //Context.parse(content, Context.makePosition({min:0, max:0, file:path})); + return result; } - //Context.parse(content, Context.makePosition({min:0, max:0, file:path})); - return result; - } - public static function getMeta(key:String):Array { - var c = Context.getLocalClass().get(); - for (meta in c.meta.get()) { - if (meta.name == key) { - return meta.params.map(function(param) return switch(param.expr) { - case ExprDef.EConst(Constant.CString(value)): value; - case _: null; - }); - } + public static function loadFile(path:String):Dynamic { + var ext = path.split('.').pop(); + return switch(ext) { + case 'json': BuilderUtil.loadJsonFile(path); + case 'yml' | 'yaml': BuilderUtil.loadYamlFile(path); + case x: throw 'Unsupported template format: "${x}"'; + } + } + + public static function getMeta(key:String):Array { + var c = Context.getLocalClass().get(); + for (meta in c.meta.get()) { + if (meta.name == key) { + return meta.params.map(function(param) return switch(param.expr) { + case ExprDef.EConst(Constant.CString(value)): value; + case _: null; + }); + } + } + return []; } - return []; - } } #end \ No newline at end of file