Improved Custom Classes (getting fields outside of the class)

This commit is contained in:
NeeEoo
2023-04-10 14:14:16 +02:00
parent 1d67946f3f
commit 732bd1520a
2 changed files with 161 additions and 15 deletions
+143 -2
View File
@@ -62,6 +62,8 @@ class ClassExtendMacro {
if (f.access.contains(ADynamic) || f.access.contains(AStatic) || f.access.contains(AExtern) || f.access.contains(AInline))
continue;
if(f.name == "hget" || f.name == "hset") continue; // sorry, no overwriting the hget and hset in custom classes
switch(f.kind) {
case FFun(fun):
if (fun.params != null && fun.params.length > 0)
@@ -178,6 +180,8 @@ class ClassExtendMacro {
args: fun.args.copy()
};
//trace(func.args);
var overrideField:Field = {
name: f.name,
access: f.access.copy(),
@@ -214,7 +218,9 @@ class ClassExtendMacro {
shadowClass.kind = TDClass({
pack: cl.pack.copy(),
name: cl.name
}, [], false, true, false);
}, [
{name: "IHScriptCustomBehaviour", pack: ["hscript"]}
], false, true, false);
shadowClass.name = '${cl.name}$CLASS_SUFFIX';
shadowClass.meta = [{
name: ':dox',
@@ -271,7 +277,142 @@ class ClassExtendMacro {
}))
});
var t:ClassType;
// Todo: get this working
if(cl.name == "FunkinShader" || cl.name == "CustomShader" || cl.name == "MultiThreadedScript") {
Context.defineModule(cl.module + CLASS_SUFFIX, [shadowClass], imports);
return fields;
}
var hasHgetInSuper = false;
var hasHsetInSuper = false;
if(cl.name == "CustomShader") {
hasHgetInSuper = hasHsetInSuper = true;
}
// TODO: somehow check the super super class
for(f in fields.copy()) {
if (f.name == "new")
continue;
if (f.name.startsWith(FUNC_PREFIX))
continue;
if (f.access.contains(ADynamic) || f.access.contains(AStatic) || f.access.contains(AExtern))
continue;
switch(f.kind) {
case FFun(fun):
if (fun.params != null && fun.params.length > 0)
continue;
if(!hasHgetInSuper)
hasHgetInSuper = f.name == "hget";
if(!hasHsetInSuper)
hasHsetInSuper = f.name == "hset";
if(hasHgetInSuper && hasHsetInSuper)
break;
default:
}
}
var hgetField = if(hasHgetInSuper) {
macro {
if(this.__interp.variables.exists("get_" + name))
return this.__interp.variables.get("get_" + name)();
if (this.__interp.variables.exists(name))
return this.__interp.variables.get(name);
return super.hget(name);
}
} else {
macro {
if(this.__interp.variables.exists("get_" + name))
return this.__interp.variables.get("get_" + name)();
if (this.__interp.variables.exists(name))
return this.__interp.variables.get(name);
return Reflect.getProperty(this, name);
}
}
var hsetField = if(hasHsetInSuper) {
macro {
if(this.__interp.variables.exists("set_" + name)) {
return this.__interp.variables.get("set_" + name)(val); // TODO: Prevent recursion from setting it in the function
}
if (this.__interp.variables.exists(name)) {
this.__interp.variables.set(name, val);
return val;
}
return super.hset(this, name);
}
} else {
macro {
if(this.__interp.variables.exists("set_" + name)) {
return this.__interp.variables.get("set_" + name)(val); // TODO: Prevent recursion from setting it in the function
}
if (this.__interp.variables.exists(name)) {
this.__interp.variables.set(name, val);
return val;
}
Reflect.setProperty(this, name, val);
return Reflect.field(this, name);
}
}
//if(hasHsetInSuper || hasHgetInSuper) return fields;
//trace(cl.name);
shadowClass.fields.push({
name: "hset",
pos: Context.currentPos(),
access: hasHsetInSuper ? [AOverride, APublic] : [APublic],
kind: FFun({
ret: TPath({name: 'Dynamic', pack: []}),
params: [],
expr: hsetField,
args: [
{
name: "name",
opt: false,
meta: [],
type: TPath({name: "String", pack: []})
},
{
name: "val",
opt: false,
meta: [],
type: TPath({name: "Dynamic", pack: []})
}
]
})
});
shadowClass.fields.push({
name: "hget",
pos: Context.currentPos(),
access: hasHgetInSuper ? [AOverride, APublic] : [APublic],
kind: FFun({
ret: TPath({name: 'Dynamic', pack: []}),
params: [],
expr: hgetField,
args: [
{
name: "name",
opt: false,
meta: [],
type: TPath({name: "String", pack: []})
}
]
})
});
/*var p = new Printer();
var aa = p.printTypeDefinition(shadowClass);
//if(aa.indexOf("pack") >= 0)
if(cl.name == "FunkinShader")
trace(aa);*/
Context.defineModule(cl.module + CLASS_SUFFIX, [shadowClass], imports);
}
+18 -13
View File
@@ -1,5 +1,7 @@
package hscript;
using StringTools;
class CustomClassHandler implements IHScriptCustomConstructor {
public static var staticHandler = new StaticHandler();
@@ -31,16 +33,18 @@ class CustomClassHandler implements IHScriptCustomConstructor {
if (e != null && e.depth <= 0)
capturedLocals.set(k, e);
var disallowCopy = Type.getInstanceFields(cl);
//trace("Locals");
for (key => value in capturedLocals) {
if(Reflect.getProperty(_class, key) == null) {
if(!disallowCopy.contains(key)) {
interp.locals.set(key, {r: value, depth: -1});
//trace(key, value);
}
}
//trace("Variables");
for (key => value in ogInterp.variables) {
if(Reflect.getProperty(_class, key) == null) {
if(!disallowCopy.contains(key)) {
interp.variables.set(key, value);
//trace(key, value);
}
@@ -77,21 +81,22 @@ class TemplateClass implements IHScriptCustomBehaviour {
public var __interp:Interp;
public function hset(name:String, val:Dynamic):Dynamic {
if(Reflect.hasField(this, name)) {
Reflect.setProperty(this, name, val);
return Reflect.getProperty(this, name); // Incase it overwrites the return value
}
if(this.__interp.variables.exists("set_" + name)) {
return this.__interp.variables.get("set_" + name)(val); // TODO: Prevent recursion from setting it in the function
}
this.__interp.variables.set(name, val);
return val;
}
public function hget(name:String):Dynamic {
if(Reflect.hasField(this, name)) {
return Reflect.getProperty(this, name);
if (this.__interp.variables.exists(name)) {
this.__interp.variables.set(name, val);
return val;
}
return this.__interp.variables.get(name);
Reflect.setProperty(this, name, val);
return Reflect.field(this, name);
}
public function hget(name:String):Dynamic {
if(this.__interp.variables.exists("get_" + name))
return this.__interp.variables.get("get_" + name)();
if (this.__interp.variables.exists(name))
return this.__interp.variables.get(name);
return Reflect.getProperty(this, name);
}
}