Don’t you hate it when you arrive near deployment stage and you have to get back to the design table because someone makes you notice that the architecture you’ve very cleverly layed out has one fatal flaw?
Well, to be honest, I hate it and yet I love it. Because it clearly puts your ego down and moves everything under a new perspective.
Let’s take GNOME Dictionary. Last week-end I was getting the UI down with the new
GdictContext object; then, Reinout van Schouwen showed me bug #167366, and this week – aside from doing the (hopefully) last profiling session of
BookmarkFile – I had to design a new architecture, flexible enough to be expanded with new back-ends.
Luckily, when I re-designed the whole implementation of the dictionary protocol client, I had it clearly separated from the whole code-base; this led to a session of “find-and-rename” and some minor code tweaking.
Now, the code in libgdict is a little more complex – but it’s expandible and should allow the creation of multiple back-ends more easily.
At top level, we still have
GdictContext, but instead of being an
GObject it’s now a
GTypeInterface; every dictionary context must inherit it’s methods (and a locality property):
gboolean (*get_databases) (GdictContext *context, GError **error); gboolean (*get_strategies) (GdictContext *context, GError **error); gboolean (*match_word) (GdictContext *context, const gchar *database, const gchar *strategy, const gchar *word, GError **error); gboolean (*define_word) (GdictContext *context, const gchar *database, const gchar *word, GError **error);
Also, we have the same signals as we had before the re-design:
void (*database_found) (GdictContext *context, GdictDatabase *database); void (*strategy_found) (GdictContext *context, GdictStrategy *strategy); void (*match_found) (GdictContext *context, GdictMatch *match); void (*definition_found) (GdictContext *context, GdictDefinition *definition);
The first implementation of this interface is the
GdictClientContext object, which is the dictionary protocol client object; in order to write a dictionary client, all you have to do is instantiate a new
GdictContext implementation and use one of the
GdictContext *context; GError *definition_error = NULL; ... /* we use a GdictClientContext */ context = gdict_client_context_new ("dict.org", 2628); g_signal_connect (context, "definition-found", G_CALLBACK (on_definition_found), NULL); gdict_context_define_word (context, "penguin", &definition_error); ...
Adding contextes is a matter of writing a
Note: Even adding run-time modules would be quite simple; right now, I don’t intend to – but nothing prevets you from doing it (hint! hint!)
Now that the architecture is a bit more solid, I’m going to land it into CVS. I’ll create a branch of gnome-utils for it; my code will live in a new directory, and will slowly move
gnome-utils/gdictsrc out of build. Now the timeframe for my work has shifted a bit, but I’m still very confident on having a feature-equivalent version of GNOME Dictionary out before the end of December.