]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Only emit notify signals if the value actually changed
authorEvan Nemerson <evan@coeus-group.com>
Thu, 7 Oct 2010 08:07:30 +0000 (01:07 -0700)
committerRico Tzschichholz <ricotz@ubuntu.com>
Tue, 25 Oct 2016 09:13:10 +0000 (11:13 +0200)
https://bugzilla.gnome.org/show_bug.cgi?id=631267

codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/objects/bug631267.vala [new file with mode: 0644]

index 60fd6bf6fea784380e17eddcd31bb2a47cc31402..dbacd3cbb8a1581ed215888c8da3a84369ed4094 100644 (file)
@@ -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_expression (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);
index a9f321cc4dc65b00455d25814e4284fc262dc6f8..bc7e104de8cbdd349de212e545942f84f732a1e5 100644 (file)
@@ -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 (file)
index 0000000..c9576c2
--- /dev/null
@@ -0,0 +1,53 @@
+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 int foo { get { return i; } }
+       public int bar { set { i = value; } }
+
+       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;
+}
+