com gtk/php-gtk: Extend closures with 'replace' type of connection that allows one to substitute a different object (any PHP value really) in place of the one that emitted the signal.: main/php_gtk.h main/ phpg_closure.c main/phpg_gobject.c

[email protected] (David Soria Parra) Sat, 05 Nov 2005 08:31:45 +0000
Newsgroups php.gtk.cvs
Message-ID <[email protected]>
Commit:    a17507e110f7eb5644db13344da1029634bce552
Author:    Andrei Zmievski <[email protected]>         Sat, 5 Nov 2005 08:31:45 +0000
Parents:   1d4fb3d121c2508fa2efadeed25b0d7bd6b16957
Branches:  master

Link:       http://git.php.net/?p=gtk/php-gtk.git;a=commitdiff;h=a17507e110f7eb5644db13344da1029634bce552

Log:
Extend closures with 'replace' type of connection that allows one to
substitute a different object (any PHP value really) in place of the one
that emitted the signal.

Changed paths:
  M  main/php_gtk.h
  M  main/phpg_closure.c
  M  main/phpg_gobject.c


Diff:
a17507e110f7eb5644db13344da1029634bce552
diff --git a/main/php_gtk.h b/main/php_gtk.h
index d88fe18..5cb0868 100644
--- a/main/php_gtk.h
+++ b/main/php_gtk.h
@@ -137,6 +137,7 @@ typedef struct _phpg_closure_t phpg_closure_t;
 enum {
     PHPG_CONNECT_NORMAL,
     PHPG_CONNECT_SIMPLE,
+    PHPG_CONNECT_REPLACE,
     PHPG_CONNECT_OBJECT,
 };
 
@@ -458,7 +459,7 @@ void phpg_gpointer_register_self(TSRMLS_D);
 PHP_GTK_API void phpg_gpointer_new(zval **zobj, GType gtype, gpointer pointer TSRMLS_DC);
 
 /* Closures */
-PHP_GTK_API GClosure* phpg_closure_new(zval *callback, zval *user_args, int connect_type TSRMLS_DC);
+PHP_GTK_API GClosure* phpg_closure_new(zval *callback, zval *user_args, int connect_type, zval *replace_object TSRMLS_DC);
 PHP_GTK_API void phpg_watch_closure(zval *obj, GClosure *closure TSRMLS_DC);
 
 PHP_GTK_API extern PHP_GTK_EXPORT_CE(gtype_ce);
diff --git a/main/phpg_closure.c b/main/phpg_closure.c
index 1655a68..ac7f9ac 100644
--- a/main/phpg_closure.c
+++ b/main/phpg_closure.c
@@ -30,6 +30,7 @@ struct _phpg_closure_t {
 	GClosure closure;
 	zval *callback;
 	zval *user_args;
+    zval *replace_object;
 	int connect_type;
 	char *src_filename;
 	uint src_lineno;
@@ -43,10 +44,14 @@ static void phpg_closure_invalidate(gpointer data, GClosure *closure)
     if (phpg_closure->user_args) {
         zval_ptr_dtor(&phpg_closure->user_args);
     }
+    if (phpg_closure->replace_object) {
+        zval_ptr_dtor(&phpg_closure->replace_object);
+    }
     efree(phpg_closure->src_filename);
 
     phpg_closure->callback = NULL;
     phpg_closure->user_args = NULL;
+    phpg_closure->replace_object = NULL;
     phpg_closure->connect_type = PHPG_CONNECT_NORMAL;
     phpg_closure->src_filename = NULL;
     phpg_closure->src_lineno = 0;
@@ -94,12 +99,18 @@ static void phpg_closure_marshal(GClosure *closure,
     }
 
 	params = (zval ***)emalloc(n_params * sizeof(zval **));
-    for (i = 0; i < n_param_values; i++) {
+    i = 0;
+
+    if (phpg_closure->connect_type == PHPG_CONNECT_REPLACE) {
+        params[i++] = &phpg_closure->replace_object;
+    }
+
+    for ( ; i < n_param_values; i++) {
         params[i] = (zval **) emalloc(sizeof(zval *));
         *(params[i]) = NULL;
         if (phpg_gvalue_to_zval(&param_values[i], params[i], FALSE TSRMLS_CC) != SUCCESS) {
             goto err_marshal;
-		}
+        }
     }
 
     if (phpg_closure->user_args) {
@@ -125,14 +136,15 @@ static void phpg_closure_marshal(GClosure *closure,
 
 err_marshal:
     efree(callback_name);
-    for (i = 0; i < n_param_values; i++) {
+    i = (phpg_closure->connect_type == PHPG_CONNECT_REPLACE) ? 1 : 0;
+    for ( ; i < n_param_values; i++) {
         zval_ptr_dtor(params[i]);
         efree(params[i]);
     }
     efree(params);
 }
 
-PHP_GTK_API GClosure* phpg_closure_new(zval *callback, zval *user_args, int connect_type TSRMLS_DC)
+PHP_GTK_API GClosure* phpg_closure_new(zval *callback, zval *user_args, int connect_type, zval *replace_object TSRMLS_DC)
 {
     GClosure *closure;
     phpg_closure_t *phpg_closure;
@@ -158,6 +170,10 @@ PHP_GTK_API GClosure* phpg_closure_new(zval *callback, zval *user_args, int conn
         phpg_closure->user_args = NULL;
     }
 
+    if (replace_object) {
+        zval_add_ref(&replace_object);
+        phpg_closure->replace_object = replace_object;
+    }
     phpg_closure->connect_type = connect_type;
 
     return closure;
diff --git a/main/phpg_gobject.c b/main/phpg_gobject.c
index fd3ab41..856d4cb 100644
--- a/main/phpg_gobject.c
+++ b/main/phpg_gobject.c
@@ -337,7 +337,7 @@ static void phpg_signal_connect_impl(INTERNAL_FUNCTION_PARAMETERS, int connect_t
         return;
     }
 
-    closure = phpg_closure_new(callback, extra, connect_type TSRMLS_CC);
+    closure = phpg_closure_new(callback, extra, connect_type, NULL TSRMLS_CC);
     if (extra) {
         zval_ptr_dtor(&extra);
     }