Guadec Hispana 7: el principio
Aunque se haya acabado ya la 7ª Guadec-Hispana, para mí siempre será el principio: la primera vez que aporté algo (por humilde que haya sido) a una conferencia de Software Libre. Fue una experiencia muy agradable, a pesar de que hablar delante de tanto hacker produzca cierta intimidación
. Afortunadamente, la (estupenda) cena del día anterior me sirvió para ir conociendo un poco a la gente, y ver que no mordían: es gente muy maja. Desde luego, es algo totalmente recomendado, tanto si tenéis la oportunidad de presentar algo como si acudís de oyentes.
Todas las charlas quedaron grabadas en vídeo, y la organización se encargó también de recoger las presentaciones, así que no creo que se tarde mucho en publicarlas en la página del evento: son todas muy recomendables. Y, para ir haciendo boca, aquí están las mías: en ellas se habla de Jamp, la aplicación desarrollada en el módulo de Desktop & Mobile del máster. ¡Que las disfrutéis!
JaMp talk at GUADEC-ES
I've just finished writing the slides for the JaMp's talk at the GUADEC-ES
Maybe it's still a bit longer than it should, but hey!
So, if you want to know those issues we faced with JaMp (GObject signals, D-Bus -from both C and Python sides-, and some notes about the Maemo port) come visit us to the Computer Science Faculty at A Coruña on 23rd July -next Friday- at 13:00. Grab the program here.
Another (general) status report
Some quick notes (the list of things which would deserve a full blog entry for themselves just keeps growing...)
- My manager (I don't like how "boss" sounds) retired last week. Although he visited us a couple of days more to spend some time with us, things will be, at least, different. We'll surely miss him.
- I started working with Grilo at Igalia, as the practicum work for the Free Software Master. I've been assigned a challenging task: improve the bindings infrastructure. Currently I'm getting familiar with the project, reading the doc and playing with the examples: it looks really interesting!
- Yesterday I received permissions to upload to extras-devel, so... maevies & butaca-server are available now! Of course, all said warnings about extras-devel still apply. In my case, it's about memory consumption: the backend doesn't free the objects exposed via DBus, so you have to kill it to get that done. It's a small footprint and all that, but it's not nice and of course not the way I want it: having it uploaded to extras will get me motivated to fix it
(Sure, there will be other issues as well, and I'll set up the bugtracker as soon as possible) - I've started with the slides for the JaMp talk at GUADEC-ES. There's still time left, but with these things, you never know...
Jamp is going to GUADEC-ES!
The application we've been developing at the Desktop & Mobile module in the Master has been accepted for a talk in the GUADEC-ES!
More info on that soon, but you can start by checking the program. Or even better: why don't you register and visit us?
Discovering GObject signals
My first idea about this entry was to write down some things I learnt about GObject signals, while comparing them to what I feel is a close relative: C# events. However, after the first draft I think it's better to focus on GObject now, and leave the comparison for another day. Credit should go to Víctor Jáquez, from Igalia, who explained me those things needed to start off. Don't blame him, however, for the mistakes or misconceptions I may have
There's a design pattern, the Observer pattern, used to allow "subscribers" to track or follow state changes happening on an object, the "subject". In C#, this is implemented via Events, in Java you have the Listeners, and in C, with GObject, you have signals. Going to the GObject implementation details:
enum {
END_OF_STREAM,
LAST_SIGNAL
};
static guint
jmp_mplayer_signals[LAST_SIGNAL] = { 0 };
The enum "tags" our signals. In this case, we just have one: END_OF_STREAM. LAST_SIGNAL is a convention: as it is in the last place, it will be always "our last real signal" + 1. And that's used in the next line, when we declare an array storing those signals: it will have "LAST_SIGNAL" size. It doesn't store the signal itself, but its identifier, but we'll see that later.
jmp_mplayer_signals[END_OF_STREAM] =
g_signal_newv ("end-of-stream",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
NULL,
NULL,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0,
NULL);
That is how the signal is created. It calls the gobject function g_signal_newv which creates the signal, and stores its identifier in the array position given. But, what means each of the params? Well, to be honest, I don't know too much:
The first one is easy: "end-of-stream" is the signal name. The documentation sets some limitations to the characters it can contain, but that's all.
The second one is "the type this signal pertains to". The macro G_TYPE_FROM_CLASS gets the type from the class structure (klass).
The third one is composed by signal flags. They "specify detail of when the default handler is to be invoked".
I don't know about the next three params: documentation says class_closure, accumulator, and accu_data. As soon as I learn what they do, I'll update this. Setting them to NULL worked fine for my needs.
The fourth one, called c_marshaller, sets the interface for the callbacks listening for our signals. So, in our example, g_cclosure_marshal_VOID__VOID means that we won't require our callback functions to receive arguments. You can find more closures here.
G_TYPE_NONE defines the return type for our callback, so our callback (closure) signature would have this form:
void end_of_stream_callback (JmpMPlayer *self, gpointer user_data);
Our last two params are the length of param types, and an array of param types.
So, what is left? Well, our "subject" still has to notify ("emit", in GObject) his subscribers. And those subscribers need to actually "subscribe" to the signal. Here we go:
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_EOS:
g_signal_emit (self, jmp_mplayer_signals[END_OF_STREAM], 0);
break;
g_signal_emit receives an instance the signal is being emitted on, the signal id (which we had previously stored in that array), and a detail. Quoting the documentation,
detail identifies the specific detail of the signal to invoke. A detail is a kind of magic token/argument which is passed around during signal emission and which is used by closures connected to the signal to filter out unwanted signal emissions. In most cases, you can safely set this value to zero. See the section called "The detail argument" for more details about this parameter.
And this closes the circle: subscribing to the signal.
g_signal_connect (jmplayer, "end-of-stream",
G_CALLBACK (end_of_stream_callback), loop);
g_signal_connect connects a given callback (G_CALLBACK (end_of_stream_callback), whose signature we saw before), with a signal in an instance (jmplayer), passing arguments (loop)
To write this entry, I've relied on two documents: API Reference's Signals and The GObject messaging system's Signals, and the (yet little) knowledge I acquired during this stage of Jamp implementation (which, itself, required Víctor's help and said documentation). Full code for this example is available at Gitorius, for both the "subject" and the "subscriber".
Introducing Jamp: a Jamendo client.
This last weekend we had two very interesting sessions in the Destkop and Mobile development module. On Friday, it was an introduction to Python, followed by a PyGTK app. While the app was very simple, it covered the basics: using containers to add widgets, handling signals, setting callback functions. I liked it so much that I'm seriously considering porting maevies (the maemo app a friend and I are developing, stalled for some months) to PyGTK. After all, all we needed was libRest, and I'm confident that Python has something similar.
But that was on Friday. On Saturday, we started with the first workshop. During the module, we are going to develop a Gnome desktop application, which will be later ported / adapted to Maemo: a Jamendo client called Jamp. The application has ben designed / is being designed with that port in mind, so hopefully we won't need too many changes to achieve it. We've been distributed between three teams: UI with PyGTK, web API connection with libsoup, and multimedia playback, with gstreamer. Wikipedia says
Jamendo is a music platform and community.
All music on Jamendo is free to download and licensed through one of several Creative Commons licenses or the Free Art License, making it legal to copy and share, as well as to modify and make commercial use of for some, depending on the license. Jamendo allows streaming of all of its thousands of albums in either Ogg Vorbis or MP3 format, and downloads through the BitTorrent and eDonkey networks.
So, while we learn, we'll be contributing to a Good Thing™
. I'm very motivated about using git, doing a team development, submitting patches, and enjoying such a collaborative environment.
I'll try to keep you updated