From: Evan Nemerson Date: Thu, 7 Oct 2010 08:07:30 +0000 (-0700) Subject: codegen: Only emit notify signals if the value actually changed X-Git-Tag: 0.35.1~72 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=64b9bfc1bc0abfed45ad07a8ebaef8a5f167f848;p=thirdparty%2Fvala.git codegen: Only emit notify signals if the value actually changed https://bugzilla.gnome.org/show_bug.cgi?id=631267 --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 60fd6bf6f..dbacd3cbb 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_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); diff --git a/tests/Makefile.am b/tests/Makefile.am index a9f321cc4..bc7e104de 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 000000000..c9576c2cc --- /dev/null +++ b/tests/objects/bug631267.vala @@ -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; +} +