I don't find a mention of cache, so I'm probably mixing up with that.
However, we should compare gtkbuilder with not using gtkbuilder. If you create gtk objects in the init of eg PersonDialog, you would also not clone an existing Dialog, you would just repeat the construction of all the widgets. So the best would be to have a single glade faile for the Dialog (we have that actually), and this is parsed then created.

As gramps with parsing of a large xml tree every time with glade is already sufficiently fast, wathever timehit we have should be neglectable, and moreover, it is important to keep the code easy to read and understand.


2009/4/25 Benny Malengier <benny.malengier@gmail.com>
You find a discussion on the one big file in glade against many small files in gtkbuilder here: http://mail.gnome.org/archives/gtk-devel-list/2007-June/msg00312.html


2009/4/25 Gerald Britton <gerald.britton@gmail.com>

There are a couple of things we can do to make life easier.

1.  Although builder maintains a flat name space, it appears that it
only matters when you want to get a reference to a widget that is a
child of some toplevel AND a widget by the same name is also the child
of another toplevel.  This is often the case in gramps.glade.
However, I found that it was not hard to write a function that
searches for a child by name within a toplevel (or within any widget,
for that matter).  I implemented this and you can see it in the trunk
in ManagedWindow.  The function get_object does this.

This means that we are not _forced_ to break up gramps.glade for that
reason alone, although I believe that is a good idea from a
maintenance perspective.  However, I'm still concerned about how
builder reads and parses the file.  I will check with the builder devs
to see if it keeps any kind of cache as you mentioned.  If not, that
really forces our hand in my opinion (probably should have done it
long ago -- but breakin up is hard to do!)

2. You are right about the problem of maintaining a dictionary of all
the objects.  The basic problem is, there is no easy way that I have
found to clone an object and its children.  If there were, this would
be easy.  Just build the objects once from source (or by gtk calls)
then save them in the dictionary.  When asked for an object, create a
clone and pass a ref to it.  Without a cloning method this just can't
be done easily.  (it's not impossible, just really messy)

On Fri, Apr 24, 2009 at 11:06 AM, Benny Malengier
<benny.malengier@gmail.com> wrote:
> Gerald,
> I mentioned this at the beginning of the discussion. Gtkbuilder is optimized
> for seperate glade files which it parses ones.
> So we need to split up gramps.glade in different glade files for every
> dialog. So yes to your question 1.
> As for 2, I would not do that. Call gtkbuilder every time again. I recall it
> has some internal cache itself, so we cannot hope to do better. More
> importantly, we can have 5 person editor windows open at the same time. So
> these 5 creations of the person editor must be independant. On finish all
> memory must be released. So depending on how gtkbuilder works, something
> like
> self.__widget = GladeMgr.__dict[key]
> does not look good. We need self.__widget to be all new allocated memory,
> and on close of window we need to free that memory to avoid memory leaking.
> Benny
> 2009/4/20 <gerald.britton@gmail.com>
>> Devs,
>> I've been working on converting gramps from libglade to gtkbuilder. The
>> work has been frustrating in part because libglade allows duplicate widget
>> names as long as they are inside separate (top level) widgets whereas the
>> builder does not. For example, with libglade I can have:
>> <widget class="GtkDialog" id="source_editor">
>> ...
>> <widget class="GtkButton" id="cancel">
>> and
>> <widget class="GtkDialog" id="family_editor">
>> ...
>> <widget class="GtkButton" id="cancel">
>> but the builder doesn't like this -- at -- all. There are two reasons:
>> 1. you have to get an entire glade file at once (at least in Python. There
>> is actually a method in C to get an object from a file)
>> 2. the builder only has a flat namespace, whereas libglade (apparently)
>> has a hierarchical namespace
>> I'vbe been able to work around these limitations by renaming some widgets
>> and implementing a method to find a widget in an tree by the builder, but
>> I'm now looking at gramps.glade, with some 38 top-level widgets! I'm
>> thinking that there must be a better way.
>> While pondering this issue, I also realized that we are reading
>> gramps.glade multiple times -- basically once for every top-level widget we
>> want, since they are referenced in different modules. Over the course of a
>> typical gramps session, I would guess that this file is read scores of
>> times. Considering that glade.gramps is over 600k, reading and rereading it
>> is _not_ a good thing. Granted, the filesystem probably caches it, but why
>> waste the storage?
>> So, here's a proposal. I haven't implemented it yet. We need to discuss it
>> first.
>> 1. split up the glade files so that they are single-purpose. There may
>> still be multiple top-level widgets, as long as there is one purpose. e.g.
>> mergedata.glade serves:
>> Merge/_MergePerson.py
>> Merge/_MergeSource.py
>> Merge/_MergePlace.py
>> Merge/_MergePlace.py
>> Let's split them up into four glade files. Similarly with gramps.glade.
>> Make a bunch of smaller files instead.
>> 2. Create a glade manager module that has these responsibilities:
>> a) loads glade files on demand
>> a) maintains a dictionary, by file and widget id, of all glade objects
>> currently loaded
>> c) returns a reference to a widget when asked for it.
>> Something like this:
>> class GladeMgr(object):
>> __dict = {}
>> def __init__(self,widget, file=None, dir=const.GLADE_DIR):
>> if file is None or not isinstance(file,basestring):
>> raise ValueError, "I need a proper file name!"
>> key = ':'.join(dir,file,widget)
>> if key not in GladeMgr.__dict:
>> builder = gtk.builder
>> builder.add_from_file(os.path.join(dir,file))
>> widget_ = builder.get_object(widget)
>> Glade.Mgr.__dict[key] = self.__widget = \
>> builder.get_object(widget)
>> else:
>> self.__widget = GladeMgr.__dict[key]
>> def __get_widget(self):
>> return self.__widget
>> widget = property(__get_widget)
>> Which you could use like this:
>> import GladeMgr
>> mywidget = GladeMgr('my_widget', 'my.glade')
>> ...
>> mywidget.widget.show()
>> ...
>> etc.
>> Again, I haven't implemented this or even tested the above code (except to
>> see that it compiles!)
>> I'm looking for feedback here.
>> ------------------------------------------------------------------------------
>> Stay on top of everything new and different, both inside and
>> around Java (TM) technology - register by April 22, and save
>> $200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco.
>> 300 plus technical and hands-on sessions. Register today.
>> Use priority code J9JMT32. http://p.sf.net/sfu/p
>> _______________________________________________
>> Gramps-devel mailing list
>> Gramps-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/gramps-devel

Gerald Britton