This commit is contained in:
Yoshman29
2023-04-01 17:53:38 +02:00
parent 71ef2243f6
commit b60ad1b1bb
4 changed files with 31 additions and 175 deletions
+1 -1
View File
@@ -677,7 +677,7 @@ class PlayState extends MusicBeatState
startingSong = true;
super.create();
for(s in introSprites)
if (s != null)
graphicCache.cache(Paths.image(s));
+27 -95
View File
@@ -1,7 +1,6 @@
package funkin.scripting;
import haxe.io.Path;
import funkin.scripting.Script.ScriptClass;
import hscript.Expr.ClassDecl;
import hscript.Expr.ModuleDecl;
import hscript.Expr.Error;
@@ -16,6 +15,7 @@ class HScript extends Script {
public var decls:Array<ModuleDecl> = null;
public var code:String;
public var folderlessPath:String;
var __importedPaths:Array<String>;
public static function initParser() {
var parser = new Parser();
@@ -32,6 +32,7 @@ class HScript extends Script {
code = Assets.getText(path);
parser = initParser();
folderlessPath = Path.directory(path);
__importedPaths = [path];
interp.errorHandler = _errorHandler;
interp.importFailedCallback = importFailedCallback;
@@ -55,21 +56,30 @@ class HScript extends Script {
}
private function importFailedCallback(cl:Array<String>):Bool {
var path = cl.join("/");
var scr = Script.create(Paths.script('classes/$path', null, false));
if (!(scr is DummyScript)) {
// script is valid
var cla = scr.getClass(cl.last());
if (cla != null) {
interp.variables.set(cl.last(), Script.createCustomClass(cla));
} else {
interp.variables.set(cl.last(), scr);
var assetsPath = 'assets/data/classes/${cl.join("/")}';
for(hxExt in ["hx", "hscript", "hsc", "hxs"]) {
var p = '$assetsPath.$hxExt';
if (__importedPaths.contains(p))
return true; // no need to reimport again
if (Assets.exists(p)) {
var code = Assets.getText(p);
var expr:Expr = null;
try {
if (code != null && code.trim() != "")
expr = parser.parseString(code);
} catch(e:Error) {
_errorHandler(e);
} catch(e) {
_errorHandler(new Error(ECustom(e.toString()), 0, 0, fileName, 0));
}
if (expr != null) {
@:privateAccess
interp.exprReturn(expr);
__importedPaths.push(p);
}
return true;
}
return true;
}
return false;
}
@@ -90,6 +100,8 @@ class HScript extends Script {
}
public override function onLoad() {
@:privateAccess
interp.execute(parser.mk(EBlock([]), 0, 0));
if (expr != null) {
interp.execute(expr);
call("new", []);
@@ -98,7 +110,7 @@ class HScript extends Script {
public override function reload() {
// save variables
interp.allowStaticVariables = interp.allowPublicVariables = false;
var savedVariables:Map<String, Dynamic> = [];
for(k=>e in interp.variables) {
@@ -151,29 +163,6 @@ class HScript extends Script {
this.interp.publicVariables = map;
}
public override function getClass(name:String) {
if (decls == null) {
decls = parser.parseModule(code, fileName);
}
var imports:Array<Array<String>> = [];
for(d in decls) {
switch(d) {
case DPackage(path):
// ignore
case DImport(path, everything):
imports.push(path);
case DClass(c):
trace(c.name);
trace(name);
if (c.name == name)
return new HScriptClass(c, interp, imports, folderlessPath);
case DTypedef(c):
// ignore
}
}
return null;
}
public override function onDestroy() {
@:privateAccess {
// INTERP
@@ -240,60 +229,3 @@ class HScript extends Script {
}
}
}
class HScriptClass extends ScriptClass {
var decl:ClassDecl;
var name:String;
var interp:Interp;
public function new(decl:ClassDecl, sInterp:Interp, classesToImport:Array<Array<String>>, forderlessPath:String) {
super();
this.name = decl.name;
switch(decl.extend) {
case CTPath(p, params):
this.classPath = p.join(".");
default:
}
interp = new Interp();
interp.errorHandler = sInterp.errorHandler;
interp.staticVariables = sInterp.staticVariables;
interp.allowStaticVariables = interp.allowPublicVariables = true;
interp.importFailedCallback = importFailedCallback;
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 hasField(field:String) {
return interp.variables.exists(field);
}
public override function get(field:String) {
return interp.variables[field];
}
public override function set(field:String, v:Dynamic) {
interp.variables[field] = v;
}
public override function onCall(field:String, parameters:Array<Dynamic>, parent:Dynamic) {
interp.scriptObject = parent;
var v = interp.variables[field];
if (v != null && Reflect.isFunction(v))
return (parameters != null && parameters.length > 0) ? Reflect.callMethod(null, v, parameters) : v();
return null;
}
}
-76
View File
@@ -142,15 +142,6 @@ class Script extends FlxBasic implements IFlxDestroyable {
return new DummyScript(path);
}
public static function createCustomClass(s:ScriptClass) {
var t:Class<IScriptClassInstance> = cast Type.resolveClass('${s.classPath}__Softcoded');
if (t == null) {
Logs.trace('Class at ${s.classPath} was not found.', ERROR);
return null;
}
return new ScriptCustomClass(s, t);
}
/**
* Creates a new instance of the script class.
* @param path
@@ -263,75 +254,8 @@ 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 var classPath:String = null;
public var folderlessPath:String = null;
public function new() {}
public function get(field:String):Dynamic {return null;}
public function set(field:String, v:Dynamic) {}
public function hasField(field:String):Bool {return false;}
/**
* Calls the function `func` defined in the class.
* @param func Name of the function
* @param parameters (Optional) Parameters of the function.
* @return Result (if void, then null)
*/
public function call(func:String, parameters:Array<Dynamic>, parent:Dynamic):Dynamic {
var result = onCall(func, parameters == null ? [] : parameters, parent);
return result;
}
public function onCall(func:String, parameters:Array<Dynamic>, parent:Dynamic):Dynamic {return null;}
private function importFailedCallback(cl:Array<String>):Bool {
var path = cl.join("/");
var scr = Script.create(Paths.script('$folderlessPath$path', null, true));
if (!(scr is DummyScript)) {
// script is valid
var cla = scr.getClass(cl.last());
if (cla != null) {
set(cl.last(), Script.createCustomClass(cla));
} else {
set(cl.last(), scr);
}
return true;
}
return false;
}
}
class ScriptCustomClass implements IHScriptCustomConstructor {
var scrClass:ScriptClass;
var scrType:Class<IScriptClassInstance>;
public function new(scrClass:ScriptClass, scrType:Class<IScriptClassInstance>) {
this.scrClass = scrClass;
this.scrType = scrType;
}
public function hnew(args:Array<Dynamic>):Dynamic {
var a = [for(arg in args) arg];
a.insert(0, scrClass);
return Type.createInstance(scrType, a);
}
}
interface IScriptClassInstance {
}
+3 -3
View File
@@ -24,7 +24,7 @@ enum abstract Action(String) to String from String {
var RIGHT_R = "right-release";
var DOWN_R = "down-release";
var NOTE_UP = "note-up";
var NOTE_LEFT = "note-left";
var NOTE_RIGHT = "note-right";
@@ -575,7 +575,7 @@ class Controls extends FlxActionSet
removeKeyboard();
keyboardScheme = scheme;
switch (scheme)
{
case Solo:
@@ -642,7 +642,7 @@ class Controls extends FlxActionSet
public function addGamepad(id:Int, ?buttonMap:Map<Control, Array<FlxGamepadInputID>>):Void
{
gamepadsAdded.push(id);
#if (haxe >= "4.0.0")
for (control => buttons in buttonMap)
inline bindButtons(control, id, buttons);