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 622278 - g_object_bind_property_full() is not introspection/binding friendly
g_object_bind_property_full() is not introspection/binding friendly
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gobject
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2010-06-21 11:12 UTC by Emmanuele Bassi (:ebassi)
Modified: 2010-08-03 11:41 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
binding: Rename _full to _transform_with_data() (18.00 KB, patch)
2010-06-21 11:12 UTC, Emmanuele Bassi (:ebassi)
none Details | Review
binding: Add a closure-based variant of bind_property_full() (15.20 KB, patch)
2010-07-13 05:08 UTC, Emmanuele Bassi (:ebassi)
committed Details | Review

Description Emmanuele Bassi (:ebassi) 2010-06-21 11:12:36 UTC
as it turns out, passing a single user_data,notify pair for two functions does not make the introspection and language bindings people happy.

one way to solve this issue is to make the _full() variant take two (func, data, notify) triplets, which would solve most of our problems, though it would make the function call, at a whopping 11 arguments, a bit unwieldy from the C developer perspective:

  GBinding *
  g_object_bind_property_full (source, source_property,
                               target, target_property,
                               flags,
                               transform_to, data1, notify1,
                               transform_from, data2, notify2);

so, the proposal is to rename the function to be:

  GBinding *
  g_object_bind_property_transform_with_data (source, source_property,
                                              target, target_property,
                                              flags,
                                              transform_to, data1, notify1,
                                              transform_from, data2, notify2);

and have a C convenience function that only takes the transformation functions:

  GBinding *
  g_object_bind_property_transform (source, source_property,
                                    target, target_property,
                                    flags,
                                    transform_to,
                                    transform_from);

on the rationale that C developers will probably only need to pass transformation functions and handle the memory themselves.
Comment 1 Emmanuele Bassi (:ebassi) 2010-06-21 11:12:53 UTC
Created attachment 164208 [details] [review]
binding: Rename _full to _transform_with_data()

Using a single DestroyNotify and user data for two functions confuses
both static and introspection generated bindings, and makes the memory
management of the closure data fuzzy.

We should use two (func, data, notify) triplets, one for each
transformation function - though this means making the _full() variant
of g_object_bind_property() a bit unwieldy for the C developer, with
11 arguments.

A way out is to have a C convenience function called:

  g_object_bind_property_transform()

and make the g_object_bind_property_full() a variant of _transform() and
rename it:

  g_object_bind_property_transform_with_data()

Mostly only for language bindings.
Comment 2 Christian Persch 2010-06-21 13:06:32 UTC
I think that makes these very inconvenient to use from C. I want to pass user data to the transform funcs, but the same user data for both directions. So I have to use the variant with the 2 destroy notify's, and thus create the same data twice (usually it's an allocated struct; or I need to introduce refcounting for my ad-hoc data struct... both alternatives suck).

(Also I think the alleged 'problem' is a misunderstanding on the part of the binding developers (or a limitation in the binding itself). It's simply that the (user data, destroy notify) pair is bound to the lifetime of the GBinding*, *not* the callbacks.)
Comment 3 Emmanuele Bassi (:ebassi) 2010-06-21 13:32:14 UTC
(In reply to comment #2)

> (Also I think the alleged 'problem' is a misunderstanding on the part of the
> binding developers (or a limitation in the binding itself). It's simply that
> the (user data, destroy notify) pair is bound to the lifetime of the GBinding*,
> *not* the callbacks.)

encoding this behaviour in the annotations is not trivial.
Comment 4 Emmanuele Bassi (:ebassi) 2010-06-21 13:33:37 UTC
[damn, bugzilla ate the rest of the comment...]

in any case, if we can find a way to express this in the language bindings then I'll be happy to close this as RESOLVED WONTFIX.
Comment 5 Emmanuele Bassi (:ebassi) 2010-07-13 05:08:16 UTC
after much prodding and deliberation, here's a GClosure-based implementation bolted on top of g_object_bind_property_full(), to preserve the "free once" semantics. there is a fair amount of GValue copying going on - which I'm afraid is unavoidable; also, the marshaller will have to be hand-written anyway. finally, language bindings will have to write their own conversion functions to transform GValues into native objects - though all language bindings already have this kind of code internally.
Comment 6 Emmanuele Bassi (:ebassi) 2010-07-13 05:08:39 UTC
Created attachment 165773 [details] [review]
binding: Add a closure-based variant of bind_property_full()

Since using the function pointer version muddles the memory management
requirements of language bindings, we should implement a GClosure-based
variant on top of g_object_bind_property_full().
Comment 7 Emmanuele Bassi (:ebassi) 2010-08-03 11:41:09 UTC
Attachment 165773 [details] pushed as 3be3ad6 - binding: Add a closure-based variant of bind_property_full()