support disconnecting signals, based on patch by Alexandre Moreira test
authorJürg Billeter <j@bitron.ch>
Fri, 16 Mar 2007 22:13:48 +0000 (22:13 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Fri, 16 Mar 2007 22:13:48 +0000 (22:13 +0000)
2007-03-16  Jürg Billeter  <j@bitron.ch>

* vala/valacodegenerator.vala: support disconnecting signals, based on
  patch by Alexandre Moreira
* tests/test-018.vala, tests/test-018.out: test disconnecting signals

svn path=/trunk/; revision=237

vala/ChangeLog
vala/tests/test-018.out
vala/tests/test-018.vala
vala/vala/valacodegenerator.vala

index 6da0106..daff2b5 100644 (file)
@@ -1,5 +1,11 @@
 2007-03-16  Jürg Billeter  <j@bitron.ch>
 
+       * vala/valacodegenerator.vala: support disconnecting signals, based on
+         patch by Alexandre Moreira
+       * tests/test-018.vala, tests/test-018.out: test disconnecting signals
+
+2007-03-16  Jürg Billeter  <j@bitron.ch>
+
        * vala/valacodegenerator.vala: fix null pointer dereference when
          emitting signals
 
index f136bee..37c2032 100644 (file)
@@ -1 +1 @@
-Signal Test: 1 2 3 4 5 6 7
+Signal Test: 1 2 3 4 5 6 7 8 9 10
index fe4c917..6081ed4 100644 (file)
@@ -3,8 +3,8 @@ using GLib;
 class Maman.Foo {
        public signal void activated (bool b);
 
-       public void do_action () {
-               activated (false);
+       public void do_action (bool b) {
+               activated (b);
        }
 }
 
@@ -24,7 +24,7 @@ class Maman.Bar {
                
                foo.activated += (foo, b) => {
                        if (b) {
-                               stdout.printf (" BAD");
+                               stdout.printf (" 8");
                        } else {
                                stdout.printf (" 4");
                        }
@@ -34,9 +34,17 @@ class Maman.Bar {
 
                stdout.printf (" 3");
                
-               foo.do_action ();
+               foo.do_action (false);
 
                stdout.printf (" 6");
+               
+               foo.activated -= activated;
+
+               stdout.printf (" 7");
+
+               foo.do_action (true);
+
+               stdout.printf (" 9");
        }
 
        static int main (string[] args) {
@@ -45,7 +53,7 @@ class Maman.Bar {
                var bar = new Bar ();
                bar.run ();
        
-               stdout.printf (" 7\n");
+               stdout.printf (" 10\n");
 
                return 0;
        }
index 1784780..253fdf9 100644 (file)
@@ -3684,9 +3684,22 @@ public class Vala.CodeGenerator : CodeVisitor {
                        var sig = (Signal) a.left.symbol_reference.node;
                        
                        var m = (Method) a.right.symbol_reference.node;
-                       var connect_func = "g_signal_connect_object";
-                       if (!m.instance) {
-                               connect_func = "g_signal_connect";
+
+                       string connect_func;
+                       bool disconnect = false;
+
+                       if (a.operator == AssignmentOperator.ADD) {
+                               connect_func = "g_signal_connect_object";
+                               if (!m.instance) {
+                                       connect_func = "g_signal_connect";
+                               }
+                       } else if (a.operator == AssignmentOperator.SUB) {
+                               connect_func = "g_signal_handlers_disconnect_matched";
+                               disconnect = true;
+                       } else {
+                               a.error = true;
+                               Report.error (a.source_reference, "Specified compound assignment type for signals not supported.");
+                               return;
                        }
 
                        var ccall = new CCodeFunctionCall (new CCodeIdentifier (connect_func));
@@ -3697,7 +3710,30 @@ public class Vala.CodeGenerator : CodeVisitor {
                                ccall.add_argument (new CCodeIdentifier ("self"));
                        }
 
-                       ccall.add_argument (sig.get_canonical_cconstant ());
+                       if (!disconnect) {
+                               ccall.add_argument (sig.get_canonical_cconstant ());
+                       } else {
+                               ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
+                               
+                               // get signal id
+                               var ccomma = new CCodeCommaExpression ();
+                               var temp_decl = get_temp_variable_declarator (uint_type);
+                               temp_vars.prepend (temp_decl);
+                               var parse_call = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_parse_name"));
+                               parse_call.add_argument (sig.get_canonical_cconstant ());
+                               var decl_type = (DataType) sig.symbol.parent_symbol.node;
+                               parse_call.add_argument (new CCodeIdentifier (decl_type.get_type_id ()));
+                               parse_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_decl.name)));
+                               parse_call.add_argument (new CCodeConstant ("NULL"));
+                               parse_call.add_argument (new CCodeConstant ("FALSE"));
+                               ccomma.append_expression (parse_call);
+                               ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
+                               
+                               ccall.add_argument (ccomma);
+
+                               ccall.add_argument (new CCodeConstant ("0"));
+                               ccall.add_argument (new CCodeConstant ("NULL"));
+                       }
 
                        ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (m.get_cname ()), "GCallback"));
 
@@ -3712,7 +3748,9 @@ public class Vala.CodeGenerator : CodeVisitor {
                                } else if (a.right is LambdaExpression) {
                                        ccall.add_argument (new CCodeIdentifier ("self"));
                                }
-                               ccall.add_argument (new CCodeConstant ("0"));
+                               if (!disconnect) {
+                                       ccall.add_argument (new CCodeConstant ("0"));
+                               }
                        } else {
                                ccall.add_argument (new CCodeConstant ("NULL"));
                        }