package psychlua; #if HSCRIPT_ALLOWED import hscript.Parser; import hscript.Interp; import hscript.Expr; #end import haxe.Exception; // import objects.Character; /* * TODO: Decouple Lua from HScript and allow for more powerful HScript * TODO: Add a Script Manager to manage Lua/HScript? */ class HScript { public static var parser:Parser = new Parser(); public var interp:Interp; public var variables(get, never):Map; public var parentLua:FunkinLua; public function get_variables() { return interp.variables; } public static function initHaxeModule(parent:FunkinLua) { #if HSCRIPT_ALLOWED if (parent.hscript == null) { trace('initializing haxe interp for: ${parent.scriptName}'); parent.hscript = new HScript(parent); } #end } public function new(parent:FunkinLua) { #if HSCRIPT_ALLOWED interp = new Interp(); parentLua = parent; interp.variables.set('FlxG', flixel.FlxG); interp.variables.set('FlxSprite', flixel.FlxSprite); interp.variables.set('FlxCamera', flixel.FlxCamera); interp.variables.set('FlxTimer', flixel.util.FlxTimer); interp.variables.set('FlxTween', flixel.tweens.FlxTween); interp.variables.set('FlxEase', flixel.tweens.FlxEase); interp.variables.set('PlayState', PlayState); interp.variables.set('game', PlayState.instance); interp.variables.set('Paths', Paths); interp.variables.set('Conductor', Conductor); interp.variables.set('ClientPrefs', ClientPrefs); interp.variables.set('Character', Character); interp.variables.set('Alphabet', Alphabet); interp.variables.set('CustomSubstate', psychlua.CustomSubstate); #if (sys) interp.variables.set('FlxRuntimeShader', flixel.addons.display.FlxRuntimeShader); #end interp.variables.set('ShaderFilter', openfl.filters.ShaderFilter); interp.variables.set('StringTools', StringTools); interp.variables.set('setVar', function(name:String, value:Dynamic) { PlayState.instance.variables.set(name, value); }); interp.variables.set('getVar', function(name:String) { var result:Dynamic = null; if (PlayState.instance.variables.exists(name)) result = PlayState.instance.variables.get(name); return result; }); interp.variables.set('removeVar', function(name:String) { if (PlayState.instance.variables.exists(name)) { PlayState.instance.variables.remove(name); return true; } return false; }); interp.variables.set('debugPrint', function(text:String, ?color:FlxColor = null) { if (color == null) color = FlxColor.WHITE; LuaUtils.luaTrace(parentLua.lua, text, true, false, color); }); // For adding your own callbacks // not very tested but should work interp.variables.set('createGlobalCallback', function(name:String, func:Dynamic) { #if HSCRIPT_ALLOWED for (script in PlayState.instance.luaArray) if (script != null && script.lua != null && !script.closed) Lua_helper.add_callback(script.lua, name, func); #end FunkinLua.customFunctions.set(name, func); }); // tested interp.variables.set('createCallback', function(name:String, func:Dynamic, ?funk:FunkinLua = null) { if (funk == null) funk = parentLua; funk.addLocalCallback(name, func); }); interp.variables.set('addHaxeLibrary', function(libName:String, ?libPackage:String = '') { try { var str:String = ''; if (libPackage.length > 0) str = libPackage + '.'; interp.variables.set(libName, Type.resolveClass(str + libName)); } catch (e:Dynamic) { FunkinLua.lastCalledScript = parent; LuaUtils.luaTrace(parentLua.lua, parentLua.scriptName + ":" + parentLua.lastCalledFunction + " - " + e, false, false, FlxColor.RED); } }); interp.variables.set('parentLua', parentLua); #end } #if HSCRIPT_ALLOWED public function execute(codeToRun:String, ?funcToRun:String = null, ?funcArgs:Array):Dynamic { @:privateAccess parser.line = 1; parser.allowTypes = true; var expr:Expr = parser.parseString(codeToRun); try { var value:Dynamic = interp.execute(parser.parseString(codeToRun)); return (funcToRun != null) ? executeFunction(funcToRun, funcArgs) : value; } catch (e:Exception) { LuaUtils.luaTrace(parentLua.lua, parentLua.scriptName + ":" + parentLua.lastCalledFunction + " - " + e, false, false, FlxColor.RED); return null; } } public function executeFunction(funcToRun:String = null, funcArgs:Array) { if (funcToRun != null) { // trace('Executing $funcToRun'); if (interp.variables.exists(funcToRun)) { // trace('$funcToRun exists, executing...'); if (funcArgs == null) funcArgs = []; try { return Reflect.callMethod(null, interp.variables.get(funcToRun), funcArgs); } catch (e) LuaUtils.luaTrace(parentLua.lua, parentLua.scriptName + ":" + parentLua.lastCalledFunction + " - " + e, false, false, FlxColor.RED); } } return null; } #end public static function implement(funk:FunkinLua) { #if LUA_ALLOWED funk.addLocalCallback("runHaxeCode", function(codeToRun:String, ?varsToBring:Any = null, ?funcToRun:String = null, ?funcArgs:Array = null) { trace('runHaxeCode added'); var retVal:Dynamic = null; final types:Array = [Bool, Int, Float, String, Array]; #if HSCRIPT_ALLOWED initHaxeModule(funk); try { if (varsToBring != null) { for (key in Reflect.fields(varsToBring)) { // trace('Key $key: ' + Reflect.field(varsToBring, key)); funk.hscript.interp.variables.set(key, Reflect.field(varsToBring, key)); } } retVal = funk.hscript.execute(codeToRun, funcToRun, funcArgs); } catch (e:Dynamic) { LuaUtils.luaTrace(funk.lua, funk.scriptName + ":" + funk.lastCalledFunction + " - " + e, false, false, FlxColor.RED); } #else LuaUtils.luaTrace(funk.lua, "runHaxeCode: HScript isn't supported on this platform!", false, false, FlxColor.RED); #end if (retVal != null && !LuaUtils.isOfTypes(retVal, types)) retVal = null; return retVal; }); funk.addLocalCallback("runHaxeFunction", function(funcToRun:String, ?funcArgs:Array = null) { #if HSCRIPT_ALLOWED try { return funk.hscript.executeFunction(funcToRun, funcArgs); } catch (e:Exception) { LuaUtils.luaTrace(funk.lua, Std.string(e)); return null; } #else LuaUtils.luaTrace(funk.lua, "runHaxeFunction: HScript isn't supported on this platform!", false, false, FlxColor.RED); #end }); funk.addLocalCallback("addHaxeLibrary", function(libName:String, ?libPackage:String = '') { #if HSCRIPT_ALLOWED initHaxeModule(funk); try { var str:String = ''; if (libPackage.length > 0) str = libPackage + '.'; funk.hscript.variables.set(libName, Type.resolveClass(str + libName)); } catch (e:Dynamic) { LuaUtils.luaTrace(funk.lua, funk.scriptName + ":" + funk.lastCalledFunction + " - " + e, false, false, FlxColor.RED); } #else LuaUtils.luaTrace(funk.lua, "addHaxeLibrary: HScript isn't supported on this platform!", false, false, FlxColor.RED); #end }); #end } }