lua-users home
lua-l archive

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


On Mon, Jul 6, 2009 at 10:06 AM, Watusimoto<watusimoto@bitfighter.org> wrote:
> Sean,
>
> 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.

Sam