Skip to content

Commit 2fd6090

Browse files
fuck
1 parent 0ea3eed commit 2fd6090

2 files changed

Lines changed: 110 additions & 10 deletions

File tree

buildnumber.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2107
1+
2125

source/funkin/scripting/LuaScript.hx

Lines changed: 109 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import llua.Lua;
55
import llua.LuaL;
66
import llua.State;
77
import llua.Convert;
8+
import llua.Macro.*;
9+
import haxe.DynamicAccess;
810

911
import openfl.utils.Assets;
1012

@@ -31,6 +33,7 @@ class LuaScript extends Script {
3133

3234
luaCallbacks["__onPointerIndex"] = onPointerIndex;
3335
luaCallbacks["__onPointerNewIndex"] = onPointerNewIndex;
36+
luaCallbacks["__onPointerCall"] = onPointerCall;
3437
luaCallbacks["__gc"] = onGarbageCollection;
3538

3639
state.newmetatable("__funkinMetaTable");
@@ -42,10 +45,17 @@ class LuaScript extends Script {
4245
state.pushstring('__newindex');
4346
state.pushcfunction(cpp.Callable.fromStaticFunction(__newindex));
4447
state.settable(-3);
48+
49+
state.pushstring('__call');
50+
state.pushcfunction(cpp.Callable.fromStaticFunction(__call));
51+
state.settable(-3);
52+
53+
state.setglobal("__funkinMetaTable");
4554
}
4655

4756
public override function onLoad() {
48-
state.dostring(Assets.getText(path));
57+
if (state.dostring(Assets.getText(path)) != 0)
58+
this.error('${state.tostring(-1)}');
4959
}
5060

5161
public static var callbackReturnVariables = [];
@@ -65,7 +75,9 @@ class LuaScript extends Script {
6575
return null;
6676
}
6777

68-
return fromLua(state.gettop());
78+
var v = fromLua(state.gettop());
79+
state.settop(0);
80+
return v;
6981
}
7082

7183
public override function set(variable:String, value:Dynamic) {
@@ -95,13 +107,42 @@ class LuaScript extends Script {
95107
}
96108

97109
public function fromLua(stackPos:Int):Dynamic {
98-
var v:Dynamic = state.fromLua(stackPos);
99-
if (v is Dynamic && Reflect.hasField(v, "__stack_id")) {
110+
var ret:Any = null;
111+
112+
switch(state.type(stackPos)) {
113+
case Lua.LUA_TNIL:
114+
ret = null;
115+
case Lua.LUA_TBOOLEAN:
116+
ret = state.toboolean(stackPos);
117+
case Lua.LUA_TNUMBER:
118+
ret = state.tonumber(stackPos);
119+
case Lua.LUA_TSTRING:
120+
ret = state.tostring(stackPos);
121+
case Lua.LUA_TTABLE:
122+
ret = toHaxeObj(stackPos);
123+
case Lua.LUA_TFUNCTION:
124+
null; // no support for functions yet
125+
// case Lua.LUA_TUSERDATA:
126+
// ret = LuaL.ref(l, Lua.LUA_REGISTRYINDEX);
127+
// trace("userdata\n");
128+
// case Lua.LUA_TLIGHTUSERDATA:
129+
// ret = LuaL.ref(l, Lua.LUA_REGISTRYINDEX);
130+
// trace("lightuserdata\n");
131+
// case Lua.LUA_TTHREAD:
132+
// ret = null;
133+
// trace("thread\n");
134+
case idk:
135+
ret = null;
136+
trace("return value not supported\n"+Std.string(idk)+" - "+stackPos);
137+
}
138+
139+
140+
if (ret is Dynamic && Reflect.hasField(ret, "__stack_id")) {
100141
// is a "pointer"! convert it back.
101-
var pos:Int = Reflect.field(v, "__stack_id");
142+
var pos:Int = Reflect.field(ret, "__stack_id");
102143
return stack[pos];
103144
}
104-
return v;
145+
return ret;
105146
}
106147
public function pushArg(val:Dynamic) {
107148
switch (Type.typeof(val)) {
@@ -116,7 +157,15 @@ class LuaScript extends Script {
116157
case Type.ValueType.TClass(String):
117158
state.pushstring(cast(val, String));
118159
case Type.ValueType.TClass(Array):
119-
state.arrayToLua(val);
160+
var arr:Array<Any> = cast val;
161+
var size:Int = arr.length;
162+
state.createtable(size, 0);
163+
164+
for (i in 0...size) {
165+
state.pushnumber(i + 1);
166+
pushArg(arr[i]);
167+
state.settable(-3);
168+
}
120169
case Type.ValueType.TObject:
121170
@:privateAccess
122171
state.objectToLua(val); // {}
@@ -142,6 +191,9 @@ class LuaScript extends Script {
142191
public static function __newindex(state:StatePointer):Int {
143192
return callback_handler(cast cpp.Pointer.fromRaw(state).ref, "__onPointerNewIndex");
144193
}
194+
public static function __call(state:StatePointer):Int {
195+
return callback_handler(cast cpp.Pointer.fromRaw(state).ref, "__onPointerCall");
196+
}
145197
public static function __gc(state:StatePointer):Int {
146198
// callbackPreventAutoConvert = true;
147199
var v = callback_handler(cast cpp.Pointer.fromRaw(state).ref, "__gc");
@@ -155,9 +207,20 @@ class LuaScript extends Script {
155207
return null;
156208
}
157209

210+
public function onPointerCall(obj:Dynamic, ...args:Any) {
211+
trace(obj);
212+
trace(args);
213+
if (obj != null && Reflect.isFunction(obj))
214+
return Reflect.callMethod(null, obj, args.toArray());
215+
return null;
216+
}
217+
158218
public function onPointerNewIndex(obj:Dynamic, key:String, val:Dynamic) {
219+
if (key == "__gc") return null;
220+
159221
if (obj != null)
160222
Reflect.setProperty(obj, key, val);
223+
return null;
161224
}
162225

163226
public function onGarbageCollection(obj:Dynamic) {
@@ -169,7 +232,7 @@ class LuaScript extends Script {
169232
}
170233

171234
private static var callbackPreventAutoConvert:Bool = false;
172-
public static inline function callback_handler(l:State, fname:String):Int {
235+
public static function callback_handler(l:State, fname:String):Int {
173236

174237
if (!(Script.curScript is LuaScript))
175238
return 0;
@@ -182,7 +245,7 @@ class LuaScript extends Script {
182245
return 0;
183246

184247
var nparams:Int = Lua.gettop(l);
185-
var args:Array<Dynamic> = callbackPreventAutoConvert ? [for(i in 0...nparams) l.fromLua(i + 1)] : [for(i in 0...nparams) curLua.fromLua(i + 1)];
248+
var args:Array<Dynamic> = callbackPreventAutoConvert ? [for(i in 0...nparams) l.fromLua(-nparams + i)] : [for(i in 0...nparams) curLua.fromLua(-nparams + i)];
186249

187250
var ret:Dynamic = null;
188251

@@ -203,6 +266,43 @@ class LuaScript extends Script {
203266
return callbackReturnVariables.length;
204267

205268
}
269+
270+
public function toHaxeObj(i:Int):Any {
271+
var count = 0;
272+
var array = true;
273+
274+
loopTable(state, i, {
275+
if(array) {
276+
if(Lua.type(state, -2) != Lua.LUA_TNUMBER) array = false;
277+
else {
278+
var index = Lua.tonumber(state, -2);
279+
if(index < 0 || Std.int(index) != index) array = false;
280+
}
281+
}
282+
count++;
283+
});
284+
285+
return
286+
if(count == 0) {
287+
{};
288+
} else if(array) {
289+
var v = [];
290+
loopTable(state, i, {
291+
var index = Std.int(Lua.tonumber(state, -2)) - 1;
292+
v[index] = fromLua(-1);
293+
});
294+
cast v;
295+
} else {
296+
var v:DynamicAccess<Any> = {};
297+
loopTable(state, i, {
298+
switch Lua.type(state, -2) {
299+
case t if(t == Lua.LUA_TSTRING): v.set(Lua.tostring(state, -2), fromLua(-1));
300+
case t if(t == Lua.LUA_TNUMBER):v.set(Std.string(Lua.tonumber(state, -2)), fromLua(-1));
301+
}
302+
});
303+
cast v;
304+
}
305+
}
206306
#end
207307
}
208308
#end

0 commit comments

Comments
 (0)