lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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