Add destroy notify parameter...
authorP. F. Chimento <philip.chimento@gmail.com>
Mon, 13 Jun 2011 12:27:55 +0000 (14:27 +0200)
committerP. F. Chimento <philip.chimento@gmail.com>
Mon, 13 Jun 2011 12:27:55 +0000 (14:27 +0200)
...to resource load callback. This is for making APIs for programming
languages where resources are managed automatically.

libchimara/chimara-glk-private.h
libchimara/chimara-glk.c
libchimara/chimara-glk.h
tests/plugin-loader.c

index 67366707f92af252c0354a97e5dc08041a934ec7..0469b8da33ac313bacaf97e64c697630ed2f3fc7 100644 (file)
@@ -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);
index a200b6ba46ad8f8189a71efb8f8ac1032b5ccb28..19925569823b16569e2246a0f457a74f974348cb 100644 (file)
@@ -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;
 }
index 593fa86f411cbc6f9be785dec2f4572d566daaac..37d2220fb8776665cf07e947257dc01601db4fe6 100644 (file)
@@ -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
 
index ab47f8967dad72bc6a3f68d28327995a3d914d38..0915b3c665e30a9b338f07a43f3386e909c482be 100644 (file)
@@ -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);