three years ago Neil and I wrote the
Model API, to be included in Clutter. We tried encode in the design what we learned from the experience with
GtkTreeModel, and while it could be said that there are shortcomings (a base class instead of an interface, no bulk operations, some corner cases in the iterators API) I think we managed well enough not to repeat the same issues (boxed types, volatile iterators, and conflating a Tree and a List API into one) on top of those.
still, we made what I now think is the same design mistake all over again: we tried to provide a way to write MVC applications with Clutter, and we ended up collapsing the model with the controller — that is: we added a new data storage class that notifies you when something changed inside it1.
I now think it’s a mistake trying to conflate the data storage with the actual object notifying the views about changes: the controller should just be notified by the model and notify the views
GLib already provides a lot of data storage types:
GHashTable, etc. — it would seem sensible to just use them and just wrap the insertion and removal functions instead of:
- create a
GObjectwrapper around a data structure;
- wrap insertion, removal and iteration operations;
- add specialized code and signals to handle the changes and notify the views;
on top of these, if you want to write a generic storage you’ll have to:
- make every entry point a virtual function, to allow sub-classes overriding or providing a default behaviour;
- provide a generic iterator API;
- wrap everything with
in essence, the complexity of the storage quickly balloons out of control — and all because you wanted to notify another object that you added a new item inside a
wouldn’t it be good to have the “notify somebody that
$SOMETHING changed inside a data storage” thing nailed down with a generic API?
I did think it would be good, so I spent some free cycles last week to implement a generic Controller — the thing that notifies a view that something changed. it requires minimal additions to already existing data storage types provided by GLib — to the point that you don’t really need a
GObject wrapper around your model altogether.
the overall design is explained on the GNOME wiki, so I won’t rewrite it down here; and yes: if, by a cursory glance, it looks a lot like a certain platform’s API it’s because I think it’s a good representation of a correct approach.
the code lives in the GNOME Git repository; it currently has a stub LGPLv2.1 license because I think it should be seen as a 1700 lines patch to GObject/GIO under version control, and not as a stand-alone project3.
there are some things left to do, notably a
GObjectController which I think I described to a colleague as GObject::notify on PCP; for that to happen, though, I’ll need some changes in
- gtk+, in a way, allows you to bolt a controller on top< of a data storage, but you still need the data storage to be a class inside the type system otherwise you won’t be able to implement the
- and no: I don’t think that keeping the complexity under check by losing generality is a good trade-off; it’s just going to bite you in the rear later on [↩]
- it also gave me the chance to play with non-recursive autotools layouts, but that was just a side-effect [↩]