[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: "Daniel Collins" <daniel.collins@...>
- Date: Sun, 21 May 2006 19:26:34 +0930
It is not quite the same situation but the UI system I have been
developing this last week does something similar.
In my C code I first create two lua tables: one for storing callback
functions and the other for storing the full userdata.
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 and the userdata to its table using the C object pointer
(pushed as lightuserdata) as the key in both cases.
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()).
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.
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.
- DC