Crap code of the moment: libgip (and how to make it better)

This week, while finishing my Computer Graphics assignment I had to deal with a library my professor had “sponsored” the development: libgip.

This library have a great purpose: easy development and maintance of GUI (Graphical User Interfaces) of Computer Graphics & Image Processing software. These software generally have some toolboxes, user input components and the canvas, where output is shown. After he experienced with TCL/Tk and Gtk for some time, he experienced some problems, the slowness of the former and the big API (Application Program Interface) change from Gtk1 to Gtk2. So he opted to code an abstraction layer atop of a toolkit (he have chosen wxWidgets for some reasons), so if the underline toolkit API changed, one port this layer to the new API and every program based on it should work.

Ok, a great idea, sure, but how about the code?

Well… to begin with, there is no source code available and no documentation. I had to read include (.h) files, which were poorly documented and not all prototypes were implemented, not even some basic widgets, like spin buttons or table layout. Then I reached some weird limitations, like the maximum of 4 buttons per application and then some weird bugs, like one in gip_check_box_get(), which receives the widget as first parameter, but actually uses the last created widget! What the hell? I cannot check the code, but it seems that the whole thing uses global variables (reentrant code? “what is this?” the code author’s may think)

If this library wants to reach any usable state, it should be rewritten, by someone that can code properly in C and with the following requirements in mind:

  1. Provide high level components to request user input, something that, given a label and possible some limits (based on type), assembles an uniform and pretty user interface. Something like Label-Entry, that adds a label and a text entry, in a tabular layout, or Label-Degree, the same, but with a specialized widget that limit user input to valid degrees, possible with limits like 0-360°, Label-Color (to pick colors), Label-Histogram (to present histograms), Label-Range (to select start and end values), other like Label-Float, Label-Integer, both with optional limits, increase steps and callbacks if data changed. If this layer wants to easy users lives, this is the first step.
  2. Use widgets names and avoid widgets as global variables. Almost every GUI toolkit provides way to refer to a widget by its name, so you don’t have to keep a global variable pointing to it, this make things much easier.
  3. Use garbage collector or an intelligent memory management system. With today computers, there is no advantage to do memory management by means of malloc() and free(), they make you code a lot more and most bugs comes from it. GCC uses the garbage collector called boehm-gc, Samba uses an intelligent memory management system called talloc, it takes care of memory using a a hierarchical, reference counted memory pool system with destructors, it can release a whole tree of allocated memory with just one talloc_free(). Using one of these systems will reduce code, while improve software quality and stability.
  4. Easy to use GUI description. Probably the best way to address it is with a run-time interpreted file, something like XML or other text format, so developers can change and test their GUI without the need to recompile the whole software, a process that often takes some time. Callbacks and controller code can use widget names to operate on them.
  5. Easy to use data saving/loading system. Often programs need to store user settings and programmer should not have to code it again and again. This should be easy, probably associated with GUI description mentioned above, data could be marked as “persistent” and it would be loaded/restored automatically.
  6. Threaded design with automatic locking handling (whenever possible): computer graphics and image processing are too CPU intensive and may “freeze” GUI for long time, giving users no feedback may lead them to kill the application. With an easy to use thread system, users may delegate CPU hungry tasks to a thread, leaving GUI responsive.

Comments are closed.