GDBus, GVariant, GTK+ 3, and Vala

Vala 0.9.2 has just been released. Tarballs are available from the GNOME FTP servers. We try to keep up with changes in the GTK+ stack and are pleased to announce that Vala 0.9.2 already comes with initial support for GDBus and GTK+ 3 and enhanced support for GVariant.

GVariant

While we’ve already had GVariant bindings for quite some time now, this release integrates support for GVariant conversions. Numbers, strings, structs, arrays, and hashtables are implicitly converted to GVariant and can explicitly be converted back using the cast operator. This should make it a lot more convenient to use GVariant in Vala code.

void main () {
	Variant v = "hello, world";
	print ("%s\n", (string) v);
}

GDBus

Until now, Vala’s integrated D-Bus support has been using libdbus and bits of dbus-glib. While we will continue to support this to not break existing code, Vala 0.9.2 now also has initial support for GDBus. The supported feature set is nearly equivalent to the previous D-Bus support.
It includes client and server support, asynchronous methods on both sides, properties, signals, and error handling. The dynamic client support is still very limited, but I hope that we can complete that soon. One of the advantages of using GDBus is that you can easily use GVariant parameters for variant types instead of the incomplete GValue support we had before.

Client

[DBus (name = "org.example.Test")]
interface Test : Object {
	public abstract string test_property { owned get; set; }

	public abstract int test_int (int i, out int j) throws IOError;
}

void main () {
	Test test = Bus.get_proxy_sync (BusType.SESSION, "org.example.Test", "/org/example/test");

	int j, k;
	k = test.test_int (42, out j);

	string t;
	test.test_property = "hello";
	t = test.test_property;
}

Server

[DBus (name = "org.example.Test")]
class Test : Object {
	public string test_property { owned get; set; }

	public int test_int (int i, out int j) {
		j = 23;
		return 11;
	}
}

void main () {
	var conn = Bus.get_sync (BusType.SESSION);
	conn.register_object ("/org/example/test", new Test ());

	var app = new Application ("org.example.Test");
	app.run ();
}

GTK+ 3

This release also brings initial bindings for GTK+ 3, so that Vala applications can prepare for GNOME 3.0. As with the C library, the API of the bindings stays mostly compatible with GTK+ 2. The biggest changes are dropping of deprecated or sealed types and members.

Closures and asynchronous methods in Vala

It’s time for the release of Vala 0.7.6. Tarballs are available from the GNOME FTP servers. This release includes a couple of new features worth explaining in a bit more detail.

Closures

While Vala has lambda expressions for a long time, they haven’t supported accessing local variables from the outer method. With the release of Vala 0.7.6 this has changed, and you can access and set any local variable from lambda expressions. One place where I’d expect this to be convenient is in signal handlers:

void main (string[] args) {
    Gtk.init (ref args);
 
    var window = new Gtk.Window (Gtk.WindowType.TOPLEVEL);
    window.set_default_size (300, 50);
    window.destroy.connect (Gtk.main_quit);
 
    var button = new Gtk.Button.with_label ("Click me!");
    button.clicked.connect (() => {
        window.title = "Closures in Vala";
    });
 
    window.add (button);
    window.show_all ();
 
    Gtk.main ();
}

You can even write recursive lambda expressions:

delegate int Func (int i);
 
void main () {
	Func fib = null;
	fib = (i) => (i <= 1) ? i : (fib (i - 2) + fib (i - 1));
 
	for (int i = 0; i < 10; i++) {
		message ("%d", fib (i));
	}
}

Asynchronous methods

The idea of integrating async methods into the language is to make it easier to write code that calls or implements async methods. Async methods are frequently used in I/O API such as GIO and in D-Bus clients and servers. Traditionally, writing async code has beeen quite painful as you often end up writing callback chains and completely lose track over the control flow in the process.

Experimental support for async methods has been implemented in Vala almost a year ago. However, the implementation was rather a proof of concept than a finished solution. While I still expect a few bugs in that area with 0.7.6, it’s a lot more robust and complete than it used to be a short time ago.

So how does it look like? It’s not unlike Alex’s AsyncRunner in JavaScript except that it’s even more concise as it’s fully integrated into the language. The following code defines an async method list_dir that asynchronously enumerates all files in the home directory:

async void list_dir () {
    var dir = File.new_for_path (Environment.get_home_dir ());
    try {
        var e = yield dir.enumerate_children_async (FILE_ATTRIBUTE_STANDARD_NAME, 0, Priority.DEFAULT, null);
        while (true) {
            var files = yield e.next_files_async (10, Priority.DEFAULT, null);
            if (files == null) {
                break;
            }
            foreach (var info in files) {
                print ("%s\n", info.get_name ());
            }
        }
    } catch (GLib.Error err) {
        warning ("Error: %s\n", err.message);
    }
}
 
void main () {
    list_dir.begin ();
 
    var loop = new GLib.MainLoop (null, false);
    loop.run();
}

As you can see, it’s very easy to call the async methods enumerate_children_async and next_files_async in try-catch blocks and loops. There is no need for manually creating structs for user_data or similar inconveniences.

Async methods in Vala can also be used to implement D-Bus servers that can process multiple requests at the same time. Using it couldn’t be easier, just write an async method such as the above example, add it to a class annotated with [DBus (name = “org.example.Test”)], and register an instance of that class with the D-Bus connection. Vala also supports async methods on client-side D-Bus interfaces.

New SPARQL Parser merged

Up to now, Tracker has used Rasqal to parse SPARQL queries received from applications. We imported a copy of Rasqal into Tracker’s source tree as we use some SPARQL extensions that are not yet fully implemented in Rasqal upstream. For the last couple of weeks I’ve been writing a new SPARQL parser, a hand-written recursive descent parser.

The motivation was to speed up (large) queries and to fix a few corner cases with OPTIONAL graph patterns that Rasqal gets wrong. Rasqal does not perform very well for large queries as it always builds a full abstract syntax tree of the query, even if it’s a very simple but long INSERT statement. The hand-written parser processes queries on the fly, trying to keep only as much state around as necessary.

The new parser has now been merged into master and should improve our SPARQL support in both speed and conformance. We’ve tested it with test cases from DAWG and it appears to work at least as well as the old parser, but I’m sure we’ve missed some bugs, so let us know if you find any issues with SPARQL in Tracker master.

Vala 0.5.3

Long time no post, I’ll try to get better. Yesterday we’ve released Vala 0.5.3. Tarballs are available from the GNOME FTP servers.

  • D-Bus server support has been rewritten to directly use libdbus. Avoiding dbus-glib marshalling helps Vala to support complex D-Bus types more easily.
  • All Vala structs will now be registered with GBoxed.
  • Many critical warnings and crashes on invalid code have been fixed and replaced by better understandable error messages.
  • Private class fields and class destructors (base_finalize) are now supported.
  • vala-gen-project has been dropped from the package, it is now part of Vala Toys for gEdit, which is progressing very well.
  • Many bug fixes all over the place.

In the following weeks and months we will focus on bug fixing, finishing some partially implemented features, and switching to GObject Introspection trunk for our bindings. We’re aiming to release a stable Vala 1.0 in March 2009.

Vala 0.3.3

It’s release time again. Yesterday we’ve released Vala 0.3.3. Tarballs are available from the GNOME FTP servers.

Thanks a lot to all the people helping out and have fun with the new version! For the following two releases we will focus on GObject introspection hacking to make it easy to write great bindings for many languages.

Vala Roadmap and 0.2.0

Last week I wrote an initial roadmap that we want to follow for the upcoming Vala releases on our way towards guaranteed language stability. Today we’ve released Vala 0.2.0 as planned. Tarballs are available from the GNOME FTP servers. It’s mainly a bug fix release, however, it also got some new features like nested namespaces, static constructors, and GType-registered enums. We also have three new contributed bindings for GNOME Keyring, SDL, and libftdi, and the usual updates for existing bindings.

Vala 0.1.7

We’ve just released Vala 0.1.7. Tarballs are available from the GNOME FTP servers.

  • Enhanced property syntax
    public int foo { get; private set; default (3); }
  • New errordomain syntax
    public errordomain MyError { NOT_FOUND, TIMED_OUT }
  • Detect missing return and break statements and unreachable code
  • Improved pointer support (pointer member access, pointer element access, and pointer arithmetic)
  • New bindings: WebKit, JSON-GLib, goocanvas, hildon-fm-2, taglib, libusb, and bzip2
  • A lot of bug fixes

Vala Project Generator

Vala 0.1.5 has been released. Tarballs are available from the GNOME FTP servers. I’ve added a small tool to create new Vala projects:

Vala Project Generator

It generates the necessary autotools magic for a Vala console or GTK+ application including i18n support and it passes distcheck. Suggestions for improvements are more than welcome.

We’ve also replaced the bindings generator gidlgen by vala-gen-introspect which includes a real C parser instead of Perl scripts using regular expressions. The 20 included bindings have all been ported. Some smaller features and many bug fixes can also be found in the new release.

There are two articles about Vala and an interview in the German Linux-Magazin, all by Christian Meyer.