From 114dcfcd702cfa3a2149c1a391fcc78c02026bcc Mon Sep 17 00:00:00 2001 From: Yoshman29 <81191621+YoshiCrafter29@users.noreply.github.com> Date: Thu, 12 Jan 2023 00:46:25 +0100 Subject: [PATCH] softcoded multithreading --- buildnumber.txt | 2 +- source/funkin/menus/PauseSubState.hx | 2 +- source/funkin/scripting/HScript.hx | 6 +- .../funkin/scripting/MultiThreadedScript.hx | 89 +++++++++++++++++++ source/funkin/scripting/Script.hx | 6 +- source/funkin/utils/EngineUtil.hx | 15 ++++ 6 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 source/funkin/scripting/MultiThreadedScript.hx create mode 100644 source/funkin/utils/EngineUtil.hx diff --git a/buildnumber.txt b/buildnumber.txt index 006b3ab0..a66320e8 100644 --- a/buildnumber.txt +++ b/buildnumber.txt @@ -1 +1 @@ -2008 \ No newline at end of file +2010 \ No newline at end of file diff --git a/source/funkin/menus/PauseSubState.hx b/source/funkin/menus/PauseSubState.hx index a623667c..c8c3e129 100644 --- a/source/funkin/menus/PauseSubState.hx +++ b/source/funkin/menus/PauseSubState.hx @@ -157,7 +157,7 @@ class PauseSubState extends MusicBeatSubstate override function destroy() { FlxG.cameras.remove(camera, true); - pauseScript.call("destroy"); + pauseScript.call("onDestroy"); if (pauseMusic != null) pauseMusic.destroy(); pauseScript.destroy(); diff --git a/source/funkin/scripting/HScript.hx b/source/funkin/scripting/HScript.hx index 8a39c44d..3e3f7a36 100644 --- a/source/funkin/scripting/HScript.hx +++ b/source/funkin/scripting/HScript.hx @@ -5,8 +5,8 @@ import openfl.Assets; import hscript.*; class HScript extends Script { - var interp:Interp; - var expr:Expr; + public var interp:Interp; + public var expr:Expr; public override function onCreate(path:String) { super.onCreate(path); @@ -72,7 +72,7 @@ class HScript extends Script { var oldParent = interp.scriptObject; onCreate(path); - for(k=>e in Script.getDefaultVariables()) + for(k=>e in Script.getDefaultVariables(this)) set(k, e); load(); diff --git a/source/funkin/scripting/MultiThreadedScript.hx b/source/funkin/scripting/MultiThreadedScript.hx new file mode 100644 index 00000000..81ba6457 --- /dev/null +++ b/source/funkin/scripting/MultiThreadedScript.hx @@ -0,0 +1,89 @@ +package funkin.scripting; + +#if ALLOW_MULTITHREADING +import sys.thread.Thread; +import flixel.util.FlxDestroyUtil; +#end + +import hscript.IHScriptCustomBehaviour; + +class MultiThreadedScript implements IFlxDestroyable implements IHScriptCustomBehaviour { + var thread:#if ALLOW_MULTITHREADING Thread #else Dynamic #end; + + /** + * Script being ran. + */ + public var script:Script; + + private var __variables:Array; + + /** + * Return value of the last call. + */ + public var returnValue:Dynamic = null; + + /** + * Whenever the current call has ended. + */ + public var callEnded:Bool = true; + + + + public function new(path:String, ?parentScript:Script) { + script = Script.create(path); + + if (parentScript != null) { + if (script is HScript && parentScript is HScript) { + var hscript = cast(script, HScript); + var parentHScript = cast(parentScript, HScript); + + hscript.interp.variables = parentHScript.interp.variables; + hscript.interp.publicVariables = parentHScript.interp.publicVariables; + hscript.interp.staticVariables = parentHScript.interp.staticVariables; + + script.setParent(parentHScript.interp.scriptObject); + } + } + + script.load(); + + thread = Thread.createWithEventLoop(function() { + // Prevent the thread from being auto deleted + Thread.current().events.promise(); + }); + + __variables = Type.getInstanceFields(Type.getClass(this)); + } + + public inline function hget(name:String):Dynamic + return __variables.contains(name) ? Reflect.getProperty(this, name) : script.get(name); + + public inline function hset(name:String, val:Dynamic):Dynamic { + if (__variables.contains(name)) + Reflect.setProperty(this, name, val); + else + script.set(name, val); + return val; + } + + public function call(func:String, args:Array) { + thread.events.run(function() { + callEnded = false; + returnValue = script.call(func, args); + callEnded = true; + }); + } + + public function destroy() { + if (script != null) { + script.call("onDestroy"); + script.destroy(); + } + + if (thread != null) { + thread.events.runPromised(function() { + // close the thing + }); + } + } +} \ No newline at end of file diff --git a/source/funkin/scripting/Script.hx b/source/funkin/scripting/Script.hx index 4ced6877..ee5491ac 100644 --- a/source/funkin/scripting/Script.hx +++ b/source/funkin/scripting/Script.hx @@ -17,7 +17,7 @@ class Script extends FlxBasic implements IFlxDestroyable { public static var staticVariables:Map = []; - public static function getDefaultVariables():Map { + public static function getDefaultVariables(?script:Script):Map { return [ // Haxe related stuff "Std" => Std, @@ -78,11 +78,13 @@ class Script extends FlxBasic implements IFlxDestroyable { "CustomShader" => funkin.shaders.CustomShader, "FunkinText" => funkin.ui.FunkinText, "Alphabet" => funkin.ui.Alphabet, + "CoolUtil" => funkin.utils.CoolUtil, "IniUtil" => funkin.utils.IniUtil, "XMLUtil" => funkin.utils.XMLUtil, "ZipUtil" => funkin.utils.ZipUtil, "MarkdownUtil" => funkin.utils.MarkdownUtil, + "EngineUtil" => funkin.utils.EngineUtil, ]; } public static function getDefaultPreprocessors():Map { @@ -157,7 +159,7 @@ class Script extends FlxBasic implements IFlxDestroyable { fileName = Path.withoutDirectory(path); this.path = path; onCreate(path); - for(k=>e in getDefaultVariables()) { + for(k=>e in getDefaultVariables(this)) { set(k, e); } } diff --git a/source/funkin/utils/EngineUtil.hx b/source/funkin/utils/EngineUtil.hx new file mode 100644 index 00000000..536357cb --- /dev/null +++ b/source/funkin/utils/EngineUtil.hx @@ -0,0 +1,15 @@ +package funkin.utils; + +import funkin.scripting.Script; +import funkin.scripting.MultiThreadedScript; + +class EngineUtil { + /** + * Starts a new multithreaded script. + * This script will share all the variables with the current one, which means already existing callbacks will be replaced by new ones on conflict. + * @param path + */ + public static function startMultithreadedScript(path:String) { + return new MultiThreadedScript(path, Script.curScript); + } +} \ No newline at end of file