Files
FNF-i486-Engine/source/psychlua/ReflectionFunctions.hx
Altertoriel 6ca6e3f284 Lua Improvements (#468)
* Lua Improvments

* fix

* fix 2

* fix 3

* fix 4

* fix 5

* fix 6

* Fix 7, please action dont fail

* done

* done 2

* done 3

* final

* last fix

* please last fix final

* add `curSection` on lua

* ready for pr

* oops

* oop2

* Lua Improvements 2

* Update Project.xml

* fixed `lastCalledScript`

* Attempt Fix 2

* Attempt fix 3

* shit

* done i think

* fuck

* fuck 2
2024-08-01 01:53:54 -04:00

232 lines
8.4 KiB
Haxe

package psychlua;
import Type.ValueType;
import haxe.Constraints;
//
// Functions that use a high amount of Reflections, which are somewhat CPU intensive
// These functions are held together by duct tape
//
using StringTools;
class ReflectionFunctions
{
static final instanceStr:Dynamic = "##PSYCHLUA_STRINGTOOBJ";
public static function implement(funk:FunkinLua)
{
var lua:State = funk.lua;
Lua_helper.add_callback(lua, "getProperty", function(variable:String, ?allowMaps:Bool = false) {
var split:Array<String> = variable.split('.');
if(split.length > 1)
return LuaUtils.getVarInArray(LuaUtils.getPropertyLoop(split, true, allowMaps), split[split.length-1], allowMaps);
return LuaUtils.getVarInArray(LuaUtils.getTargetInstance(), variable, allowMaps);
});
Lua_helper.add_callback(lua, "setProperty", function(variable:String, value:Dynamic, ?allowMaps:Bool = false) {
var split:Array<String> = variable.split('.');
if(split.length > 1) {
return LuaUtils.setVarInArray(LuaUtils.getPropertyLoop(split, true, allowMaps), split[split.length-1], value, allowMaps);
}
return LuaUtils.setVarInArray(LuaUtils.getTargetInstance(), variable, value, allowMaps);
});
Lua_helper.add_callback(lua, "getPropertyFromClass", function(classVar:String, variable:String, ?allowMaps:Bool = false) {
var myClass:Dynamic = Type.resolveClass(classVar);
if(myClass == null)
{
FunkinLua.luaTrace('getPropertyFromClass: Class $classVar not found', false, false, FlxColor.RED);
return null;
}
var split:Array<String> = variable.split('.');
if(split.length > 1) {
var obj:Dynamic = LuaUtils.getVarInArray(myClass, split[0], allowMaps);
for (i in 1...split.length-1)
obj = LuaUtils.getVarInArray(obj, split[i], allowMaps);
return LuaUtils.getVarInArray(obj, split[split.length-1], allowMaps);
}
return LuaUtils.getVarInArray(myClass, variable, allowMaps);
});
Lua_helper.add_callback(lua, "setPropertyFromClass", function(classVar:String, variable:String, value:Dynamic, ?allowMaps:Bool = false) {
var myClass:Dynamic = Type.resolveClass(classVar);
if(myClass == null)
{
FunkinLua.luaTrace('setPropertyFromClass: Class $classVar not found', false, false, FlxColor.RED);
return null;
}
var split:Array<String> = variable.split('.');
if(split.length > 1) {
var obj:Dynamic = LuaUtils.getVarInArray(myClass, split[0], allowMaps);
for (i in 1...split.length-1)
obj = LuaUtils.getVarInArray(obj, split[i], allowMaps);
LuaUtils.setVarInArray(obj, split[split.length-1], value, allowMaps);
return value;
}
LuaUtils.setVarInArray(myClass, variable, value, allowMaps);
return value;
});
Lua_helper.add_callback(lua, "getPropertyFromGroup", function(obj:String, index:Int, variable:Dynamic, ?allowMaps:Bool = false) {
var split:Array<String> = obj.split('.');
var realObject:Dynamic = null;
if(split.length > 1)
realObject = LuaUtils.getPropertyLoop(split, false, allowMaps);
else
realObject = Reflect.getProperty(LuaUtils.getTargetInstance(), obj);
if(Std.isOfType(realObject, FlxTypedGroup))
{
var result:Dynamic = LuaUtils.getGroupStuff(realObject.members[index], variable, allowMaps);
return result;
}
var leArray:Dynamic = realObject[index];
if(leArray != null) {
var result:Dynamic = null;
if(Type.typeof(variable) == ValueType.TInt)
result = leArray[variable];
else
result = LuaUtils.getGroupStuff(leArray, variable, allowMaps);
return result;
}
FunkinLua.luaTrace("getPropertyFromGroup: Object #" + index + " from group: " + obj + " doesn't exist!", false, false, FlxColor.RED);
return null;
});
Lua_helper.add_callback(lua, "setPropertyFromGroup", function(obj:String, index:Int, variable:Dynamic, value:Dynamic, ?allowMaps:Bool = false) {
var split:Array<String> = obj.split('.');
var realObject:Dynamic = null;
if(split.length > 1)
realObject = LuaUtils.getPropertyLoop(split, false, allowMaps);
else
realObject = Reflect.getProperty(LuaUtils.getTargetInstance(), obj);
if(Std.isOfType(realObject, FlxTypedGroup)) {
LuaUtils.setGroupStuff(realObject.members[index], variable, value, allowMaps);
return value;
}
var leArray:Dynamic = realObject[index];
if(leArray != null) {
if(Type.typeof(variable) == ValueType.TInt) {
leArray[variable] = value;
return value;
}
LuaUtils.setGroupStuff(leArray, variable, value, allowMaps);
}
return value;
});
Lua_helper.add_callback(lua, "removeFromGroup", function(obj:String, index:Int, dontDestroy:Bool = false) {
var groupOrArray:Dynamic = Reflect.getProperty(LuaUtils.getTargetInstance(), obj);
if(Std.isOfType(groupOrArray, FlxTypedGroup)) {
var sex = groupOrArray.members[index];
if(!dontDestroy)
sex.kill();
groupOrArray.remove(sex, true);
if(!dontDestroy)
sex.destroy();
return;
}
groupOrArray.remove(groupOrArray[index]);
});
Lua_helper.add_callback(lua, "callMethod", function(funcToRun:String, ?args:Array<Dynamic> = null) {
return callMethodFromObject(PlayState.instance, funcToRun, parseInstances(args));
});
Lua_helper.add_callback(lua, "callMethodFromClass", function(className:String, funcToRun:String, ?args:Array<Dynamic> = null) {
return callMethodFromObject(Type.resolveClass(className), funcToRun, parseInstances(args));
});
Lua_helper.add_callback(lua, "createInstance", function(variableToSave:String, className:String, ?args:Array<Dynamic> = null) {
variableToSave = variableToSave.trim().replace('.', '');
if(!PlayState.instance.variables.exists(variableToSave))
{
if(args == null) args = [];
var myType:Dynamic = Type.resolveClass(className);
if(myType == null)
{
FunkinLua.luaTrace('createInstance: Class $className not found.', false, false, FlxColor.RED);
return false;
}
var obj:Dynamic = Type.createInstance(myType, args);
if(obj != null)
PlayState.instance.variables.set(variableToSave, obj);
else
FunkinLua.luaTrace('createInstance: Failed to create $variableToSave, arguments are possibly wrong.', false, false, FlxColor.RED);
return (obj != null);
}
else FunkinLua.luaTrace('createInstance: Variable $variableToSave is already being used and cannot be replaced!', false, false, FlxColor.RED);
return false;
});
Lua_helper.add_callback(lua, "addInstance", function(objectName:String, ?inFront:Bool = false) {
if(PlayState.instance.variables.exists(objectName))
{
var obj:Dynamic = PlayState.instance.variables.get(objectName);
if (inFront)
LuaUtils.getTargetInstance().add(obj);
else
{
if(!PlayState.instance.isDead)
PlayState.instance.insert(PlayState.instance.members.indexOf(LuaUtils.getLowestCharacterGroup()), obj);
else
GameOverSubstate.instance.insert(GameOverSubstate.instance.members.indexOf(GameOverSubstate.instance.boyfriend), obj);
}
}
else FunkinLua.luaTrace('addInstance: Can\'t add what doesn\'t exist~ ($objectName)', false, false, FlxColor.RED);
});
Lua_helper.add_callback(lua, "instanceArg", function(instanceName:String, ?className:String = null) {
var retStr:String ='$instanceStr::$instanceName';
if(className != null) retStr += '::$className';
return retStr;
});
}
static function parseInstances(args:Array<Dynamic>)
{
if (args == null) return [];
for (i in 0...args.length)
{
var myArg:String = cast args[i];
if(myArg != null && myArg.length > instanceStr.length)
{
var index:Int = myArg.indexOf('::');
if(index > -1)
{
myArg = myArg.substring(index+2);
var lastIndex:Int = myArg.lastIndexOf('::');
var split:Array<String> = lastIndex > -1 ? myArg.substring(0, lastIndex).split('.') : myArg.split('.');
args[i] = (lastIndex > -1) ? Type.resolveClass(myArg.substring(lastIndex+2)) : PlayState.instance;
for (j in 0...split.length)
{
args[i] = LuaUtils.getVarInArray(args[i], split[j].trim());
}
}
}
}
return args;
}
static function callMethodFromObject(classObj:Dynamic, funcStr:String, args:Array<Dynamic> = null)
{
if(args == null) args = [];
var split:Array<String> = funcStr.split('.');
var funcToRun:Function = null;
var obj:Dynamic = classObj;
if(obj == null)
{
return null;
}
for (i in 0...split.length)
{
obj = LuaUtils.getVarInArray(obj, split[i].trim());
}
funcToRun = cast obj;
return funcToRun != null ? Reflect.callMethod(obj, funcToRun, args) : null;
}
}