[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: light userdata
- From: Mark Hamburg <mhamburg@...>
- Date: Sun, 25 Jul 2004 22:09:12 -0700
Another example would be proxying C/C++/Objective-C objects to Lua. The
proxy is going to be a full userdata. (I keep wanting to call them "heavy
userdatas".) Furthermore, we'd like to share proxies if one already exists.
Solution: Use a weak table mapping light userdatas to full userdata proxies.
Roughly (and from memory)...
pushObject (lua_State *L, Obj *obj )
{
lua_pushlightuserdata (L, &pushObject );
/* Registry mapping for weak table. Key is arbitrary. */
lua_rawget (L, LUA_REGISTRYINDEX);
if( lua_isnil (L, -1) ) {
lua_pop (L, 1);
lua_newtable (L);
lua_newtable (L);
lua_pushliteral (L, "__mode");
lua_pushliteral (L, "kv");
lua_rawset (L, -3);
lua_setmetatable (L,-2);
lua_pushlightuserdata (L, &pushObject);
lua_pushvalue (L, -2); /* the table */
lua_rawset (L, LUA_REGISTRYINDEX);
}
lua_pushlightuserdata (L, obj);
lua_rawget (L, -2);
if( lua_isnil( L, -1 ) ) {
Obj **proxy;
lua_pop (L, 1);
proxy = (Obj**) lua_newuserdata (L, sizeof(*proxy));
*proxy = obj;
/* setmetatable on proxy */
lua_pushlightuserdata (L, obj);
lua_pushvalue (L, -2);
lua_rawset (L, -4); /* weak table */
}
lua_remove (L, -2); /* weak table */
}
This may actually be illegal since it relies on turning a function pointer
into a void* but the point is that we want some unique address to use as a
light userdata key. If you don't worry about independent Lua universes, you
can gain some speed by using a Lua ref to find the weak table.
Mark
P.S. This is the sort of code where lua_lock gets really, really
expensive...
on 7/26/04 2:47 PM, Adrian Sietsma at adrian_groups@sietsma.com wrote:
> I find that lightuserdata is ideal for window handles (in the ms world).
>
> I have a routine that constructs a gui object (tree view) from a lua
> table. I then have a seperate lua table indexed by the window handle of
> each tree node, as a lightuserdata. This simplifies the c/lua interface
> - i can use the c handle to lookup the appropriate lua table object.
>
> --save a window handle
> lua_pushlightuserdata(L, hKey);
> lua_pushvalue(L,filt); // copy of filter table entry
> lua_settable(L, treeindex);
>
>
> --find data for a window handle
> lua_pushstring(L, "__treeitems");
> lua_gettable(L, LUA_GLOBALSINDEX);
> lua_pushlightuserdata(L, hKey);
> lua_gettable(L, -2);
>
> In this case, the handle (lightuserdata) is never accessed by lua
> scripts, and so its type is irrelevant. This is a useful way of binding
> lua objects to c++ without worrying about pointers and the gc.
>
> Adrian