[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: storing a lua closure in a C object, then calling it from C?
- From: "lists@..." <lists@...>
- Date: Sun, 21 May 2006 16:34:48 -0700
Hi,
Thanks for the detailed reply!
On May 21, 2006, at 2:56 AM, Daniel Collins wrote:
In my C code I first create two lua tables: one for storing callback
functions and the other for storing the full userdata.
I thought I might have to something like this. I'm still not sure
about the difference between the registry and the environment, but
I'm new to Lua and will keep on reading the manual...
When the lua code calls a factory method to create a new widget my C
factory function ends up with 3 essential items - the C object that
represents the UI widget in the C API, the full userdata representing
the widget for lua, and on the stack there is a lua function that was
passed as a parameter to the factory method. I add the callback
function
to its table using the C object pointer (pushed as lightuserdata)
as the key
What calls do you use to grab the function and push it into the
table? lua_tothread() and lua_pushthread() ? I can't see any other
API functions to grab a Lua function from the stack, or place one on
the stack...
Or do you use lua_rawget() and lua_setfield() ?
Then when my C API triggers a UI event for one of the widgets, I get a
function call with a pointer to the C object. This then looks up the
function (or closure) and puts it on the stack. Second it looks up the
fulluserdata, puts it on the stack then does a lua_call (this is
already
running in protected mode so I don't need a pcall). This works really
well. Passing the fulluserdata as the first parameter means the
callback
is compatible with lua methods (eg: function m:callback()).
Nice!
This is also similar to your case since the actual widgets are
allocated
outside of lua. The fulluserdata just holds the C pointer. The fact
that
I am holding the fulluserdata in a lua table prevents any garbage
collection.
Since my UI system also has a C API for creating widgets, it also
has a
pathway for storing cfunctions in the callback table. In this case the
callback function receives the C pointer rather than the
fulluserdata as
the only parameter.
I could also have used a single table, keyed by the C pointer with
each
entry being another table holding the callback function and the
fulluserdata but I don't see how this would be any different for my
usage pattern. Perhaps if I was updating all the objects.
Or storing more than one callback function per object?
The fact that some of the registered functions have upvalues and
others
don't is all handled transparently since I am using lua tables and API
calls to handle all the data.
Very nice.
- DC