lua-users home
lua-l archive

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


Sam,
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.

This is an interesting idea, and will probably work well for my situation. I have been thinking of ways to do this on the C++ side, but hadn't considered using weak tables on the Lua side to fit it all together. I'm assuming that the overhead of asking Lua to look up a value in a table is much lower than that of creating a relatively lightweight object directly in C++ (then garbage collecting it later). Presumably the weak table would have weak keys only.

So if my current code were:

// C++, in Ship
LuaShip *Ship::getLuaShip() {
  return new LuaShip(this);
}

The new code might be:

LuaShip *Ship::getLuaShip() {
LuaShip *luaship = findShipInWeakTable(L, this); // Use this as "key" to find LuaShip in Lua table
  if(luaship) {
     return luaship;
  } else {
     luaship = new LuaShip(this);
storeShipInWeakTable(L, this, luaship ); // Store luaship in Lua table, using "this" as key
     return luaship;
  }
}

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.
Would I need to manually delete the pointer from the weak table, or would gc take care of that once the ship has been deleted? I suppose it wouldn't, as that's an analogous situation to the problem I'm trying to solve.
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

Thanks for the good advice.
Chris