lua-users home
lua-l archive

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


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