[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: C-objects with __gc *and* __index?
- From: Uli Kusterer <witness.of.teachtext@...>
- Date: Sun, 7 Aug 2005 10:46:19 +0200
On Aug 7, 2005, at 9:07:28, Rici Lake wrote:
On 6-Aug-05, at 8:23 PM, Uli Kusterer wrote:
for i=100,1,-1 do
aRoom = Room.new()
print( tostring( aRoom ) )
aRoom = nil
Any particular reason you didn't choose to write:
for i = 100, 1, -1 do
local aRoom = Room.new()
-- or even
for i = 1, 100 do print(tostring(Room.new())) end
First and foremost, I originally just tried the part inside the
loop. When that didn't call the destructor, I thought maybe there's a
threshold for the GC how many objects have to be there to be
considered worth collecting, so I put it a loop around it. I also
wanted to have some room for trying out some member functions later.
I didn't use the second because I simply didn't consider it readable
Leaving that aside, Room.new() must contain the following:
RoomData *self = lua_pushuserdata(L, sizeof(RoomData));
Thanks, this is exactly what I'm doing in UKAdventureNewRoom(), the
difference being I'm using UKRoom* instead of UserData.
If you don't have this code, or something that looks like it,
that's why it's not working. If you're using a lightuserdata rather
than a pushuserdata, that is why it's not working (light user data
don't have metatable).
I'm using full metadata.
If none of the above is the reason, try checking the return values
from luaL_getmetatable and lua_setmetatable, and perhaps you'll get
Since you mention c++ constructors, there are two common ways of
dealing with the RoomData object.
The "simplest" (or at least most common) is to simply use a pointer
to the actual object; the statement after self = lua_pushuserdata
(...) would be *self = new Room; and RoomData would either be
typedef'd or replace with Room*, depending on your style preferences.
Yes, that's what I'm trying to do.
The more elegant way, which works as long as you're ok with letting
Lua manage your memory for you, is to use "placement new" syntax,
in which case the self = statement would look something like this:
Room self = new(lua_pushuserdata(L, sizeof(Room)) Room(...);
One of the nice things about placement-new is that the __gc method
will typically simply be an explicit call to the class destructor;
furthermore, it can be omitted completely under a specific but not
uncommon case, where no member variable of the class needs to be
destructed. The placement expression can be supplied by a template
function if you're careful; I think there is an example on the Lua
That's the first time I hear of this approach. I simply did what
the docs (the Programming with Lua book) suggested, assuming that
this was the recommended technique, and the one most tested and thus
most likely to work without much work. I'll look into this some more.
-- M. Uli Kusterer