lua-users home
lua-l archive

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


Lua list,

Say you have the following situation:

function DoIt()
        widgetContainer = WidgetContainer:new()
        local widget = Widget:new()

        widgetContainer:AddWidget(widget)
end

Now, imagine that WidgetContainer and Widget are both thin wrappers around 
C++ objects with the same names.  If I don't explicity create a "ref" to 
widget inside AddWidget()'s C++ code (using luaL_ref or similar), widget 
will be marked for garbage collection as soon as the function exits, which 
is obviously not what I want.  This much I understand, but there is one 
problem.

The problem exists when widgetContainer gets nil'd out.  At this point, my 
__gc metamethod calls the widgetContainer's destructor, which in turn 
calls a RemoveWidget function on every widget remaining in its collection. 
 As you'd expect, the RemoveWidget() function calls the equivalent "unref" 
on the ref previously created by AddWidget().  Then, I call 
collectgarbage() from lua.  As expected, the widgetContainer gets 
collected, but the widget does not.  I have to call collectgarbage() 
*again* to make the widget get collected.

This kind of makes sense in that the widget is being marked for collection 
during an *existing* collection, so the GC doesn't "know" about it until 
the second time around.

So, two questions arise:
1) Is there a better way to manage refs in C++ than the way I'm doing it?
2) Is there a way to do this so that everything gets collected in the same 
call to collectgarbage()?

Thanks a lot!

Brad...