[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [ Userdata ] __index aware of original lookup value
- From: Sean Conner <sean@...>
- Date: Wed, 17 Feb 2016 02:17:41 -0500
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