Arun Tejasvi Chaganty about articles blog thoughts research

GObject Properties

After creating a number of signals and functions on my own to handle my class’ fields, I reaised that GLib 1-uped me, and already has a frame work for that; properties. Properties are well exposed to the rest of the framework, can be elegantly handled using the g_object_set and g_object_get functions, and of course, emit signals whenever they are modified. This means you get signal creation free of cost. This was something I didn’t find well treated in the tutorial. There is a lot of boiler plate code that goes into enabling properties. An outline of the process (which is very well documented in the standard tutorial):

  1. #define a bunch of macros with a unique number for each property.
  2. Register the property in the _class_init using the g_param_spec_ () function and gobject_class_install_property(), with the aforementioned number.
  3. Implement functions for the _get_property and _set_property functions. This is done using a switch-case on the property_id, matched the macros. You can either code how to get/set the property inline in each case statement, or call functions for them (depending on the complexity).

If it all boils down to just calling get/set functions anyway, you may question the whole point of properties. Some reasons to make you think otherwise (following the same theme as previous posts):

  1. A clean way of setting fields while constructing objects:
plot = g_object_new (
  PLOTS_TYPE_WDP, 
  "probability", 0.42, // probability of success 
  "codename", "Polka-dotted Panther", // Something jazzy 
  "schedule", NULL, // Who needs timelines anyways? 
  NULL);
  1. A similar way of getting and setting properties:
g_object_set (obj, 
  "probabilty", 0.23, // Things are never as optimistic as you make them out to be 
  // the codename sounds cool enough 
  "schedule", &last_minute, // Procrastination != cool 
  NULL); 
// _get puts the value of the fields into the variables 
g_object_get (obj,
  // To put on the list of "yet another plan that failed" 
  "codename", &codename, 
  NULL);
  1. Signal emission, via the “notify” signal:
// listen for whenever probability changes 
sig_id = g_signal_connect (
  plot, 
  "notify:probability", 
  (GCallback)back_to_the_drawing_board, // The function checks if probability = 0 
  NULL); 

// Note, the callback has a special argument, the properties' specification: 
back_to_the_drawing_board (PlotsPlot *plot, GParamSpec *param, gpointer user_data);

In an enlightening discussion with the davyd on #gnome-hackers, he told me how you can use these notify signals to elegantly connect up widgets to their models, thus really creating a MVC (Model-View-Controller) framework. Certain properties expose other useful snippets data like min/max value for the G_PARAM_SPEC_INT property, which could be used on a spin-controller. Sadly, there is no ready-made function to link up a widget and a data ‘source’. I haven’t done it myself, so I can’t comment on how easy/hard it may be, but according to davyd it’s simple, and largely boilerplate.

  1. Your objects are now introspectable (I honestly don’t understand the implications of this)
  2. Your objects can be easily language-binded
  3. You’ll be seeing lots of properties in all sorts of objects, for example GTK+ widgets. Might as well get used to it. People using your code will expect the same.