howto create async functions using gio async api
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <glib.h> | |
#include <glib-object.h> | |
#include <gio/gio.h> | |
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) | |
#define TEST_TYPE_GIO_ASYNC (test_gio_async_get_type()) | |
#define TEST_GIO_ASYNC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TEST_TYPE_GIO_ASYNC, TestGioAsync)) | |
#define TEST_GIO_ASYNC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), TEST_TYPE_GIO_ASYNC, TestGioAsyncClass)) | |
#define TEST_IS_GIO_ASYNC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), TEST_TYPE_GIO_ASYNC)) | |
#define TEST_IS_GIO_ASYNC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), TEST_TYPE_GIO_ASYNC)) | |
#define TEST_GIO_ASYNC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TEST_TYPE_GIO_ASYNC, TestGioAsyncClass)) | |
#define TEST_GIO_ASYNC_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), TEST_TYPE_GIO_ASYNC, TestGioAsyncPrivate)) | |
typedef struct _TestGioAsync TestGioAsync; | |
typedef struct _TestGioAsyncClass TestGioAsyncClass; | |
typedef struct _TestGioAsyncPrivate TestGioAsyncPrivate; | |
struct _TestGioAsyncClass { | |
GObjectClass parent; | |
}; | |
struct _TestGioAsyncPrivate { | |
gchar *something_to_say; | |
}; | |
struct _TestGioAsync { | |
GObject parent_instance; | |
TestGioAsyncPrivate *priv; | |
}; | |
enum { | |
TEST_GIO_ASYNC_DUMMY_PROPERTY, | |
TEST_GIO_ASYNC_SOMETHING_TO_SAY | |
}; | |
static gpointer test_gio_async_parent_class = NULL; | |
GType test_gio_async_get_type(void) G_GNUC_CONST; | |
static void test_gio_async_set_property(GObject *obj, guint prop_id, const GValue *value, GParamSpec *spec) { | |
TestGioAsyncPrivate *priv = NULL; | |
priv = TEST_GIO_ASYNC_GET_PRIVATE(obj); | |
switch(prop_id) { | |
case TEST_GIO_ASYNC_SOMETHING_TO_SAY: | |
priv->something_to_say = g_value_dup_string(value); | |
break; | |
default: | |
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, spec); | |
} | |
} | |
static void test_gio_async_get_property(GObject *obj, guint prop_id, GValue *value, GParamSpec *spec) { | |
TestGioAsyncPrivate *priv = NULL; | |
priv = TEST_GIO_ASYNC_GET_PRIVATE(obj); | |
switch(prop_id) { | |
case TEST_GIO_ASYNC_SOMETHING_TO_SAY: | |
g_value_set_string(value, priv->something_to_say); | |
break; | |
default: | |
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, spec); | |
} | |
} | |
static void test_gio_async_instance_init(TestGioAsync *self) { | |
self->priv = TEST_GIO_ASYNC_GET_PRIVATE(self); | |
} | |
static void test_gio_async_finalize(GObject *obj) { | |
TestGioAsyncPrivate *priv = NULL; | |
priv = TEST_GIO_ASYNC_GET_PRIVATE(obj); | |
g_free(priv->something_to_say); | |
G_OBJECT_CLASS(test_gio_async_parent_class)->finalize(obj); | |
} | |
static void test_gio_async_class_init(TestGioAsyncClass *klass) { | |
test_gio_async_parent_class = g_type_class_peek_parent(klass); | |
g_type_class_add_private(klass, sizeof(TestGioAsyncPrivate)); | |
G_OBJECT_CLASS(klass)->set_property = test_gio_async_set_property; | |
G_OBJECT_CLASS(klass)->get_property = test_gio_async_get_property; | |
G_OBJECT_CLASS(klass)->finalize = test_gio_async_finalize; | |
g_object_class_install_property(G_OBJECT_CLASS(klass), | |
TEST_GIO_ASYNC_SOMETHING_TO_SAY, | |
g_param_spec_string("something_to_say", | |
"something_to_say", | |
"something_to_say", | |
NULL, | |
G_PARAM_READABLE | | |
G_PARAM_WRITABLE | | |
G_PARAM_CONSTRUCT)); | |
} | |
GType test_gio_async_get_type(void) { | |
static volatile gsize test_gio_async_type_id__volatile = 0; | |
if(g_once_init_enter(&test_gio_async_type_id__volatile)) { | |
static const GTypeInfo g_define_type_info = { sizeof(TestGioAsyncClass), | |
(GBaseInitFunc) NULL, | |
(GBaseFinalizeFunc) NULL, | |
(GClassInitFunc) test_gio_async_class_init, | |
(GClassFinalizeFunc) NULL, | |
NULL, | |
sizeof(TestGioAsync), | |
0, | |
(GInstanceInitFunc) test_gio_async_instance_init, | |
NULL }; | |
, GType test_gio_async_type_id = g_type_register_static(G_TYPE_OBJECT, | |
"TestGioAsync", | |
&g_define_type_info, | |
0); | |
g_once_init_leave(&test_gio_async_type_id__volatile, test_gio_async_type_id); | |
} | |
return test_gio_async_type_id__volatile; | |
} | |
TestGioAsync* test_gio_async_new(void) { | |
return g_object_new(TEST_TYPE_GIO_ASYNC, NULL); | |
} | |
static gboolean test_gio_async_say_idle_func(gpointer user_data) { | |
TestGioAsync *self = (TestGioAsync *) user_data; | |
GSimpleAsyncResult *simple = g_object_get_data(G_OBJECT(self), "simple"); | |
gchar *result = NULL; | |
g_object_get(G_OBJECT(self), "something_to_say", &result, NULL); | |
g_simple_async_result_set_op_res_gpointer(simple, result, g_free); | |
g_simple_async_result_complete_in_idle(simple); | |
_g_object_unref0(simple); | |
return FALSE; | |
} | |
void test_gio_async_say(TestGioAsync *self, | |
GCancellable *cancellable, | |
GAsyncReadyCallback callback, | |
gpointer user_data) { | |
GSimpleAsyncResult *simple = g_simple_async_result_new(G_OBJECT(self), | |
callback, | |
user_data, | |
test_gio_async_say); | |
g_simple_async_result_set_check_cancellable(simple, cancellable); | |
g_object_set_data(G_OBJECT(self), "simple", simple); | |
g_idle_add(test_gio_async_say_idle_func, self); | |
} | |
gchar* test_gio_async_say_finish(TestGioAsync *self, | |
GAsyncResult *res, | |
GError **error) { | |
GSimpleAsyncResult *simple = NULL; | |
g_return_val_if_fail(g_simple_async_result_is_valid(res, G_OBJECT(self), test_gio_async_say), NULL); | |
simple = (GSimpleAsyncResult *) res; | |
if(error) g_simple_async_result_propagate_error(simple, error); | |
return g_simple_async_result_get_op_res_gpointer(simple); | |
} | |
static void test_gio_async_say_cb(GObject *self, GAsyncResult *res, gpointer user_data) { | |
gchar *result = test_gio_async_say_finish(TEST_GIO_ASYNC(self), res, NULL); | |
GMainLoop *mainloop = (GMainLoop *) user_data; | |
g_print("%s\n", result); | |
g_main_loop_quit(mainloop); | |
} | |
int main(int argc, char *argv[]) { | |
TestGioAsync *test = test_gio_async_new(); | |
GMainLoop *mainloop = g_main_loop_new(NULL, TRUE); | |
g_object_set(G_OBJECT(test), "something_to_say", "hello world", NULL); | |
test_gio_async_say(test, NULL, test_gio_async_say_cb, mainloop); | |
g_print("started saying..\n"); | |
g_main_loop_run(mainloop); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment