diff --git a/hscript/CustomClassHandler.hx b/hscript/CustomClassHandler.hx index f70cece..10b399c 100644 --- a/hscript/CustomClassHandler.hx +++ b/hscript/CustomClassHandler.hx @@ -22,7 +22,7 @@ class CustomClassHandler implements IHScriptCustomConstructor { this.extend = extend; this.interfaces = interfaces; - this.cl = extend == null ? TemplateClass : Type.resolveClass('${extend}_HSX'); + this.cl = extend == null ? CustomTemplateClass : Type.resolveClass('${extend}_HSX'); if(cl == null) ogInterp.error(EInvalidClass(extend)); } @@ -153,7 +153,7 @@ class CustomClassHandler implements IHScriptCustomConstructor { } } -class TemplateClass implements IHScriptCustomClassBehaviour implements IHScriptCustomBehaviour { +class CustomTemplateClass implements IHScriptCustomClassBehaviour implements IHScriptCustomAccessBehaviour { public var __interp:Interp; public var __allowSetGet:Bool = true; public var __custom__variables:Map; @@ -198,6 +198,45 @@ class TemplateClass implements IHScriptCustomClassBehaviour implements IHScriptC } } + +/** + * This is for backwards compatibility with old hscript-improved, since some scripts use it +**/ +@:dox(hide) +@:keep +class TemplateClass implements IHScriptCustomBehaviour implements IHScriptCustomAccessBehaviour { + public var __interp:Interp; + public var __allowSetGet:Bool = true; + + public function hset(name:String, val:Dynamic):Dynamic { + var variables = __interp.variables; + if(__allowSetGet && variables.exists("set_" + name)) + return __callSetter(name, val); + variables.set(name, val); + return val; + } + public function hget(name:String):Dynamic { + var variables = __interp.variables; + if(__allowSetGet && variables.exists("get_" + name)) + return __callGetter(name); + return variables.get(name); + } + + public function __callGetter(name:String):Dynamic { + __allowSetGet = false; + var v = __interp.variables.get("get_" + name)(); + __allowSetGet = true; + return v; + } + + public function __callSetter(name:String, val:Dynamic):Dynamic { + __allowSetGet = false; + var v = __interp.variables.get("set_" + name)(val); + __allowSetGet = true; + return v; + } +} + final class StaticHandler { public function new() {} } \ No newline at end of file diff --git a/hscript/IHScriptCustomAccessBehaviour.hx b/hscript/IHScriptCustomAccessBehaviour.hx new file mode 100644 index 0000000..12e982a --- /dev/null +++ b/hscript/IHScriptCustomAccessBehaviour.hx @@ -0,0 +1,11 @@ +package hscript; + +interface IHScriptCustomAccessBehaviour { + var __allowSetGet:Bool; + + public function hset(name:String, val:Dynamic):Dynamic; + public function hget(name:String):Dynamic; + + public function __callGetter(name:String):Dynamic; + public function __callSetter(name:String, val:Dynamic):Dynamic; +} \ No newline at end of file diff --git a/hscript/Interp.hx b/hscript/Interp.hx index 23e61a5..e97eb3f 100644 --- a/hscript/Interp.hx +++ b/hscript/Interp.hx @@ -48,6 +48,7 @@ enum abstract ScriptObjectType(UInt8) { var SStaticClass; var SCustomClass; // custom classes var SBehaviourClass; // hget and hset + var SAccessBehaviourObject; // hget and hset with __allowSetGet var SNull; } @@ -79,6 +80,8 @@ class Interp { if(classFields != null) __instanceFields = __instanceFields.concat(classFields); _scriptObjectType = SCustomClass; + } else if(v is IHScriptCustomAccessBehaviour) { + _scriptObjectType = SAccessBehaviourObject; } else if(v is IHScriptCustomBehaviour) { _scriptObjectType = SBehaviourClass; } else { @@ -109,6 +112,7 @@ class Interp { public var publicVariables:Map; public var staticVariables:Map; + // warning can be null public var locals:Map; var binops:MapExpr->Dynamic>; @@ -240,7 +244,8 @@ class Interp { var v = expr(e2); switch (Tools.expr(e1)) { case EIdent(id): - if (!locals.exists(id)) { + var l = locals.get(id); + if (l == null) { if (_hasScriptObject && !varExists(id)) { var instanceHasField = __instanceFields.contains(id); @@ -256,7 +261,17 @@ class Interp { return res; } return obj.hset(id, v); - } else if (_scriptObjectType == SBehaviourClass) { + } else if(_scriptObjectType == SAccessBehaviourObject) { + var obj:IHScriptCustomAccessBehaviour = cast scriptObject; + if(isBypassAccessor) { + obj.__allowSetGet = false; + var res = obj.hset(id, v); + obj.__allowSetGet = true; + return res; + } + return obj.hset(id, v); + } + else if (_scriptObjectType == SBehaviourClass) { var obj:IHScriptCustomBehaviour = cast scriptObject; return obj.hset(id, v); } @@ -278,7 +293,6 @@ class Interp { setVar(id, v); } } else { - var l = locals.get(id); l.r = v; if (l.depth == 0) { setVar(id, v); @@ -313,8 +327,9 @@ class Interp { var v; switch (Tools.expr(e1)) { case EIdent(id): + var l = locals.get(id); v = fop(expr(e1), expr(e2)); - if (!locals.exists(id)) { + if (l == null) { if(_hasScriptObject && !varExists(id)) { var instanceHasField = __instanceFields.contains(id); @@ -330,7 +345,17 @@ class Interp { return res; } return obj.hset(id, v); - } else if (_scriptObjectType == SBehaviourClass) { + } else if(_scriptObjectType == SAccessBehaviourObject) { + var obj:IHScriptCustomAccessBehaviour = cast scriptObject; + if(isBypassAccessor) { + obj.__allowSetGet = false; + var res = obj.hset(id, v); + obj.__allowSetGet = true; + return res; + } + return obj.hset(id, v); + } + else if (_scriptObjectType == SBehaviourClass) { var obj:IHScriptCustomBehaviour = cast scriptObject; return obj.hset(id, v); } @@ -389,8 +414,8 @@ class Interp { #end switch (e) { case EIdent(id): - if(locals.exists(id)) { - var l = locals.get(id); + var l = locals.get(id); + if(l != null) { var v:Dynamic = l.r; if (prefix) { v += delta; @@ -452,6 +477,8 @@ class Interp { return exprReturn(expr); } + public var printCallStack:Bool = true; + function exprReturn(e):Dynamic { try { try { @@ -468,7 +495,10 @@ class Interp { return v; } } catch(e) { - error(ECustom('${e.toString()}')); + if(printCallStack) + error(ECustom('${e.toString()}\n${CallStack.toString(CallStack.exceptionStack(true))}')); + else + error(ECustom(e.toString())); return null; } } catch(e:Error) { @@ -525,8 +555,12 @@ class Interp { if (id == null) return null; id = StringTools.trim(id); - if (locals.exists(id)) - return locals.get(id).r; + + if (locals.exists(id)) { + var l = locals.get(id); + if(l != null) + return l.r; + } if(variables.exists(id)) return variables.get(id); @@ -555,6 +589,15 @@ class Interp { return res; } return obj.hget(id); + } else if(_scriptObjectType == SAccessBehaviourObject) { + var obj:IHScriptCustomAccessBehaviour = cast scriptObject; + if(isBypassAccessor) { + obj.__allowSetGet = false; + var res = obj.hget(id); + obj.__allowSetGet = true; + return res; + } + return obj.hget(id); } else if(_scriptObjectType == SBehaviourClass) { var obj:IHScriptCustomBehaviour = cast scriptObject; return obj.hget(id); @@ -1171,6 +1214,17 @@ class Interp { return obj.hget(f); } + if (o is IHScriptCustomAccessBehaviour) { + var obj:IHScriptCustomAccessBehaviour = cast o; + if(isBypassAccessor) { + obj.__allowSetGet = false; + var res = obj.hget(f); + obj.__allowSetGet = true; + return res; + } + return obj.hget(f); + } + if (o is IHScriptCustomBehaviour) { var obj:IHScriptCustomBehaviour = cast o; return obj.hget(f); @@ -1209,6 +1263,17 @@ class Interp { return obj.hset(f, v); } + if (o is IHScriptCustomAccessBehaviour) { + var obj:IHScriptCustomAccessBehaviour = cast o; + if(isBypassAccessor) { + obj.__allowSetGet = false; + var res = obj.hset(f, v); + obj.__allowSetGet = true; + return res; + } + return obj.hset(f, v); + } + if (o is IHScriptCustomBehaviour) { var obj:IHScriptCustomBehaviour = cast o; return obj.hset(f, v); diff --git a/hscript/macros/ClassExtendMacro.hx b/hscript/macros/ClassExtendMacro.hx index 9c7ec92..18e5c59 100644 --- a/hscript/macros/ClassExtendMacro.hx +++ b/hscript/macros/ClassExtendMacro.hx @@ -60,6 +60,7 @@ class ClassExtendMacro { if(key == "away3d.tools.commands.SphereMaker") return fields; // Error: Unknown identifier if(key == "away3d.tools.commands.Weld") return fields; // Error: Unknown identifier if(fkey == "hscript.CustomClassHandler.TemplateClass") return fields; // Error: Redefined + if(fkey == "hscript.CustomClassHandler.CustomTemplateClass") return fields; // Error: Redefined if(key == "sys.thread.EventLoop") return fields; // Error: cant override force inlined if(Config.DISALLOW_CUSTOM_CLASSES.contains(cl.module) || Config.DISALLOW_CUSTOM_CLASSES.contains(fkey)) return fields; if(cl.module.contains("_")) return fields; // Weird issue, sorry @@ -330,7 +331,7 @@ class ClassExtendMacro { pack: cl.pack.copy(), name: cl.name }, [ - {name: "IHScriptCustomBehaviour", pack: ["hscript"]}, + {name: "IHScriptCustomAccessBehaviour", pack: ["hscript"]}, {name: "IHScriptCustomClassBehaviour", pack: ["hscript"]} ], false, true, false); shadowClass.name = '${cl.name}$CLASS_SUFFIX';