custom classes progress
This commit is contained in:
@@ -128,6 +128,9 @@
|
||||
<!-- Comment this out to disable support for custom ndlls. !-->
|
||||
<haxedef name="NDLLS_SUPPORTED" />
|
||||
|
||||
<!-- Comment this out to disable support for custom extended classes (data/classes). !-->
|
||||
<define name="SOFTCODED_CLASSES" />
|
||||
|
||||
<!-- Comment this out to disable video cutscene support, in case of compilation errors. !-->
|
||||
<define name="VIDEO_CUTSCENES" unless="web || linux || hl || mac" />
|
||||
|
||||
@@ -139,6 +142,9 @@
|
||||
<haxedef name="UPDATE_CHECKING" if="UPDATE_CHECKING" />
|
||||
<haxedef name="DISCORD_RPC" if="DISCORD_RPC" />
|
||||
<haxedef name="SHOW_BUILD_ON_FPS" if="SHOW_BUILD_ON_FPS" />
|
||||
<haxedef name="SOFTCODED_CLASSES" if="SOFTCODED_CLASSES" />
|
||||
|
||||
<haxeflag name="--macro" value="funkin.macros.SoftcodedClassMacro.init()" />
|
||||
<haxeflag name="--macro" value="funkin.macros.StdDeprecationsRemover.init()" />
|
||||
<!-- _______________________________ Libraries ______________________________ -->
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ using StringTools;
|
||||
@:allow(funkin.desktop.editors.CharacterEditor)
|
||||
@:allow(funkin.game.StrumLine)
|
||||
@:allow(funkin.game.PlayState)
|
||||
@:build(funkin.macros.SoftcodedClassMacro.build())
|
||||
class Character extends FunkinSprite implements IBeatReceiver implements IOffsetCompatible
|
||||
{
|
||||
private var __stunnedTime:Float = 0;
|
||||
|
||||
@@ -17,23 +17,5 @@ class ScriptsMacro {
|
||||
// FOR ABSTRACTS
|
||||
Compiler.addGlobalMetadata('haxe.xml', '@:build(hscript.UsingHandler.build())');
|
||||
}
|
||||
|
||||
public static function build():Array<Field> {
|
||||
var fields:Array<Field> = Context.getBuildFields();
|
||||
|
||||
for(f in fields) {
|
||||
switch(f.kind) {
|
||||
case FFun(func):
|
||||
if (f.access == null) f.access = [];
|
||||
if (f.access.contains(AInline))
|
||||
f.access.remove(AInline);
|
||||
f.access.push(ADynamic);
|
||||
default:
|
||||
// do nothing u piece of shit
|
||||
}
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
}
|
||||
#end
|
||||
@@ -0,0 +1,118 @@
|
||||
package funkin.macros;
|
||||
|
||||
class SoftcodedClassMacro {
|
||||
#if macro
|
||||
public static function init() {
|
||||
trace("cock and balls");
|
||||
// Compiler.addGlobalMetadata('funkin.game', '@:build(funkin.macros.SoftcodedClassMacro.build())');
|
||||
}
|
||||
|
||||
public static function build():Array<Field> {
|
||||
var fields = Context.getBuildFields();
|
||||
var cl = Context.getLocalClass();
|
||||
|
||||
var funcs:Array<Field> = [];
|
||||
if (cl != null) {
|
||||
var c = cl.get();
|
||||
if (c.isAbstract) return fields;
|
||||
|
||||
for(m in c.meta.get()) {
|
||||
switch(m.name) {
|
||||
case ":final", ":noSoftcodedExtend":
|
||||
return fields;
|
||||
default:
|
||||
// cool
|
||||
}
|
||||
}
|
||||
|
||||
for(f in fields) {
|
||||
var valid = true;
|
||||
if (f.access != null) for(e in f.access) {
|
||||
switch (e) {
|
||||
case AStatic | ADynamic | AInline | AMacro | AFinal | AExtern | AAbstract:
|
||||
valid = false;
|
||||
break;
|
||||
default:
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid) continue;
|
||||
|
||||
switch(f.kind) {
|
||||
case FFun(fun):
|
||||
var funcExpr = macro {
|
||||
${{
|
||||
pos: Context.currentPos(),
|
||||
expr: ECall({
|
||||
pos: Context.currentPos(),
|
||||
expr: EField({
|
||||
pos: Context.currentPos(),
|
||||
expr: EConst(CIdent("super"))
|
||||
}, f.name)
|
||||
}, fun.args != null ? [for(a in fun.args) {
|
||||
pos: Context.currentPos(),
|
||||
expr: EConst(CIdent(a.name))
|
||||
}] : [])
|
||||
}};
|
||||
};
|
||||
|
||||
var accessors = [];
|
||||
if (f.access != null) for(f in f.access) accessors.push(f);
|
||||
accessors.remove(AOverride);
|
||||
|
||||
if (f.name != "new") {
|
||||
var func:Function = {
|
||||
expr: funcExpr,
|
||||
args: fun.args
|
||||
};
|
||||
funcs.push({
|
||||
pos: Context.currentPos(),
|
||||
name: '__super__${f.name}',
|
||||
kind: FFun(func),
|
||||
access: accessors
|
||||
});
|
||||
}
|
||||
|
||||
accessors.push(AOverride);
|
||||
|
||||
var overrideFuncExpr = macro {
|
||||
var fieldName = ${{
|
||||
pos: Context.currentPos(),
|
||||
expr: EConst(CString(f.name, DoubleQuotes))
|
||||
}};
|
||||
if (__scriptClass != null && __scriptClass.hasField(fieldName) && Reflect.isFunction(__scriptClass.get(fieldName))) {
|
||||
__scriptClass.call(fieldName, ${{
|
||||
pos: Context.currentPos(),
|
||||
expr: EArrayDecl([for(a in fun.args) {
|
||||
pos: Context.currentPos(),
|
||||
expr: EConst(CIdent(a.name))
|
||||
}])
|
||||
}});
|
||||
} else ${funcExpr}
|
||||
};
|
||||
|
||||
var overrideFunc:Function = {
|
||||
expr: overrideFuncExpr,
|
||||
args: fun.args
|
||||
};
|
||||
funcs.push({
|
||||
pos: Context.currentPos(),
|
||||
name: '${f.name}',
|
||||
kind: FFun(overrideFunc),
|
||||
access: accessors
|
||||
});
|
||||
|
||||
|
||||
|
||||
var printer = new Printer();
|
||||
trace(printer.printField(funcs[funcs.length - 1]));
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
#end
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package funkin.scripting;
|
||||
|
||||
import funkin.scripting.Script.ScriptClass;
|
||||
import hscript.Expr.ClassDecl;
|
||||
import hscript.Expr.ModuleDecl;
|
||||
import hscript.Expr.Error;
|
||||
import hscript.Parser;
|
||||
import openfl.Assets;
|
||||
@@ -9,16 +12,23 @@ class HScript extends Script {
|
||||
public var interp:Interp;
|
||||
public var parser:Parser;
|
||||
public var expr:Expr;
|
||||
public var decls:Array<ModuleDecl> = null;
|
||||
public var code:String;
|
||||
|
||||
public static function initParser() {
|
||||
var parser = new Parser();
|
||||
parser.allowJSON = parser.allowMetadata = parser.allowTypes = true;
|
||||
parser.preprocesorValues = Script.getDefaultPreprocessors();
|
||||
return parser;
|
||||
}
|
||||
|
||||
public override function onCreate(path:String) {
|
||||
super.onCreate(path);
|
||||
|
||||
interp = new Interp();
|
||||
|
||||
var code:String = Assets.getText(path);
|
||||
parser = new Parser();
|
||||
parser.allowJSON = parser.allowMetadata = parser.allowTypes = true;
|
||||
parser.preprocesorValues = Script.getDefaultPreprocessors();
|
||||
code = Assets.getText(path);
|
||||
parser = initParser();
|
||||
interp.errorHandler = _errorHandler;
|
||||
interp.staticVariables = Script.staticVariables;
|
||||
interp.allowStaticVariables = interp.allowPublicVariables = true;
|
||||
@@ -117,6 +127,27 @@ class HScript extends Script {
|
||||
this.interp.publicVariables = map;
|
||||
}
|
||||
|
||||
public override function getClass(name:String) {
|
||||
if (decls == null) {
|
||||
decls = parser.parseModule(code, fileName);
|
||||
}
|
||||
for(d in decls) {
|
||||
switch(d) {
|
||||
case DPackage(path):
|
||||
// ignore
|
||||
case DImport(path, everything):
|
||||
// ignore
|
||||
case DClass(c):
|
||||
if (c.name == name) {
|
||||
|
||||
}
|
||||
case DTypedef(c):
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override function onDestroy() {
|
||||
@:privateAccess {
|
||||
// INTERP
|
||||
@@ -182,4 +213,40 @@ class HScript extends Script {
|
||||
interp = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HScriptClass extends ScriptClass {
|
||||
var decl:ClassDecl;
|
||||
var name:String;
|
||||
|
||||
var interp:Interp;
|
||||
|
||||
public function new(decl:ClassDecl, sInterp:Interp) {
|
||||
super();
|
||||
this.name = decl.name;
|
||||
|
||||
|
||||
|
||||
interp = new Interp();
|
||||
interp.errorHandler = sInterp.errorHandler;
|
||||
interp.staticVariables = sInterp.staticVariables;
|
||||
interp.allowStaticVariables = interp.allowPublicVariables = false;
|
||||
// interp.execute({ e : EBlock(decl.fields), pmin : 0, pmax : 0, origin : fileName, line : 0 });
|
||||
|
||||
var parser = HScript.initParser();
|
||||
|
||||
for(f in decl.fields) {
|
||||
switch(f.kind) {
|
||||
case KVar(v):
|
||||
interp.variables[f.name] = interp.execute(v.expr);
|
||||
case KFunction(fun):
|
||||
@:privateAccess
|
||||
interp.variables[f.name] = interp.execute(parser.mk(EFunction(fun.args, fun.expr, f.name, fun.ret, false, false)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override function get(field:String) {
|
||||
return interp.variables[field];
|
||||
}
|
||||
}
|
||||
@@ -266,8 +266,22 @@ class Script extends FlxBasic implements IFlxDestroyable {
|
||||
|
||||
public function onDestroy() {};
|
||||
|
||||
public function getClass(name:String):ScriptClass {
|
||||
return null;
|
||||
}
|
||||
|
||||
public override function destroy() {
|
||||
super.destroy();
|
||||
onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
class ScriptClass {
|
||||
public function new() {}
|
||||
|
||||
public function get(field:String):Dynamic {return null;}
|
||||
|
||||
public function set(field:String, v:Dynamic) {}
|
||||
|
||||
public function call(field:String, ?args:Array<Dynamic>) {return null;}
|
||||
}
|
||||
Reference in New Issue
Block a user