Closed FengZi-lv closed 1 year ago
Hi, I covered passing a table from Lua into Dart in the article I wrote about using LuaDardo a few months ago, hopefully that can be of some help to you.
@FengZi-lv It's easy!
int randomInt(LuaState ls) {
int? max = ls.checkInteger(1);
ls.getField(2, "hello");
// This is a debugging method that looks at the stack
ls.printStack();
var hello = ls.toStr(-1);
print(hello);
ls.pop(1);
ls.getField(2, "hello22");
var hello22 = ls.toStr(-1);
print(hello22);
ls.pop(1);
var random = Random();
var randVal = random.nextInt(max!);
ls.pushInteger(randVal);
return 1;
}
@arcticfox1919 thanks for the tip about getField()
! For some reason I hadn't noticed it before as when I wrote my article I just showed how to use the Lua "C API" getTable()
but I see you actually already have using getField
documented in the Readme too 👍🏻
Looking at your implementation of getTable
it looks much simpler than the example one in the Lua book?
PS. also in your code example it looks like: int? max = ls.checkInteger(1);
doesn't seem to be used for anything?
The problem has been solved, here is the workaround.
/// Pushes a Dart function onto the Lua stack.
/// @param name The name of the function in Lua.
/// @param func The Dart function to push.
/// @param args The arguments for the Dart function in the form of a map {"value_name":example_value}.
/// This is an example of a Map, the data in it will not be passed to lua, but the format of the Table passed in when the function is called should be consistent with the Map
LuaState pushFunction(String name, Function func, Map<String, dynamic> args) {
luaState.pushDartFunction((ls) {
// Convert the Dart function to a Lua function.
int counter = 1; // Counter for the arguments.
Map<String, dynamic> params = {}; // List of arguments.
var val; // Argument value.
args.forEach((key, value) {
// Iterate through the arguments.
debugPrint(value.runtimeType);
switch (value.runtimeType) {
// Get the argument value based on its type.
case String:
val = ls.checkString(counter);
break;
case int:
val = ls.checkInteger(counter);
break;
case double:
val = ls.checkNumber(counter);
break;
default:
val = {};
var val0;
value.forEach((k, v) {
debugPrint('k,v,counter $k,$v,$counter');
try {
val0 = ls.checkInteger(counter);
} catch (e) {
try {
val0 = ls.checkNumber(counter);
} catch (e) {
ls.getField(counter, k);
val0 = ls.checkString(-1);
}
}
val[k] = val0;
});
break;
}
params[key] = val; // Add the argument to the list.
counter++;
});
func(params); // Call the Dart function.
ls.pushInteger(12); // Push the return value onto the Lua stack.
Logger().i('Plugin `$name` called $args'); // Log the function call.
return 1; // Return the number of return values.
});
luaState.setGlobal(name); // Store the function in a global variable.
return luaState;
}
@maks
It seems simpler, only because here { ["hello"] = "World", ["hello22"] = "World132414" }
there is no variable name.
In addition, the int? max = ls.checkInteger(1);
here is retrieving the first parameter from the above function example: randomInt(10,{ ["hello"] = "World", ["hello22"] = "World132414" })
. The checkInteger
method attempts to get an integer from the first position of the stack, and it will throw an error if it doesn't exist.
How to pass Table when Lua calls Dart function, and get it in Dart?