[glibmm] Glib::Binding: Keep a binding alive even without a RefPtr
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm] Glib::Binding: Keep a binding alive even without a RefPtr
- Date: Sun, 15 Dec 2019 14:47:07 +0000 (UTC)
commit dc92d02f4d50851a1af59e5fbe2a753dcfd2e9df
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date: Sun Dec 15 15:43:37 2019 +0100
Glib::Binding: Keep a binding alive even without a RefPtr
A binding between properties can remain even after all RefPtr<Binding>s
are gone. This is similar to how Gtk::Widget::set_controller() works
in gtkmm4.
Fixes #62, see !21
glib/src/binding.ccg | 20 --------------------
glib/src/binding.hg | 18 ++++++------------
tests/glibmm_binding/main.cc | 13 +++++++++----
3 files changed, 15 insertions(+), 36 deletions(-)
---
diff --git a/glib/src/binding.ccg b/glib/src/binding.ccg
index dfad8a66..0c07a07c 100644
--- a/glib/src/binding.ccg
+++ b/glib/src/binding.ccg
@@ -125,24 +125,4 @@ Binding::unbind()
g_binding_unbind(gobj());
}
-// Override unreference() from ObjectBase.
-//
-// Why is this necessary? Because GBinding is an unusual kind of GObject.
-// It calls g_object_unref() itself, if either the source object or the
-// target object is finalized, almost like g_binding_unbind().
-// But the GBinding object shall be destroyed when and only when the last
-// reference from a Glib::RefPtr is dropped.
-void
-Binding::unreference() const
-{
- GBinding* const binding = const_cast<GBinding*>(gobj());
-
- // If the last Glib::RefPtr is being deleted, and the binding has not been unbound,
- // then drop the extra reference that was added by bind_property_value().
- if (gobject_->ref_count == 2 && g_binding_get_source(binding))
- g_object_unref(binding);
-
- Object::unreference();
-}
-
} // namespace Glib
diff --git a/glib/src/binding.hg b/glib/src/binding.hg
index c6849e17..98bc3fc6 100644
--- a/glib/src/binding.hg
+++ b/glib/src/binding.hg
@@ -29,7 +29,7 @@ namespace Glib
/** Bind two object properties.
*
- * Glib::Binding is the representation of a binding between a property on a
+ * %Glib::Binding is the representation of a binding between a property on a
* Glib::ObjectBase instance (or source) and another property on another Glib::ObjectBase
* instance (or target). Whenever the source property changes, the same
* value is applied to the target property; for instance, the following binding:
@@ -90,10 +90,11 @@ namespace Glib
* various ways of blocking a signal emission, like Glib::SignalProxyNormal::emission_stop()
* or g_signal_handler_block().
*
- * A binding will be severed, and the resources it allocates freed, whenever
- * either one of the Glib::ObjectBase instances it refers to is deleted,
- * when unbind() is called, or when the Glib::Binding instance loses
- * its last reference.
+ * The binding between the two properties is broken whenever either one of the
+ * Glib::ObjectBase instances it refers to is deleted or when unbind() is called.
+ * If a RefPtr<Binding> remains after the binding has been broken, get_source()
+ * and get_target() return a <tt>nullptr</tt>. It's not necessary to keep a
+ * RefPtr<Binding> in order to keep the binding alive.
*
* @newin{2,44}
*/
@@ -407,13 +408,6 @@ public:
_WRAP_PROPERTY("target", Glib::RefPtr<Glib::ObjectBase>, newin "2,44")
_WRAP_PROPERTY("target-property", Glib::ustring, newin "2,44")
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
- /** Decrement the reference count for this object.
- * You should never need to do this manually - use the object via a RefPtr instead.
- */
- void unreference() const override;
-#endif /* DOXYGEN_SHOULD_SKIP_THIS */
-
private:
// The functor TransformProp can be implicitly converted to a SlotTransform
// and used in a call to bind_property_value().
diff --git a/tests/glibmm_binding/main.cc b/tests/glibmm_binding/main.cc
index 9b727e51..4d0bacc7 100644
--- a/tests/glibmm_binding/main.cc
+++ b/tests/glibmm_binding/main.cc
@@ -80,11 +80,12 @@ test()
// Ensure no change when invalid source results in false return
source.property_string() = "six six six";
g_assert_cmpint(target.property_int(), ==, 47);
- }
- // Ensure the binding was released when its RefPtr went out of scope
- source.property_string() = "89";
- g_assert_cmpint(target.property_int(), ==, 47);
+ // Ensure the binding is broken when unbind() is called
+ binding->unbind();
+ source.property_string() = "89";
+ g_assert_cmpint(target.property_int(), ==, 47);
+ }
{
auto binding = Glib::Binding::bind_property(
@@ -94,6 +95,10 @@ test()
// With SYNC_CREATE, value of source must sync to target on bind
g_assert_cmpint(target.property_int(), ==, 89);
}
+
+ // Ensure the binding was not broken when its RefPtr went out of scope
+ source.property_string() = "90";
+ g_assert_cmpint(target.property_int(), ==, 90);
}
} // namespace
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]