Passing non-Sprite/Bitmap args from Lua to C

Hi! I'm trying to create a custom audio source in C using playdate->sound->channel->addCallbackSource. I want to expose a class for controlling the sound source to Lua so that I can do something like:

chan = playdate.sound.channel.new()
gen = generator.new() -- C class exposed to Lua via playdate->lua->registerClass
src = gen:add(chan) 
-- src is now a playdate.sound.source instance

I'm having trouble getting the SoundChannel instance in C using playdate->lua->getArgObject.

If I use playdate->lua->getArgType, I can see that the type of the second argument is playdate.sound.channel:

Generator *gen = pd->lua->getArgObject(1, "generator", NULL); 
// works as expected. gen is non-NULL

const char *outClass;
enum LuaType type = pd->lua->getArgType(2, &outClass);
// outClass is "playdate.sound.channel"
// type is kTypeObject (8)

However, if I try to get a SoundChannel pointer using the playdate.sound.channel as the class type, I get a NULL pointer:

SoundChannel *channel = pd->lua->getArgObject(2, "playdate.sound.channel", NULL);
// channel = NULL

Am I doing something wrong? Does the Playdate C API support this usage pattern?

Thanks!

ohhhh, yep. I knew that would come up eventually. :frowning: snd.channel.new() creates a plain userdata but the C API pushObject() and getArgObject() use another wrapper (LuaUDObject) around the C objects. It's a lucky coincidence that your SoundChannel* channel there is NULL instead of a garbage value. I'll file an issue to change the Lua playdate.sound.channel object to use those wrappers instead of normal userdata, and see where else we should be doing that. Pretty much anywhere there's a type exposed in the C API..

1 Like

I've got an MR in to fix this, all C types will be accessible with getArgObject(). It's a pretty big change under the hood but something I've been meaning to get to for a long time. Thanks for the motivation. :slight_smile:

1 Like