From 5cee0eefebe5d0272bb108d9c3f2519ae80fee65 Mon Sep 17 00:00:00 2001 From: "P. F. Chimento" Date: Mon, 13 Jun 2011 14:27:55 +0200 Subject: [PATCH] Add destroy notify parameter... ...to resource load callback. This is for making APIs for programming languages where resources are managed automatically. --- libchimara/chimara-glk-private.h | 1 + libchimara/chimara-glk.c | 21 ++++++++++++++++++++- libchimara/chimara-glk.h | 2 +- tests/plugin-loader.c | 2 +- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/libchimara/chimara-glk-private.h b/libchimara/chimara-glk-private.h index 6736670..0469b8d 100644 --- a/libchimara/chimara-glk-private.h +++ b/libchimara/chimara-glk-private.h @@ -94,6 +94,7 @@ struct _ChimaraGlkPrivate { /* Optional callback for loading resource data */ ChimaraResourceLoadFunc resource_load_callback; gpointer resource_load_callback_data; + GDestroyNotify resource_load_callback_destroy_data; /* Callbacks for registering and unregistering dispatch objects */ gidispatch_rock_t (*register_obj)(void *, glui32); void (*unregister_obj)(void *, glui32, gidispatch_rock_t); diff --git a/libchimara/chimara-glk.c b/libchimara/chimara-glk.c index a200b6b..1992556 100644 --- a/libchimara/chimara-glk.c +++ b/libchimara/chimara-glk.c @@ -302,6 +302,9 @@ chimara_glk_finalize(GObject *object) /* Unref input queues (this should destroy them since any Glk thread has stopped by now */ g_async_queue_unref(priv->char_input_queue); g_async_queue_unref(priv->line_input_queue); + /* Destroy callback data if ownership retained */ + if(priv->resource_load_callback_destroy_data) + priv->resource_load_callback_destroy_data(priv->resource_load_callback_data); /* Free other stuff */ g_free(priv->current_dir); @@ -1519,6 +1522,7 @@ chimara_glk_update_style(ChimaraGlk *glk) * @glk: a #ChimaraGlk widget * @func: a function to call for loading resources, or %NULL * @user_data: user data to pass to @func, or %NULL + * @destroy_user_data: a function to call for freeing @user_data, or %NULL * * Sometimes it is preferable to load image and sound resources from somewhere * else than a Blorb file, for example while developing a game. Section 14 of @@ -1531,12 +1535,27 @@ chimara_glk_update_style(ChimaraGlk *glk) * Note that @func is only called if no Blorb resource map has been set; having * a resource map in place overrides this function. * + * If you pass non-%NULL for @destroy_user_data, then @glk takes ownership of + * @user_data. When it is not needed anymore, it will be freed by calling + * @destroy_user_data on it. If you wish to retain ownership of @user_data, pass + * %NULL for @destroy_user_data. + * * To deactivate the callback, call this function with @func set to %NULL. */ void -chimara_glk_set_resource_load_callback(ChimaraGlk *glk, ChimaraResourceLoadFunc func, gpointer user_data) +chimara_glk_set_resource_load_callback(ChimaraGlk *glk, ChimaraResourceLoadFunc func, gpointer user_data, GDestroyNotify destroy_user_data) { CHIMARA_GLK_USE_PRIVATE(glk, priv); + + if(priv->resource_load_callback == func + && priv->resource_load_callback_data == user_data + && priv->resource_load_callback_destroy_data == destroy_user_data) + return; + + if(priv->resource_load_callback_destroy_data) + priv->resource_load_callback_destroy_data(priv->resource_load_callback_data); + priv->resource_load_callback = func; priv->resource_load_callback_data = user_data; + priv->resource_load_callback_destroy_data = destroy_user_data; } diff --git a/libchimara/chimara-glk.h b/libchimara/chimara-glk.h index 593fa86..37d2220 100644 --- a/libchimara/chimara-glk.h +++ b/libchimara/chimara-glk.h @@ -132,7 +132,7 @@ gboolean chimara_glk_is_line_input_pending(ChimaraGlk *glk); GtkTextTag *chimara_glk_get_tag(ChimaraGlk *glk, ChimaraGlkWindowType window, const gchar *name); const gchar **chimara_glk_get_tag_names(ChimaraGlk *glk, unsigned int *num_tags); void chimara_glk_update_style(ChimaraGlk *glk); -void chimara_glk_set_resource_load_callback(ChimaraGlk *glk, ChimaraResourceLoadFunc func, gpointer user_data); +void chimara_glk_set_resource_load_callback(ChimaraGlk *glk, ChimaraResourceLoadFunc func, gpointer user_data, GDestroyNotify destroy_user_data); G_END_DECLS diff --git a/tests/plugin-loader.c b/tests/plugin-loader.c index ab47f89..0915b3c 100644 --- a/tests/plugin-loader.c +++ b/tests/plugin-loader.c @@ -100,7 +100,7 @@ main(int argc, char *argv[]) if(argc < 2) g_error("Must provide a plugin\n"); - chimara_glk_set_resource_load_callback(CHIMARA_GLK(glk), (ChimaraResourceLoadFunc)resource_load, NULL); + chimara_glk_set_resource_load_callback(CHIMARA_GLK(glk), (ChimaraResourceLoadFunc)resource_load, NULL, NULL); if( !chimara_glk_run(CHIMARA_GLK(glk), argv[1], argc - 1, argv + 1, &error) ) g_error("Error starting Glk library: %s\n", error->message); -- 2.30.2