This document describes the garbage collection mechanisms of hush.
It is our firm conviction hat garbage collection should be supported by the language environment, as the developers of Java have realized. In C++ this is unfortunately not the case. Nevertheless, the hush library is becoming increasingly strict in collecting garbage. It may clean up itself one day. Many classes do provide a register method that allows the user to declare which (component) objects must be deleted when cleaning up. In most cases you do not have to be very strict in cleaning up obsolete objects, except when resource management (such as occupying the audio device) is involved. A hush programmer should never, or only very rarely, delete an object explicitly. Rather, one must register each newly created object to a (handler) object that provides the most suitable scope. For example some objects live as long as a session, whereas for other objects the widget they belong to is a more suitable scope. See garbage(4) and handler(4).
Widgets that are created as child of an ancestor widget are automatically registered for eventual garbage collection. As a result, deleting a toplevel widget will result in the subsequent deletion of all its children. Note that this strategy mirrors the Tk destroy algorithm.
The root window will be automatically destroyed after quitting the program. This means that all direct and indirect children of the root window are automatically deleted.
The following widgets are all deleted automatically:
widget* root = tk->root(); // Get widget of root window frame* f1 = new frame(root, "f1"); button* b1 = new button(f1, "b1"); ... etc
The following widgets are all deleted by deleting top:
toplevel *top = new toplevel("t1"); frame* f2 = new frame(top, "f2"); button* b2 = new button(f2, "b2"); ... etc
The hush handler class and its descendants have a handler::_register function which can be used to register objects for deletion. Every object registered by a specific handler will be deleted by the destructor of the handler object. Since every widget is derived from handler, you can use the widget's _register member for objects which need to be destructed when the widget itself is destructed. The kit's _register can be used for objects which are needed during a complete hush application.
Handler will be deleted when kit is deleted:
handler* h = new myhandler; tk->bind("do-something",h); tk->_register(h);
Handler will be deleted when button is deleted:
button* b = new button(parent, "b"); handler h = new myhandler; b->_register(h);
After destruction of your session, all hush object should have been deleted. You can check this by calling the static session::statistics member function.
int main(int argc, char **argv) { app *a = new app(argc,argv); // create a session int result = a->run(); // run session delete a; // delete session session::statistics(); // print statistics return result; // return result of run }prints something like:
Statistics: created - deleted = ? session:: 2 - 2 = 0 kit:: 2 - 2 = 0 handler:: 24 - 24 = 0 event:: 1 - 1 = 0 widget:: 8 - 8 = 0 item:: 4 - 4 = 0 binding:: 4 - 4 = 0 string:: 0 - 0 = 0 iter<T>:: 0 - 0 = 0 list<T>:: 0 - 0 = 0 dictionary<T>:: 0 - 0 = 0 garbage<T>:: 0 - 0 = 0 sublistrep:: 0 - 0 = 0 baselist:: 0 - 0 = 0 cell:: 19 - 19 = 0