[vala/staging: 3/3] codegen: Only emit notify signals if the value actually changed



commit f1dde0b34ff933d434df851568c7e1a08d7e8aa3
Author: Evan Nemerson <evan coeus-group com>
Date:   Thu Oct 7 01:07:30 2010 -0700

    codegen: Only emit notify signals if the value actually changed
    
    https://bugzilla.gnome.org/show_bug.cgi?id=631267

 codegen/valaccodebasemodule.vala |   53 +++++++++++++++++++++++++++++++++-----
 tests/Makefile.am                |    1 +
 tests/objects/bug631267.vala     |   50 +++++++++++++++++++++++++++++++++++
 3 files changed, 97 insertions(+), 7 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 60fd6bf..f95ecb1 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1788,12 +1788,6 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                ccode.add_assignment (new CCodeIdentifier ("self"), get_cvalue_ 
(transform_value (new GLibValue (base_type, new CCodeIdentifier ("base"), true), this_type, acc)));
                        }
 
-                       acc.body.emit (this);
-
-                       if (current_method_inner_error) {
-                               ccode.add_declaration ("GError *", new CCodeVariableDeclarator.zero 
("_inner_error_", new CCodeConstant ("NULL")));
-                       }
-
                        // notify on property changes
                        if (is_gobject_property (prop) &&
                            get_ccode_notify (prop) &&
@@ -1801,7 +1795,52 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                var notify_call = new CCodeFunctionCall (new CCodeIdentifier 
("g_object_notify"));
                                notify_call.add_argument (new CCodeCastExpression (new CCodeIdentifier 
("self"), "GObject *"));
                                notify_call.add_argument (get_property_canonical_cconstant (prop));
-                               ccode.add_expression (notify_call);
+
+                               var get_accessor = prop.get_accessor;
+                               if (get_accessor != null) {
+                                       var property_type = prop.property_type;
+                                       var get_call = new CCodeFunctionCall (new CCodeIdentifier 
(get_ccode_real_name (get_accessor)));
+                                       get_call.add_argument (new CCodeIdentifier ("self"));
+
+                                       if (property_type is ArrayType) {
+                                               ccode.add_declaration ("int", new CCodeVariableDeclarator 
("old_value_length"));
+                                               get_call.add_argument (new CCodeUnaryExpression 
(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("old_value_length")));
+                                               ccode.open_if (new CCodeBinaryExpression 
(CCodeBinaryOperator.INEQUALITY, get_call, new CCodeIdentifier ("value")));
+                                       } else if (property_type.compatible (string_type)) {
+                                               var ccall = new CCodeFunctionCall (new CCodeIdentifier 
("g_strcmp0"));
+                                               ccall.add_argument (new CCodeIdentifier ("value"));
+                                               ccall.add_argument (get_call);
+                                               ccode.open_if (new CCodeBinaryExpression 
(CCodeBinaryOperator.INEQUALITY, ccall, new CCodeConstant ("0")));
+                                       } else if (property_type is StructValueType) {
+                                               ccode.add_declaration (get_ccode_name (property_type), new 
CCodeVariableDeclarator ("old_value"));
+                                               get_call.add_argument (new CCodeUnaryExpression 
(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("old_value")));
+
+                                               var get_expr = new CCodeCommaExpression ();
+                                               get_expr.append_expression (get_call);
+                                               get_expr.append_expression (new CCodeUnaryExpression 
(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("old_value")));
+
+                                               var equalfunc = generate_struct_equal_function ((Struct) 
property_type.data_type);
+                                               var ccall = new CCodeFunctionCall (new CCodeIdentifier 
(equalfunc));
+                                               ccall.add_argument (new CCodeIdentifier ("value"));
+                                               ccall.add_argument (get_expr);
+                                               ccode.open_if (new CCodeBinaryExpression 
(CCodeBinaryOperator.INEQUALITY, ccall, new CCodeConstant ("TRUE")));
+                                       } else {
+                                               ccode.open_if (new CCodeBinaryExpression 
(CCodeBinaryOperator.INEQUALITY, get_call, new CCodeIdentifier ("value")));
+                                       }
+
+                                       acc.body.emit (this);
+                                       ccode.add_expression (notify_call);
+                                       ccode.close ();
+                               } else {
+                                       acc.body.emit (this);
+                                       ccode.add_statement (notify_call);
+                               }
+                       } else {
+                               acc.body.emit (this);
+                       }
+
+                       if (current_method_inner_error) {
+                               ccode.add_declaration ("GError *", new CCodeVariableDeclarator.zero 
("_inner_error_", new CCodeConstant ("NULL")));
                        }
 
                        cfile.add_function (function);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a9f321c..bc7e104 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -159,6 +159,7 @@ TESTS = \
        objects/bug624594.vala \
        objects/bug626038.vala \
        objects/bug628639.vala \
+       objects/bug631267.vala \
        objects/bug634782.vala \
        objects/bug641418-1.test \
        objects/bug641418-2.test \
diff --git a/tests/objects/bug631267.vala b/tests/objects/bug631267.vala
new file mode 100644
index 0000000..2157f12
--- /dev/null
+++ b/tests/objects/bug631267.vala
@@ -0,0 +1,50 @@
+class FObject : Object {
+}
+
+struct FStruct {
+       public int i;
+}
+
+class Foo : Object {
+       public string s { get; set; }
+       public unowned string[] a { get; set; }
+       public int i { get; set; }
+       public FObject o { get; set; }
+       public FStruct t { get; set; }
+       public void* p { get; set; }
+       
+       public Foo () {
+       }
+}
+
+void main () {
+       var s = "bar";
+       string[] a = { "foo", "baz" };
+       var i = 42;
+       var o = new FObject ();
+       FStruct t = {};
+       void* p = &o;
+       
+       var foo = new Foo ();
+       foo.s = s;
+       foo.a = a;
+       foo.i = i;
+       foo.o = o;
+       foo.t = t;
+       foo.p = p;
+       
+       foo.notify["s"].connect (() => error ("string-type equality failed"));
+       foo.notify["a"].connect (() => error ("array-type equality failed"));
+       foo.notify["i"].connect (() => error ("simple-type equality failed"));
+       foo.notify["o"].connect (() => error ("object-type equality failed"));
+       foo.notify["t"].connect (() => error ("struct-type equality failed"));
+       foo.notify["p"].connect (() => error ("pointer-type equality failed"));
+
+       foo.s = s;
+       foo.a = a;
+       foo.i = i;
+       foo.o = o;
+       foo.t = t;
+       foo.p = p;
+}
+


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