I'm making project using C API and recently I needed access to system keyboard which unfortunately is available only in Lua.
I successfully initialized Lua runtime but I have problem with MenuItems.
I tried to narrow down the issue and prepared minimal example when it occurs.
Looks like if I add menu item using C API, e.g.:
Unfortunately this workaround doesn't work... at least when you try to call any other function inside Menu Item callback
e.g. when I change Test function to:
int GetInt()
{
return 42;
}
void Test(void* data)
{
int test= GetInt();
}
Then it crashes with:
Update error: failed expression: ((n) < (L->top - L->ci->func)) && "not enough elements in the stack" at C:\GitLab-Runner\ci-builds\HeHsk-Bm\0\playdate\PlayDate\Core\minilua\ldo.c:545
stack traceback:
[C]: in ?
Unfortunately original problem wasn't fixed. On 1.13.1 SDK it still occurs, if you add MenuItem via C and project is also using Lua runtime then it crashes with the same error.
This update fixed workaround I came with tho. I mean adding MenuItem from within Lua with C function passed as argument works.
Oh, sorry for misleading reply. Looks like on simple example it fixed the problem, but on my real "complex" project it didn't. I digged a bit more and looks like issue with Lua stack still persists.
Interesting part is that crash doesn't occur when I make call to pdAPI (tested on pdAPI->system->logToConsole(...)). If I don't then it crashes
Example code (main.c):
int GetInt()
{
return 32;
}
void Test(void* data)
{
int a = GetInt();
//pdAPI->system->logToConsole("%d", a); => if I uncomment this line then it doesn't crash!
}
void AddTestMenu()
{
pdAPI->lua->pushString("Test");
pdAPI->lua->pushFunction(Test);
const char* err;
if (!pdAPI->lua->callFunction("custom.addMenuItem", 2, &err))
{
pdAPI->system->logToConsole(err);
}
}
(main.lua):
function custom.addMenuItem(name, f)
local menu = playdate.getSystemMenu()
local menuItem, error = menu:addMenuItem(name, f)
end
aha! Found it. The problem is the menu callback should be a lua_CFunction, which returns an int telling Lua how many items it pushed on the stack. But Test() has a void return (and assumes the caller knows this) so it doesn't bother clearing out the return value register which is still 32 from the GetInt() call. Lua thinks you're saying you put 32 items on the stack so it's complaining that it can't find them. When you add the logToConsole call it apparently does clear that value, so no error. If you change Test() to return 0 everything should be fine.
Back to the attempt to call a nil value error: that's our bug. Our code assumes that if there's a Lua environment active then all menu callbacks are Lua functions. It looks for a Lua function for those menu items set with the C API and comes up with nil. We'll get that fix as soon as we can. Well done finding a workaround on this one!
Thanks for the reminder! I finally got a chance to take a look at this, submitted a fix for the next release--hopefully we'll be able to get that it. Sorry it took a while!