Dictionary Applet/5

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 methods:

  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 GdictContext implementation.

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.