Over the last couple of weeks I’ve been gradually pulling glibmm’s gio wrapper into shape. It provides a gtkmm-like API for the new gio I/O API in glib 2.15/16. It’s available in the glibmm 2.15.x tarballs, and will be API stable in glibmm 2.16 (Tarballs, svn).
There are a handful of giomm examples in the gtkmm-documentation module and we are adding more. Thanks to Marko Anastasov who did all the initial wrapping work and Jonathan Jongsma and José Alburquerque who have helped to perfect it.
It was quite awkward repetitive work because we had to add so many method overloads and reorder so many parameters, and write most of the documentation by hand (not finished yet). I feel most of the work is now done, so I’m less worried about impending API stability, but I still want more people to review the API and try to use it.
Some thoughts for people creating language bindings
Many gio functions take several arguments, half of which (such as the GCancellable, and sometimes the callback) can be NULL or have obvious defaults (such as G_IO_PRIORITY_DEFAULT, or G_FILE_QUERY_INFO_NONE, or “*” for attributes). It’s too late to reorder the parameters in the C API, but I strongly suggest that you try to copy the parameter sequences in the giomm methods. Replacing GError with an exception removes another parameter. For instance, compare Gio::File::query_info(), which can be called with no parameters, with g_file_query_info().
Some thoughts in general
I quite like the consistent approach to asynchronous operations. Basically, there are often two forms of a function – a synchronous one (blocks, returning when it has a result) and an asynchronous one (returns immediately, and tells you later when it has a result). For instance, g_file_query_info() and g_file_query_info_async(). With the async one, you then call the *_finish() (for instance, g_file_query_info_finish()) to get the result. See GFile (or Gio::File) for a full explanation.
For a while I wondered if some intermediate object would be conceptually more beautiful, so you wouldn’t have to read the documentation to know about the *_finish() method to call, but it seems worse. For instance:
async_request = file.query_info_async(); async_request.signal_finished().connect(&on_query_finished); async_request.start(); //We would have to do this only after connecting the signal. ... if(something happened) async_request.cancel(); ... void on_query_finished(...) { ... result = async_request.get_result(); }
Hey,
Nice work.
I’m wondering about the split between std::strings and Glib::ustrings. Things like Gio::File::create_for_path take std::strings, so I presume this means it expect filenames to be encoded in the native filesystem encoding, whatever that happens to be. OK. But what about attributes? g_file_info_get_attribute_as_string(), for example, returns UTF-8 strings, not locale dependent ones, so shouldn’t it use ustrings?
Also, about initialisation: do Glib::MainLoop and Gtk::Main initialise Gio? I presume they do, but I haven’t tried it out…
Regards.
Yes, Gio::File::get_attribute_as_string() should return a Glib::ustring. I’ll fix that. I didn’t see the mention of UTF-8 in its documentation. The encoding (UTF-8 or unknown/unspecified) is usually not mentioned in the documentation, which is frustrating.
I think I will make gtkmm depend on giomm and make Gtk::Main initialize giomm. I guess that Glib::Mainloop could not initialize giomm because it would create a dependency on giomm from glibmm.