lua-users home
lua-l archive

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


It was thus said that the Great JeanHeyd Meneide once stated:
>      I hope this message finds you well.
> 
>      I am developing a lua <-> C++ binding (like the several other that
> exist), and I've made significant headway into getting a very performant
> and easy to use wrapper. My final challenge in increasing the performance
> comes from trying to make basic "variable" get/sets on userdata made by C
> code work.
> 
>      The Question: Is there a way to get the original object that a lookup
> was performed on in a cascading series of `__index` queries? Right now, lua
> hands you the current object in the `__index` cascade that lookup failed on
> and the key name it is trying to find. This is all well and good and based
> on the specification, but my problem is that I want what the original
> lookup failed on (e.g. the userdata that started it all, in my case).
> 
> This tree might help explain what my dilemma is (pseudo code):
> 
> myuserdata -- userdata
> myuserdata.mt -- metatable
> myuserdata.mt.__index -- table
> myuserdata.mt.__index.mt -- second metatable
> mysuserdata.mt.__index.mt.__index -- function that performs variable lookup
> 
> When I do
> myuserdata.x -- cascades down to second function, but the provided "lookup
> failed" argument is userdata.mt.__index, the table, not myuserdata. How do
> I get to 'userdata' ?

  It sounds like you might want to use lua_setuservalue()/lua_getuservalue()
(available in Lua 5.2 or higher).  With this, you can associate an addtional
table with your userdata (while sharing a metatable with all instances of a
given userdata type).  Then your __index method (a function) can call
lua_getuservalue() to get a table just for that instance where you can fetch
values from.  Something like:

static int myfoo___index(lua_State *L)
{
  /*----------------------------------------
  ; Assuming that the value associated with the userdata is a Lua table.
  ; Then push the key being looked for onto the stack, and reference said
  ; table for said value.  Once it's on the stack, we can return.
  ;--------------------------*/

  lua_getuservalue(L,1);
  lua_pushvalue(L,2);
  lua_gettable(L,-2);
  return 1;
}

  -spc