[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Lunar, C++, and premature object destruction
- From: Sam Roberts <vieuxtech@...>
- Date: Mon, 6 Jul 2009 11:50:32 -0700
On Mon, Jul 6, 2009 at 10:06 AM, Watusimoto<firstname.lastname@example.org> wrote:
> Thanks for your response. I may have found a solution just last night.
> You are right that with Luna, the C++ code is unaware of any references
> that Lua has to an object, so when C++ is done with it, it gets deleted,
> creating the problem I reported. My solution was to rearchitect my
> Ship/LuaShip relationship, such that there is no longer a one-to-one
> relationship. When Lua wants a LuaShip, I create a new one, and let Lua
> control its lifespan. I used a reference-counting pointer on LuaShip to
> refer back to the Ship, so that if the Ship is killed and deleted, the
> LuaShip pointer to it is set to NULL, and I can detect and handle that
> situation when dealing with the LuaShip object. That let me remove the
> pointer from Ship to LuaShip that led to the problems in my previous design.
> The only drawback to this solution is that I end up creating a lot of
> LuaShip objects (the Lua script may ask for several such references each
> game cycle), whereas in my previous scheme, there was only one for each
> Ship. But it does work -- Lua can hold or delete the LuaShip as it
> likes, and C++ doesn't care; it will just create another when it needs one.
One pattern for avoiding overcreation of userdata is to ensure you
never have more than 1 userdata (luaship)
for each C++ object (c++ship).
When creating a luaship, store it in a global weak table, indexed by
lightuserdata of the c++ship's pointer value.
Before creating a luaship for a c++ship, look up the pointer value in
the global table, and return the preexisting luaship if possible, only
creating a new luaship if necessary.
In the c++ship's delete, you can then look up any possibly existing
luaship that might have a reference to it, and both zero the pointer
in the userdata, as you are now, and also delete the pointer->luaship
mapping from the global weak table.
Lots of variations on this are possible, but they key is using weak
tables with lightuserdata as keys to maintain a mapping from the C++
world to the lua world.