The corresponding code in C is pretty straight forward and would
look like this:
static void on_new_kinect_device ( GObject *obj,
GAsyncResult *res,
gpointer user_data)
{
kinect = gfreenect_device_new_finish (res, &error);
if (kinect == NULL)
{
g_debug ("Failed to created kinect device: %s", error->message);
g_error_free (error);
clutter_main_quit ();
return;
}
g_debug ("Kinect device created!");
int main (int argc, char *argv[])
{
gfreenect_device_new (0,
GFREENECT_SUBDEVICE_CAMERA,
NULL,
on_new_kinect_device,
NULL);
clutter_main ();
return 0;
}
Trying to implement that in Vala, I took the approach below.
It seems however, that the init_async does not work. Looking at the
generated C-Code it looks like the g_async_initable_init_finish method
is called right after init_async an not with in the callback as expected.
As a result the code is crashing in the underlying libusb due to
incorrect initialization.
What am I missing here? Any idea how to solve the issue.
thanks and sorry for the lengthy post,
--tomw
---------------------------------------------------------
using GLib;
using GFreenect;
public class Main : Object
{
public GFreenect.Device device;
public Cancellable cancellable;
public Main () {
Cancellable cancellable = new Cancellable ();
}
public async void run (out Device dev) {
debug ("Starting");
Device device = (Device) GLib.Object.@new (
typeof (Device),
"index", 0,
"subdevices", Subdevice.CAMERA
);
debug ("Device created");
Idle.add (run.callback);
try {
debug ("Trying to run init_async");
bool re = yield device.init_async (Priority.DEFAULT, cancellable);
if (re) {
debug ("Result = OK");
} else {
debug ("Result = FAILED");
}
} catch (Error e) {
debug ("Error initalizing device : %s", e.message);
}
}
public void callback (Main? source, GLib.AsyncResult? res, void* user_data) {
debug ("Entering Callback");
Device dev;
if (res != null) {
source.run.end (res, out dev);
debug ("Callback called - Device created");
try {
Device kinect = new dev.finish(res);
} catch (Error e) {
debug ("Error finalizing device : %s", e.message);
}
} else {
debug ("No result delivered");
}
}
static int main (string[] args) {
var loop = new MainLoop ();
var app = new Main ();
app.run.begin ((AsyncReadyCallback)callback);
loop.run ();
return 0;
}
}
[1] https://gitorious.org/gfreenect
[2] http://pastebin.com/xdXKCmWR
_______________________________________________
vala-list mailing list
vala...@gnome.org
http://mail.gnome.org/mailman/listinfo/vala-list
[Freenect C init sample ]
^^ No need for this since you're using yield in the function. Might
actually be harmful, causing a race between the init_async you call and
the one Vala calls implicitly.
> try {
> debug ("Trying to run init_async");
> bool re = yield device.init_async (Priority.DEFAULT, cancellable);
^^ this yield returns to main loop and once init_async calls its
call-back will call init_finish for you. So after this line the device
is initialized.
> if (re) {
> debug ("Result = OK");
> } else {
> debug ("Result = FAILED");
> }
> } catch (Error e) {
> debug ("Error initalizing device : %s", e.message);
> }
> }
>
> public void callback (Main? source, GLib.AsyncResult? res, void* user_data) {
> debug ("Entering Callback");
> Device dev;
> if (res != null) {
> source.run.end (res, out dev);
> debug ("Callback called - Device created");
> try {
> Device kinect = new dev.finish(res);
^^ And here you're basically trying to create another device.
> } catch (Error e) {
> debug ("Error finalizing device : %s", e.message);
> }
> } else {
> debug ("No result delivered");
> }
> }
I would do it like this:
using GLib;
using GFreenect;
public class Main : Object
{
public GFreenect.Device device;
public Cancellable cancellable;
public Main () {
Cancellable cancellable = new Cancellable ();
}
public async void run () {
debug ("Starting");
Device device = (Device) GLib.Object.@new (
typeof (Device),
"index", 0,
"subdevices", Subdevice.CAMERA
);
debug ("Device created");
try {
debug ("Trying to run init_async");
bool re = yield device.init_async (Priority.DEFAULT, cancellable);
// start using the device
} catch (Error e) {
// re will always be true in the try block if you always get an error
// when it's false, because you end up here anyway.
debug ("Error initalizing device : %s", e.message);
}
}
static int main (string[] args) {
var loop = new MainLoop ();
var app = new Main ();
app.run.begin ();
loop.run ();
return 0;
> > try {
> > debug ("Trying to run init_async");
> > bool re = yield device.init_async (Priority.DEFAULT, cancellable);
>
> ^^ this yield returns to main loop and once init_async calls its
> call-back will call init_finish for you. So after this line the device
> is initialized.
Thanks,
I'm afraid that the statement above is just initializing a new device
instance, which (according to gfreenect) can only be used after
gfreenect_device_new_finish () is called like in the C example. This is
why I was trying to create a finished instance in the callback. As the
code is still crashing in libusb - Is there a way to get the callback
called rather than the implicit init_finish being called from
init_async?
--tomw
gfreenect_device_new_finished is just calling _async_initable_new_finish
which calls async_initable_finish, same for _device_new. Removing the
subdevices property stops the crashing here. looking at the gfreenect
code that isn't used at all:
https://github.com/elima/GFreenect/blob/master/gfreenect/gfreenect-device.c#L1150
many thanks,
--tomw