[gjs] Remove user_data arguments for callbacks



commit 906ad5a2186545d7804934244e4c3d9cc8165dec
Author: Florian Müllner <florian muellner gmail com>
Date:   Fri Dec 4 02:46:31 2009 +0100

    Remove user_data arguments for callbacks
    
    We already remove user_data arguments to the timeout/idle and
    signal functions - this change does the same for generic callbacks
    (assuming correct gi-annotations of course).
    
    Note that this change constitutes an API break.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=606258

 gi/function.c                  |   44 ++++++++++++++++++++++++---------------
 test/js/testEverythingBasic.js |   33 +++++++++++++----------------
 2 files changed, 42 insertions(+), 35 deletions(-)
---
diff --git a/gi/function.c b/gi/function.c
index f8a4fb7..f3083ea 100644
--- a/gi/function.c
+++ b/gi/function.c
@@ -44,6 +44,7 @@
 typedef struct {
     GIFunctionInfo *info;
     guint n_destroy_notifies;
+    guint n_user_data;
     guint expected_js_argc;
     guint js_out_argc;
     guint inout_argc;
@@ -357,7 +358,6 @@ gjs_callback_from_arguments(JSContext *context,
     GSList *l;
     gboolean is_notify = FALSE;
     GjsCallbackInfo *callback_info = NULL;
-    int arg_n;
 
     for (l = *data_for_notify; l; l = l->next) {
         GjsCallbackInfo *callback_info = l->data;
@@ -406,11 +406,6 @@ gjs_callback_from_arguments(JSContext *context,
             g_assert(g_arg_info_get_destroy(arg_info) < n_args);
 
             gjs_callback_info_add_argument(context, callback_info, argv[*argv_pos]);
-            arg_n = g_arg_info_get_closure(arg_info);
-            if (arg_n > current_arg_pos && arg_n < n_args) {
-                g_assert_cmpuint(arg_n, <, argc);
-                gjs_callback_info_add_argument(context, callback_info, argv[arg_n]);
-            }
             callback_info->arg_index = g_arg_info_get_destroy(arg_info);
 
             callback_info->invoke_infos = g_slist_prepend(callback_info->invoke_infos, invoke_info);
@@ -419,11 +414,6 @@ gjs_callback_from_arguments(JSContext *context,
         case GI_SCOPE_TYPE_ASYNC:
             gjs_callback_info_add_argument(context, &invoke_info->callback_info, argv[*argv_pos]);
 
-            arg_n = g_arg_info_get_closure(arg_info);
-            if (arg_n > current_arg_pos && arg_n < n_args) {
-                g_assert_cmpuint(arg_n, <, argc);
-                gjs_callback_info_add_argument(context, &invoke_info->callback_info, argv[arg_n]);
-            }
             *all_invoke_infos = g_slist_prepend(*all_invoke_infos, invoke_info);
             break;
         default:
@@ -575,6 +565,7 @@ gjs_invoke_c_function(JSContext      *context,
     for (i = 0; i < n_args; i++) {
         GIDirection direction;
         GIArgInfo arg_info;
+        gboolean arg_removed = FALSE;
 
         /* gjs_debug(GJS_DEBUG_GFUNCTION, "i: %d in_args_pos: %d argv_pos: %d", i, in_args_pos, argv_pos); */
 
@@ -605,10 +596,9 @@ gjs_invoke_c_function(JSContext      *context,
 
             if (g_slist_find(callback_arg_indices, GUINT_TO_POINTER((guint)i)) != NULL) {
                 g_assert(type_tag == GI_TYPE_TAG_VOID);
+                arg_removed = TRUE;
                 convert_argument = FALSE;
-
-                g_assert_cmpuint(argv_pos, <, argc);
-                in_value->v_pointer = (gpointer)argv[argv_pos];
+                in_value->v_pointer = NULL;
             } else if (type_tag == GI_TYPE_TAG_VOID) {
                 /* FIXME: notify/throw saying the callback annotation is wrong */
                 convert_argument = FALSE;
@@ -625,6 +615,8 @@ gjs_invoke_c_function(JSContext      *context,
 
                 interface_type = g_base_info_get_type(interface_info);
                 if (interface_type == GI_INFO_TYPE_CALLBACK) {
+                    gint user_data_pos;
+
                     if (!gjs_callback_from_arguments(context, interface_info, &arg_info,
                                                      i, n_args, &argv_pos, argc, argv,
                                                      &invoke_infos,
@@ -633,8 +625,12 @@ gjs_invoke_c_function(JSContext      *context,
                         failed = TRUE;
                         break;
                     }
+                    user_data_pos = g_arg_info_get_closure(&arg_info);
+                    if (is_method)
+                        --user_data_pos;
                     callback_arg_indices = g_slist_prepend(callback_arg_indices,
-                                                           GINT_TO_POINTER(g_arg_info_get_closure(&arg_info)));
+                                                           GINT_TO_POINTER(user_data_pos));
+
                     convert_argument = FALSE;
                 }
 
@@ -661,7 +657,8 @@ gjs_invoke_c_function(JSContext      *context,
                 inout_args_pos++;
             }
 
-            ++argv_pos;
+            if (!arg_removed)
+                ++argv_pos;
         }
 
         ++in_args_pos;
@@ -993,6 +990,7 @@ init_cached_function_data (JSContext      *context,
                            GIFunctionInfo *info)
 {
     guint8 i, n_args;
+    gboolean is_method;
     GError *error = NULL;
     GITypeInfo return_type;
 
@@ -1001,6 +999,8 @@ init_cached_function_data (JSContext      *context,
         return FALSE;
     }
 
+    is_method = (g_function_info_get_flags(info) & GI_FUNCTION_IS_METHOD) != 0;
+
     g_callable_info_load_return_type((GICallableInfo*)info, &return_type);
     if (g_type_info_get_tag(&return_type) != GI_TYPE_TAG_VOID)
       function->js_out_argc += 1;
@@ -1010,10 +1010,15 @@ init_cached_function_data (JSContext      *context,
     for (i = 0; i < n_args; i++) {
         GIDirection direction;
         GIArgInfo arg_info;
-        guint8 destroy;
+        guint8 destroy, closure;
 
         g_callable_info_load_arg((GICallableInfo*) info, i, &arg_info);
         destroy = g_arg_info_get_destroy(&arg_info);
+        if (is_method)
+            --destroy;
+        closure = g_arg_info_get_closure(&arg_info);
+        if (is_method)
+            --closure;
         direction = g_arg_info_get_direction(&arg_info);
 
         if (destroy > 0 && destroy < n_args) {
@@ -1021,6 +1026,11 @@ init_cached_function_data (JSContext      *context,
             function->n_destroy_notifies += 1;
         }
 
+        if (closure > 0 && closure < n_args) {
+            function->expected_js_argc -= 1;
+            function->n_user_data += 1;
+        }
+
         if (direction == GI_DIRECTION_IN || direction == GI_DIRECTION_INOUT)
             function->expected_js_argc += 1;
         if (direction == GI_DIRECTION_OUT || direction == GI_DIRECTION_INOUT)
diff --git a/test/js/testEverythingBasic.js b/test/js/testEverythingBasic.js
index f7da669..9495070 100644
--- a/test/js/testEverythingBasic.js
+++ b/test/js/testEverythingBasic.js
@@ -6,6 +6,7 @@ if (!('assertEquals' in this)) { /* allow running this test standalone */
 
 // We use Gio to have some objects that we know exist
 const Gio = imports.gi.Gio;
+const Lang = imports.lang;
 
 const INT8_MIN = (-128);
 const INT16_MIN = (-32767-1);
@@ -205,24 +206,20 @@ function testCallback() {
     assertEquals('CallbackUndefined', Everything.test_callback(undefined), 0);
 }
 
-function testCallbackUserData() {
-    let callbackUserData = function(userData) {
-                               return userData.foo.length;
-                           };
-
-    let userData = {'foo': 'bar'};
-    assertEquals('CallbackUserData', Everything.test_callback_user_data(
-                                     callbackUserData, userData), userData.foo.length);
-}
-
 function testCallbackDestroyNotify() {
-    let called = 0;
-    let test = function(userData) {
-                   called++;
-                   return userData;
-               };
-    assertEquals('CallbackDestroyNotify', Everything.test_callback_destroy_notify(test, 42), 42);
-    assertEquals('CallbackDestroyNotify', called, 1);
+    let testObj = {
+        called: 0,
+        test: function(data) {
+            this.called++;
+            return data;
+        }
+    };
+    assertEquals('CallbackDestroyNotify',
+                 Everything.test_callback_destroy_notify(Lang.bind(testObj,
+                     function() {
+                         return testObj.test(42);
+                     })), 42);
+    assertEquals('CallbackDestroyNotify', testObj.called, 1);
     assertEquals('CallbackDestroyNotify', Everything.test_callback_thaw_notifications(), 42);
 }
 
@@ -407,7 +404,7 @@ function testTortureSignature1Success() {
 
 function testTortureSignature2() {
     let [y, z, q] = Everything.test_torture_signature_2(42, function () {
-        }, null, 'foo', 7);
+        }, 'foo', 7);
     assertEquals(Math.floor(y), 42);
     assertEquals(z, 84);
     assertEquals(q, 10);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]