implementing custom GtkTreeModels for language bindings



All,

Language bindings want to be able to implement the GtkTreeModel
interface. Unfortunately this is rather hard without causing a space
leak.

The issue is that to implement a the GtkTreeModel interface you must
fill in GtkTreeIter structures. These are typically stack allocated and
do not need to be explicitly freed. As a consequence it is not possible
to track resources that are referenced by GtkTreeIters.

This is mentioned in the pygtk documentation:

http://www.pygtk.org/pygtk2tutorial/sec-GenericTreeModel.html#sec-GenericTreeModelMemoryManagement

They allow arbitrary python values to be used as the TreeModel iters and
so store a PyObject * in the iter's user_data field.

They have a property "leak-references" which is used to switch between
two unappealing behaviours: either add a reference to the PyObjects (so
that at least they will remain valid but they will never be freed) or
add no reference in which case the user must guarantee that the python
values referenced always remain valid.

(Side note: In a language with garbage collection the problem is even
worse since pointers to heap objects are not stable. The GC may move
things about. In most language with GC it is possible to allocate
'stable pointers' which can be passed to foreign code but these need
freeing so we're back in the same situation.)

So I'm looking for a proper way of solving this problem. Suggestions
would be appreciated.

I have two ideas:

1. remember the references that get handed out in GtkTreeIters and
periodically invalidate all iters and free the references that they were
retaining.

>From the GtkTreeModel documentation:
http://developer.gnome.org/doc/API/2.0/gtk/GtkTreeModel.html#desc
        "Iterators are expected to always be valid for as long as the
        model is unchanged (and doesn't emit a signal)."

So it looks like emitting a signal (such as the row_changed signal)
means that users of the model must assume that all previous iters are
now invalid.

So the open questions for this approach are: does
gtk_tree_model_row_changed really invalidate all iterators? When can
gtk_tree_model_row_changed safely be called? (it would not be safe to
call it immediately after handing out an iter obviously).

2. keep a cache in C land of the tree created by calls to the
GtkTreeModel interface. This cache could be cleared whenever the model
changed (which corresponds to when iters can be invalidated normally).
This is a rather heavy weight solution since it duplicates the data
which of course is one of the reasons for implementing a custom model in
the first place. It basically corresponds to the first idea above but
with an unbounded cache of iters.

Any advice or suggestions would be much appreciated.

Duncan
(Gtk2Hs developer, http://haskell.org/gtk2hs/)




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