lua-users home
lua-l archive

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


On Thu, Apr 05, 2001 at 10:42:06AM -0700, anon wrote:
> basically i just want to be able to call it thats all. it doesn't have the
> to be the string value, just a value to i can pass so that lua_call will
> work..
> 
> how do i get the reference via tolua ? i dont see anything that looks
> like its getting a ref

First of all, it is great to see gllua being ported. I would like to
coordinate the GL canvas of tklua with your port of gllua, so please
get in touch with me when you feel that your port has reached an
appropriate level of functionality. Also feel free to take a look at
my partial gllua port. You can find the link at

http://www.cis.upenn.edu/~cvogler/lua/tklua.html

Now, to answer your question:

Getting the reference via tolua currently won't work without some
hackery of the generated *.c file. I suggest that you do it the way I
did it in tklua instead. This is how the idle function is written
there, for example. 

static int tkluaRegisterIdle (lua_State *tklua_S)
{
 TkLua *tklua = tklua_tkinfo(tklua_S);
 DEBUG_BEGINFUNCTION;
 
 if (tklua->idleLua)
 {
  lua_unref(tklua_S, tklua->idleLua);
  tklua->idleLua = LUA_NOREF;
 }
 if (lua_isnil(tklua_S, 1))
  Tk_CancelIdleCall(doLua,tklua_S);
 else
 {
  lua_pushvalue(tklua_S, 1);
  tklua->idleLua = lua_ref(tklua_S, 1);
  Tk_DoWhenIdle(doLua,tklua_S);
 }
 DEBUG_ENDFUNCTION(0);
 return 0;
}


and somewhere in the initialization function:

lua_register(tklua_S, "tkidle",tkluaRegisterIdle);

The crucial calls in the above function are

  lua_pushvalue(tklua_S, 1);
  tklua->idleLua = lua_ref(tklua_S, 1);

The first one pushes the lua callback function on the top of the
stack.  The second one creates a reference to it, so that it won't be
garbage-collected, and so that it can later be accessed via this
reference. This access is done in doLua, which dispatches the callback
to the appropriate lua function. It is quite simple:

static void doLua (ClientData state)
{
 lua_State *tklua_S = (lua_State *) state;
 TkLua *tklua = tklua_tkinfo(tklua_S);
 lua_getref(tklua_S, tklua->idleLua);
 lua_call(tklua_S, 0, 0);
 Tk_DoWhenIdle(doLua,tklua_S);
}

As you can (hopefully) see, you can get the lua function with
lua_getref(tklua->idleLua) here. This is the reference that previously
was stored there by tkluaRegisterIdle().


Now, another thing: How are you obtaining the lua state for the
callback functions? This was the most troublesome aspect of porting
tklua. I solved this problem by passing the state in the ClientData
field of the tk calls. How are you planning to solve this problem with
OpenGL callbacks? IIRC, these callbacks don't allow you to pass extra
data at all.

- Christian