[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: linking tables to C++ objects?
- From: Sam Roberts <sroberts@...>
- Date: Mon, 26 Feb 2007 13:56:18 -0800
On Mon, Feb 26, 2007 at 01:08:40PM -0800, Graham Wakefield wrote:
> Ah, now I read Rici's note.
>
> So in pseudocode again:
>
> // creation (synchronized) of table, userdata & c++ instance:
>
> ptr = [C++ instance]
> udata = userdata[ptr] // boxed pointer
> table = lua_newtable
> setfenv(udata, table)
> REGISTRY[weakvaluedtable][ptr] = udata
You can't literally use a ptr, you must use a lightuserdata as the key.
> REGISTRY[weakvaluedtable][table] = ptr
^-- probably unnecessary, see below
> // from C++ ptr to table:
>
> getfenv(REGISTRY[weakvaluedtable][ptr])
>
> // from table to C++ ptr:
>
> REGISTRY[weakvaluedtable][table]
Why would you would you want to map the table to the ptr?
lua code will have only a udata, and will pass a udata to C code, your C
code will call lua_touserdata() to get the ptr. No table required.
> // garbage collection:
>
> udata.__gc { // remove ptr & table entries from REGISTRY
> [weakvaluedtable]) }
No, the only thing you need to do in your __gc is free any non-lua
resources.
This could be as easy delete on the C++ object boxed in the udata.
__gc isn't called until there are no longer ANY references to the udata,
INCLUDING the weak-valued table. Note that this allows your C code an
easy way to determine if lua has a udata that boxes some ptr -> look up
REGISTRY[weakvaluedtable][lightuserdata(ptr)], if its nil, the udata
never existed, or has been GCed.
> Surely there is a more efficient way to do this!?
Don't create table entries you don't need.
You need to go from ptr -> lightuserdata(ptr) -> udata, thats what the
table is for.
You want the udata to be garbage collected, thats why the table has weak
values, and you implement the __gc metamethod.
You need to go from udata -> ptr, thats what lua_touserdata() is for.
Optional: if you need to go from udata -> table, maybe to store some
number of lua values with your udata, thats what lua_getfenv() is for.
Sam