After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 348080 - GObject property bindings like in libexo
GObject property bindings like in libexo
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gobject
2.23.x
Other All
: Normal enhancement
: ---
Assigned To: gtkdev
gtkdev
: 679254 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2006-07-20 03:31 UTC by Michael Lawrence
Modified: 2012-07-02 12:25 UTC
See Also:
GNOME target: ---
GNOME version: Unversioned Enhancement


Attachments
Initial attempt (30.09 KB, patch)
2008-05-27 03:44 UTC, A. Walton
none Details | Review
ugh. (29.92 KB, patch)
2008-05-27 04:09 UTC, A. Walton
none Details | Review
Add GBinding (34.62 KB, patch)
2010-06-02 23:00 UTC, Emmanuele Bassi (:ebassi)
none Details | Review
Add GBinding (45.60 KB, patch)
2010-06-03 16:37 UTC, Emmanuele Bassi (:ebassi)
none Details | Review
Add GBinding (43.79 KB, patch)
2010-06-03 17:35 UTC, Emmanuele Bassi (:ebassi)
none Details | Review
gobject: Add GBinding (48.30 KB, patch)
2010-06-04 15:19 UTC, Emmanuele Bassi (:ebassi)
none Details | Review
gobject: Add GBinding (50.05 KB, patch)
2010-06-09 13:29 UTC, Emmanuele Bassi (:ebassi)
committed Details | Review

Description Michael Lawrence 2006-07-20 03:31:34 UTC
I think that the API for binding properties between GObjects (as demonstrated by libexo, see http://os-cillation.com/documentation/api/libexo/0.3/exo-Binding-Properties-Functions.html) is of enough general utility to warrant inclusion in GObject itself.
Comment 1 Stefan Sauer (gstreamer, gtkdoc dev) 2008-03-29 08:51:18 UTC
I would also find this useful. Obvious examples:
GtkToggleButton::active -> GtkWidget::sensitive
GtkToggleButton::active -> GtkWidget::visible
Comment 2 Paul Pogonyshev 2008-03-30 18:42:04 UTC
I have a library that implements the same idea in a more generic way, but in Python: http://home.gna.org/py-notify/.  However, I'm not sure how that (or a subset of that) is possible to rewrite in C, so it is just a pointer for consideration.
Comment 3 Sven Herzberg 2008-03-31 11:15:34 UTC
PyNotify to mee looks more like a general signal implementation; not related to property-binding...
Comment 4 Bastien Nocera 2008-03-31 18:39:27 UTC
Would probably need a number of helper functions to go with it, such as the gboolean negation:
http://os-cillation.com/documentation/api/libexo/0.3/exo-Extensions-to-GObject.html
Or string <=> enum member conversions.
Comment 5 Havoc Pennington 2008-04-01 17:26:44 UTC
Ryan Lortie has a related thingy in dconf (to bind properties to config settings), don't know if it would really tie into this though.
Comment 6 A. Walton 2008-05-27 03:44:42 UTC
Created attachment 111576 [details] [review]
Initial attempt

Pretty straightforward port of ExoBinding from libexo to glib, added a few sanity checks and some more documentation (that could use a review...) Dropped the _negation() code so we can discuss where the best place to put the value transform code is (g_value_SPECIAL_transform()/g_value_transform_SPECIAL() just doesn't seem as appealing to me for some reason) and what value transform functions we need in GLib, etc. However, the functionality is still great even without these functions.

Six new symbols in the g_object namespace, one new type:
g_object_bind(), _bind_full(), _unbind(), _mutual_bind(), _mutual_bind_full(), _mutual_unbind(), GObjectBindingTransform (type seems a bit wordy though, maybe GBindingTransform? not great with names...) I'd be happy to change the namespace and naming of these though I'd like to keep the function names short and concise like g_object_bind().

TODO: add some plain GObject test cases; they're fun and easy to make using Gtk+ and Clutter, but having some simple regression tests would be best.
Comment 7 A. Walton 2008-05-27 04:09:10 UTC
Created attachment 111577 [details] [review]
ugh.

(Remove some accidental copy & paste in the documentation from the example code. Sad the things you notice after you hit submit. Considering the sentences before it, it's enough irony for everyone...)
Comment 8 Matthew Barnes 2008-11-16 10:56:11 UTC
Just piling on a testimonial here...

I recently learned of ExoBinding myself and have copied it into a private Evolution branch I'm working on.  A binding API in combination with something like GConfBridge and... wow.  Makes wiring up a complex properties dialog a cinch.  Nice and clean.  GObject would really benefit from this.
Comment 9 Stefan Sauer (gstreamer, gtkdoc dev) 2009-02-20 11:53:17 UTC
I was discussing the approach with Tim Janik a few days ago. One of his concerns was the use of g_signal_handler_block() in g_object_bind_properties_notify(). If should probably ignore such a notify.

Blocking could cause issues in this example:
assume a mvc example with modell m, a slider as a view v1 and an entry field as v2. The model constrains the value range to 0..100.
v2.set(105)
v2.notity(m,v1)
m.set(100)
m.notify(v1,v2)

v2 should not block the "value-changed" on m. I needs to ignore the value-changed, if it is the reply to the own notify.


If there are tests some day, they should cover circular chains as well:
objects a,b,c
bind [a,b],[b,c],[c,a]
set a
,,,
assert a==b==c
Comment 10 Stef Walter 2009-03-02 16:11:04 UTC
We've implemented something similar in seahorse. It also has the concept of 'transforms' where you can hook in a transformation between the value of one property to a value acceptable by the other. 
Comment 11 Bastien Nocera 2009-09-25 16:14:11 UTC
Comment on attachment 111577 [details] [review]
ugh.

Apologies, git bz made me do it.
Comment 12 Emmanuele Bassi (:ebassi) 2010-06-02 23:00:49 UTC
Created attachment 162585 [details] [review]
Add GBinding

GBinding is a simple, opaque object that represents a binding between a
property on a GObject instance (source) and property on another GObject
instance (target).
Comment 13 Emmanuele Bassi (:ebassi) 2010-06-02 23:04:40 UTC
my take on the binding API. this is a simple implementation that covers:

  • uni-directional bindings
  • bi-directional bindings
  • custom transformation functions

the g_object_bind_property_full() function is a bit nasty for introspection-based bindings because it uses a single user data and GDestroyNotify with two callbacks; while it makes perfect sense from a C API user standpoint, it should have a variant using two GClosures as well (it would help for non-introspection-based languages as well).

the patch is against GIO 2.25. it only needs a test unit for the GIO test suite.
Comment 14 Emmanuele Bassi (:ebassi) 2010-06-02 23:12:36 UTC
as an addendum to the straight port of ExoBinding in attachment 111577 [details] [review] (which I explicitly avoided to look at while implementing the patch):

  • GBinding does not require an explicit unbind: the binding will be undone under three circumstances: 1. the source goes away; 2. the target goes away; 3. the GBinding instance goes away.

  • the bidirectional binding is handled by a flag instead of a separate function.

  • it is possible to query the GBinding instance itself - though not strictly necessary.

  • the notify signal is not blocked: a simple guard is used to avoid loops.

  • the GBinding instance is stored inside the source and target GObject instances, to minimize bookkeeping.
Comment 15 Danielle Madeley 2010-06-03 00:11:15 UTC
(In reply to comment #13)

> the g_object_bind_property_full() function is a bit nasty for
> introspection-based bindings because it uses a single user data and
> GDestroyNotify with two callbacks; while it makes perfect sense from a C API
> user standpoint, it should have a variant using two GClosures as well (it would
> help for non-introspection-based languages as well).

GDBus already has one of these (two callbacks, one destroy-notify).
Comment 16 Emmanuele Bassi (:ebassi) 2010-06-03 10:06:19 UTC
(In reply to comment #15)
> (In reply to comment #13)
> 
> > the g_object_bind_property_full() function is a bit nasty for
> > introspection-based bindings because it uses a single user data and
> > GDestroyNotify with two callbacks; while it makes perfect sense from a C API
> > user standpoint, it should have a variant using two GClosures as well (it would
> > help for non-introspection-based languages as well).
> 
> GDBus already has one of these (two callbacks, one destroy-notify).

yes, and I've asked on #introspection and it turns out that it's a pain; see also the thread on gtk-devel-list:

http://mail.gnome.org/archives/gtk-devel-list/2010-May/msg00136.html
Comment 17 Vincent Untz 2010-06-03 10:20:02 UTC
Just want to point out that we probably want to make this and g_settings_bind() stuff work in a similar way. Sure, they don't do the same thing, but I expect people will link them together in their mind.

Quickly looking at the patch and at the GSettings API:

 - we might want to choose one term between transform and map
 - GSettings uses GET/SET while GBinding uses BIDIRECTIONAL
Comment 18 Emmanuele Bassi (:ebassi) 2010-06-03 11:30:30 UTC
(In reply to comment #17)
> Just want to point out that we probably want to make this and g_settings_bind()
> stuff work in a similar way. Sure, they don't do the same thing, but I expect
> people will link them together in their mind.

I understand the point, though I really believe that the two should not be confused. prolly the documentation should be *much* clearer about it.

> Quickly looking at the patch and at the GSettings API:
> 
>  - we might want to choose one term between transform and map

Transform is used by GValue already; I would have preferred Ryan went with Transform as well, but I don't get to complain after the API has been frozen, so I can change to Map.

>  - GSettings uses GET/SET while GBinding uses BIDIRECTIONAL

here's where it falls apart. there is no point in having the same granularity as GSettings: you're either using a uni-directional binding or a bi-directional one. otherwise it wouldn't be a binding.
Comment 19 Vincent Untz 2010-06-03 11:37:21 UTC
(In reply to comment #18)
> (In reply to comment #17)
> >  - we might want to choose one term between transform and map
> 
> Transform is used by GValue already; I would have preferred Ryan went with
> Transform as well, but I don't get to complain after the API has been frozen,
> so I can change to Map.

Well, it's not too late to change this in GSettings, I guess. But maybe Ryan had a good reason for this?
Comment 20 Allison Karlitskaya (desrt) 2010-06-03 12:59:16 UTC
there's one major difference here and it might justify a difference in terms:

  - 'transform' converts GValue <-> GValue
  - 'map' converts GVariant <-> GValue
Comment 21 Emmanuele Bassi (:ebassi) 2010-06-03 13:19:07 UTC
(In reply to comment #20)
> there's one major difference here and it might justify a difference in terms:
> 
>   - 'transform' converts GValue <-> GValue
>   - 'map' converts GVariant <-> GValue

that teaches me to look at the API before making a point. :-)
Comment 22 Emmanuele Bassi (:ebassi) 2010-06-03 15:12:14 UTC
if we want GBindingFlags to be similar to GSettingsBindFlags then they should probably be:

  enum {
    G_BINDING_DEFAULT = 0, /* unidirectional */

    G_BINDING_BIDIRECTIONAL = 1 << 0
  }

unless we want to match GSetting's default behaviour, in which case:

  enum {
    G_BINDING_DEFAULT = 0, /* bidirectional */

    G_BINDING_GET     = 1 << 0, /* unidirectional, from source to target */
    G_BINDING_SET     = 1 << 1, /* unidirectional, from target to source */
  }

but it would be frankly quite odd: an object binding is essentially symmetric - binding ObjectA:property-a to ObjectB:property-b with SET is idempotent to binding ObjectB:property-b to ObjectA:property-a with GET. that's the main difference between GSettings binding and GObject binding: a setting key is not an object property, so there is not symmetry - that is, you cannot swap the arguments of g_settings_bind() around.
Comment 23 Emmanuele Bassi (:ebassi) 2010-06-03 16:37:52 UTC
Created attachment 162669 [details] [review]
Add GBinding

GBinding is a simple, opaque object that represents a binding between a
property on a GObject instance (source) and property on another GObject
instance (target).
Comment 24 Emmanuele Bassi (:ebassi) 2010-06-03 16:40:36 UTC
new version of the GBinding patch:

  • renamed G_BINDING_FLAGS_NONE to G_BINDING_DEFAULT;
  • fixed some dumb thinkos that actually prevented the whole shebang to work *blush*;
  • added a test suite, checking default binding, lifetime tracking and transformation functions;
Comment 25 Emmanuele Bassi (:ebassi) 2010-06-03 17:04:24 UTC
one final API change could be removing the GObject and GParamSpec arguments from the GBindingTransformFunc, and just keep the GValues:

  gboolean (* GBindingTransformFunc) (GBinding     *binding,
                                      const GValue *source_value,
                                      GValue       *target_value,
                                      gpointer      user_data);

rationales:

  • simplifies the function signature and use;
  • the two GObject arguments can be retrieved from GBinding itself;
  • same goes for the two GParamSpec arguments;
  • validation against GParamSpec is done internally by the GBinding.
Comment 26 Emmanuele Bassi (:ebassi) 2010-06-03 17:35:25 UTC
Created attachment 162677 [details] [review]
Add GBinding

GBinding is a simple, opaque object that represents a binding between a
property on a GObject instance (source) and property on another GObject
instance (target).
Comment 27 Stefan Sauer (gstreamer, gtkdoc dev) 2010-06-03 20:36:49 UTC
Review of attachment 162677 [details] [review]:

When I read GBinding I would think more of language bindings or something like that. What about GLink, GValueLink, GPropertyLink.
Also why is this in go and not gobject?

Otherwise, very nice!

::: gio/gbinding.c
@@ +29,3 @@
+ * #GObject instance (or source) and another property on another #GObject
+ * instance (or target). Whenever the source property changes, the same
+ * value is applied to the target property.

Maybe rephrase:
"GBinding is the representation of a binding between two #GObject properties (source and target).
Whenever the source property changes, the target property is updated."

Does it make sense to bind two properties on *one* object?

::: gio/gbinding.h
@@ +78,3 @@
+ * g_object_bind_property_full().
+ *
+ * This enumeration can be extended at later date.

Isn't this true for many flags :) ?
Comment 28 Emmanuele Bassi (:ebassi) 2010-06-03 22:04:20 UTC
(In reply to comment #27)
> Review of attachment 162677 [details] [review]:
> 
> When I read GBinding I would think more of language bindings or something like
> that. What about GLink, GValueLink, GPropertyLink.

any time I read "link" I think "oh, a URL" :-)

I'm not overly attached to the name - and in theory you shouldn't be using a GBinding instance, given the automatic binding management.

> Also why is this in go and not gobject?

I don't mind GObject, but the pattern until now is to have only the basic type system in gobject, and all the utility in GIO.

> Otherwise, very nice!

thanks.

> ::: gio/gbinding.c
> @@ +29,3 @@
> + * #GObject instance (or source) and another property on another #GObject
> + * instance (or target). Whenever the source property changes, the same
> + * value is applied to the target property.
> 
> Maybe rephrase:
> "GBinding is the representation of a binding between two #GObject properties
> (source and target).
> Whenever the source property changes, the target property is updated."
> 
> Does it make sense to bind two properties on *one* object?

in theory, yes; third party code could link two properties with a transformation without requiring changes in the class itself or, worse, a sub-class.

> ::: gio/gbinding.h
> @@ +78,3 @@
> + * g_object_bind_property_full().
> + *
> + * This enumeration can be extended at later date.
> 
> Isn't this true for many flags :) ?

true - but being explicit doesn't hurt. :-)
Comment 29 Bastien Nocera 2010-06-03 22:34:57 UTC
(In reply to comment #28)
<snip>
> > Also why is this in go and not gobject?
> 
> I don't mind GObject, but the pattern until now is to have only the basic type
> system in gobject, and all the utility in GIO.

I'd have expected, you know, I/O stuff in GIO, not random GObject helpers.
Comment 30 A. Walton 2010-06-03 22:49:05 UTC
(In reply to comment #29)
> I'd have expected, you know, I/O stuff in GIO

That fell apart when GSettings was merged and when GApplication eventually gets merged. But it's probably more sensible than spawning yet another library "libgappkit".

OTOH, I still agree that this should be in libgobject. It's very tightly related to GObject and belongs with it.
Comment 31 Emmanuele Bassi (:ebassi) 2010-06-04 09:19:16 UTC
(In reply to comment #30)

> OTOH, I still agree that this should be in libgobject. It's very tightly
> related to GObject and belongs with it.

it's really not tightly integrated at all: I didn't have to use any internal data structure, just public API.

also, moving it to GObject would mean adding the enumeration types machinery under gobject/ just for GBindingFlags.

honestly, since gio is compiled inside the libglib shared object I see no point in pushing GBinding inside gobject/, since it's not using internal API at all.
Comment 32 Milan Bouchet-Valat 2010-06-04 09:40:02 UTC
(In reply to comment #31)
> it's really not tightly integrated at all: I didn't have to use any internal
> data structure, just public API.
At least it's *logically* very integrated. g_object_bind_property() could be seen as an internal feature of GObjects, from the user POV.

> also, moving it to GObject would mean adding the enumeration types machinery
> under gobject/ just for GBindingFlags.
> 
> honestly, since gio is compiled inside the libglib shared object I see no point
> in pushing GBinding inside gobject/, since it's not using internal API at all.
IMHO it makes more sense to put this into GObject, since people not using GIO might still want to use this simple feature. I guess the criteria is to keep GObject relatively lightweight and well-identified around the type system, which I think could include GBinding. I'm sure there are apps out there that don't link to GIO and might use it.

That said, the effective consequences of this choice are very small. It's more about logical consistence of the API and libraries roles. So if you think it's not worth adding enumerations support...
Comment 33 A. Walton 2010-06-04 11:48:04 UTC
(In reply to comment #31) 
> it's really not tightly integrated at all: I didn't have to use any internal
> data structure, just public API.

I did say 'related', not integrated. It's basically extending GObject, so you'd think that'd be part of GObject's implementation, not off in wonderland.

But I don't think it's worth arguing the point if it keeps this out of glib any longer. I'd rather see it merged than argue where it should be.
Comment 34 Stefan Sauer (gstreamer, gtkdoc dev) 2010-06-04 12:04:52 UTC
I see the point regading the binaries, but also to me GIO is I/O and as a developers I would look for the feature in the GObject docs and not in the GIO docs.
Comment 35 Matthias Clasen 2010-06-04 12:58:00 UTC
> also, moving it to GObject would mean adding the enumeration types machinery
> under gobject/ just for GBindingFlags.

That seems like a weak reason for putting this into GIO.  I'm with the 'this fits better in gobject' camp here. While it is true that GIO has accumulated some non-IO stuff (like ginitable), this binding stuff really has no relation to anything in gio and isn't even used anywhere in gio.

What I have been missing in the docs is some discussion about the possibility of cycles, and how gbinding handles them (or doesn't handle them).
Comment 36 Matthew Barnes 2010-06-04 13:04:42 UTC
(In reply to comment #35)
> What I have been missing in the docs is some discussion about the possibility
> of cycles, and how gbinding handles them (or doesn't handle them).

Evolution has been using its own version of ExoBinding for over a year now and I've found it's mostly up to the set() functions to break cycles: don't emit "notify" unless the value has really changed.  Not a foolproof solution but works for most cases.

BTW, I'm delighted to see this finally moving again.  Thanks Emmanuele!
Comment 37 Emmanuele Bassi (:ebassi) 2010-06-04 13:52:49 UTC
(In reply to comment #35)
> > also, moving it to GObject would mean adding the enumeration types machinery
> > under gobject/ just for GBindingFlags.
> 
> That seems like a weak reason for putting this into GIO.

it wasn't meant as a reason, but just something I noted while doing the gio → gobject move in my local repository.

>  I'm with the 'this
> fits better in gobject' camp here. While it is true that GIO has accumulated
> some non-IO stuff (like ginitable), this binding stuff really has no relation
> to anything in gio and isn't even used anywhere in gio.

then, as I asked on IRC, I'd really like to get some more documentation (a FAQ entry, perhaps, or a wiki page) on where to put GObject extensions, like (in this case) GBinding or the GController API outlined in bug 620569. not a specific rule, but at least a set of guidelines. moving stuff around is not incredibly fun, especially when it starts encompassing multiple files (unlike GBinding).

> What I have been missing in the docs is some discussion about the possibility
> of cycles, and how gbinding handles them (or doesn't handle them).

cycles as in:

  g_object_bind_property (object_a, property_a, object_b, property_b, 0);
  g_object_bind_property (object_b, property_b, object_a, property_a, 0);

are not detected - though they should not be necessary in the first place since we have the BIDIRECTIONAL flag.

the common behaviour for modifier methods is, like Matthew wrote in comment 36, to not emit ::notify unless the value really changed. it could be possible to check, when setting up the binding, both in the object_a and object_b instances whether there exists a binding between the two properties already, and return the existing binding instance.
Comment 38 Matthias Clasen 2010-06-04 14:23:10 UTC
> g_object_bind_property (object_a, property_a, object_b, property_b, 0);
> g_object_bind_property (object_b, property_b, object_a, property_a, 0);

That case is obviously not interesting. I was more interested in

obj1::a -> obj2::b -> obj3::c --> obj1::a

with maybe some connections not via explicit binding, but just because properties are not independent.
Now, in general, it is very hard to prevent such things from happening, but I just think that the docs need to at least discuss the general topic a bit.

Another fun twist is that bindings themselves are objects, so you can probably have some extra fun by binding properties of other bindings...
Comment 39 Emmanuele Bassi (:ebassi) 2010-06-04 14:32:58 UTC
(In reply to comment #38)
> > g_object_bind_property (object_a, property_a, object_b, property_b, 0);
> > g_object_bind_property (object_b, property_b, object_a, property_a, 0);
> 
> That case is obviously not interesting. I was more interested in
> 
> obj1::a -> obj2::b -> obj3::c --> obj1::a
> 
> with maybe some connections not via explicit binding, but just because
> properties are not independent.
> Now, in general, it is very hard to prevent such things from happening, but I
> just think that the docs need to at least discuss the general topic a bit.

completely agree.

> Another fun twist is that bindings themselves are objects, so you can probably
> have some extra fun by binding properties of other bindings...

well, the binding object's properties are construct-only, and you cannot sub-class them, but I see the point. :-)
Comment 40 Emmanuele Bassi (:ebassi) 2010-06-04 15:19:03 UTC
Created attachment 162760 [details] [review]
gobject: Add GBinding

GBinding is a simple, opaque object that represents a binding between a
property on a GObject instance (source) and property on another GObject
instance (target).
Comment 41 Emmanuele Bassi (:ebassi) 2010-06-04 15:21:31 UTC
GBinding patch, take 4:

• moved to gobject/

• added more documentation (with examples), mentioning cycles and the fact that the binding is susceptible to blocking the GObject::notify signal.
Comment 42 Allison Karlitskaya (desrt) 2010-06-04 19:08:01 UTC
(In reply to comment #35)
> What I have been missing in the docs is some discussion about the possibility
> of cycles, and how gbinding handles them (or doesn't handle them).

fwiw, GSettings deals with this case by having a bool in the binding structure for if we are currently actively modifying the property or setting.  If so, and we see another callback (either from GObject notify or GSettings change) then we just ignore it.

This approach is possibly applicable here and it might be a better idea than just relying on set() not to notify if there is no change.  This could get particularly hairy when transforms are involved, for example.
Comment 43 Emmanuele Bassi (:ebassi) 2010-06-05 23:02:54 UTC
(In reply to comment #42)
> (In reply to comment #35)
> > What I have been missing in the docs is some discussion about the possibility
> > of cycles, and how gbinding handles them (or doesn't handle them).
> 
> fwiw, GSettings deals with this case by having a bool in the binding structure
> for if we are currently actively modifying the property or setting.

the same happens in GBinding, with the is_frozen guard.
Comment 44 Nick Schermer 2010-06-09 06:12:19 UTC
Some comments/questions about the patch:

- What is exactly the purpose of maintaining the bindings_qdata? Doesn't seems to be used somewhere right now.
- 'available since GIO 2.26' doesn't apply anymore.
- g_binding_flags_get_type is defined in __G_BINDING_H__, not in __G_ENUM_TYPES_H__ in gobject.symbols.
- The other flag g_*_flags_get_type lines in gobject.symbols have nothing to do with this patch right? Maybe move it to a separate patch.

That said, I'm glad something like ExoBinding finally lands in glib.
Comment 45 Emmanuele Bassi (:ebassi) 2010-06-09 11:27:40 UTC
(In reply to comment #44)
> Some comments/questions about the patch:
> 
> - What is exactly the purpose of maintaining the bindings_qdata? Doesn't seems
> to be used somewhere right now.

cannot parse this sentence.

the binding instance is added, through the instance data, to the two objects it's binding, to allow automatic bookkeeping.

> - 'available since GIO 2.26' doesn't apply anymore.

yup, fixed.

> - g_binding_flags_get_type is defined in __G_BINDING_H__, not in
> __G_ENUM_TYPES_H__ in gobject.symbols.
> - The other flag g_*_flags_get_type lines in gobject.symbols have nothing to do
> with this patch right? Maybe move it to a separate patch.

they were just random noise that I forgot to unstage when trying to the automatic enumeration types generation in gobject - which is not possible, since we have a collision with GParamFlags and GParamSpecFlags over the get_type() function.
Comment 46 Nick Schermer 2010-06-09 13:17:00 UTC
(In reply to comment #45)
> (In reply to comment #44)
> > Some comments/questions about the patch:
> > 
> > - What is exactly the purpose of maintaining the bindings_qdata? Doesn't seems
> > to be used somewhere right now.
> 
> cannot parse this sentence.
> 
> the binding instance is added, through the instance data, to the two objects
> it's binding, to allow automatic bookkeeping.

I mean you maintain a list of all the bindings on both the source and target GObjects (add_binding_qdata(), remove_binding_qdata() and parts of weak_unbind()), but it is not used in the code (to lookup a binding or return a list of bindings on an object), just the binding is added and removed. Seems a bit useless to me.
Only purpose I can think of is getting the list with g_object_get_data(object, "g-binding"); to see what bindings are connected to an object, but does one really care?
Comment 47 Emmanuele Bassi (:ebassi) 2010-06-09 13:29:17 UTC
Created attachment 163198 [details] [review]
gobject: Add GBinding

GBinding is a simple, opaque object that represents a binding between a
property on a GObject instance (source) and property on another GObject
instance (target).
Comment 48 Emmanuele Bassi (:ebassi) 2010-06-09 13:33:33 UTC
(In reply to comment #46)
> (In reply to comment #45)
> > (In reply to comment #44)
> > > Some comments/questions about the patch:
> > > 
> > > - What is exactly the purpose of maintaining the bindings_qdata? Doesn't seems
> > > to be used somewhere right now.
> > 
> > cannot parse this sentence.
> > 
> > the binding instance is added, through the instance data, to the two objects
> > it's binding, to allow automatic bookkeeping.
> 
> I mean you maintain a list of all the bindings on both the source and target
> GObjects (add_binding_qdata(), remove_binding_qdata() and parts of
> weak_unbind()), but it is not used in the code (to lookup a binding or return a
> list of bindings on an object), just the binding is added and removed. Seems a
> bit useless to me.

the binding is there so that you don't have to store it, and so that when either one of the bound objects are finalized, the binding itself is unreferenced. since you cannot know which one of the objects bound will go away first you need to keep a reference on both ends of the binding - and destroy the other one accordingly.
Comment 49 Emmanuele Bassi (:ebassi) 2010-06-15 15:11:21 UTC
Attachment 163198 [details] pushed as 6d1d9cf - gobject: Add GBinding
Comment 50 Emmanuele Bassi (:ebassi) 2012-07-02 12:25:27 UTC
*** Bug 679254 has been marked as a duplicate of this bug. ***