[ease/bindings] [bindings] Improved signal handling and dropping
- From: Nate Stedman <natesm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ease/bindings] [bindings] Improved signal handling and dropping
- Date: Sat, 21 Aug 2010 00:52:23 +0000 (UTC)
commit 72b35ce25c56c71ad815e3652f506caab15e56d4
Author: Nate Stedman <natesm gmail com>
Date: Fri Aug 20 20:51:18 2010 -0400
[bindings] Improved signal handling and dropping
- Signals are never connected more than once
- Signals are automatically disconnected when they no longer apply
- drop_if function allowing a callback for conditional dropping
- All other drop functions now use drop_if behind the scenes
ease-bindings/bindings.vala | 95 +++++++++++++++++++++++++++++--------------
1 files changed, 64 insertions(+), 31 deletions(-)
---
diff --git a/ease-bindings/bindings.vala b/ease-bindings/bindings.vala
index 3593102..08ee9e5 100644
--- a/ease-bindings/bindings.vala
+++ b/ease-bindings/bindings.vala
@@ -28,8 +28,7 @@ namespace Bindings
GLib.Object object2, string property2)
{
// connect signal handlers
- object1.notify[property1].connect(on_notify);
- object2.notify[property1].connect(on_notify);
+ connect_signals(object1, property1, object2, property2);
// keep track of the binding
bindings().add(new Binding(object1, property1, object2, property2));
@@ -42,51 +41,58 @@ namespace Bindings
public void drop(GLib.Object object1, string property1,
GLib.Object object2, string property2)
{
- if (bindings().size < 1) return;
-
- var itr = bindings().iterator();
- for (itr.first();; itr.next())
- {
- var binding = itr.get() as Binding;
- if ((binding.obj1 == object1 && binding.prop1 == property1 &&
- binding.obj2 == object2 && binding.prop2 == property2) ||
- (binding.obj2 == object1 && binding.prop2 == property1 &&
- binding.obj1 == object2 && binding.prop1 == property2))
- {
- itr.remove();
- }
- if (!itr.has_next()) break;
- }
+ drop_if((obj1, prop1, obj2, prop2) => {
+ return ((obj1 == object1 && prop1 == property1 &&
+ obj2 == object2 && prop2 == property2) ||
+ (obj2 == object1 && prop2 == property1 &&
+ obj1 == object2 && prop1 == property2));
+ });
}
public void drop_object(GLib.Object object)
{
- if (bindings().size < 1) return;
-
- var itr = bindings().iterator();
- for (itr.first();; itr.next())
- {
- var binding = itr.get() as Binding;
- if (binding.obj1 == object || binding.obj2 == object)
- {
- itr.remove();
- }
- if (!itr.has_next()) break;
- }
+ drop_if((obj1, prop1, obj2, prop2) => {
+ return (obj1 == object || obj2 == object);
+ });
}
public void drop_property(GLib.Object object, string property)
{
+ drop_if((obj1, prop1, obj2, prop2) => {
+ return ((obj1 == object && prop1 == property) ||
+ (obj2 == object && prop2 == property));
+ });
+ }
+
+ public void drop_if(DropFunction function)
+ {
if (bindings().size < 1) return;
var itr = bindings().iterator();
for (itr.first();; itr.next())
{
var binding = itr.get() as Binding;
- if ((binding.obj1 == object && binding.prop1 == property) ||
- (binding.obj2 == object && binding.prop2 == property))
+ weak GLib.Object object1 = binding.obj1, object2 = binding.obj2;
+ weak string prop1 = binding.prop1, prop2 = binding.prop2;
+ if (function(binding.obj1, binding.prop1,
+ binding.obj2, binding.prop2))
{
itr.remove();
+ bool has1 = false, has2 = false;
+ foreach (var b in bindings())
+ {
+ if (b.obj1 == object1 || b.obj2 == object1)
+ {
+ has1 = true;
+ }
+ if (b.obj1 == object2 || b.obj2 == object2)
+ {
+ has2 = true;
+ }
+ }
+
+ if (!has1) object1.notify[prop1].disconnect(on_notify);
+ if (!has2) object2.notify[prop2].disconnect(on_notify);
}
if (!itr.has_next()) break;
}
@@ -94,6 +100,7 @@ namespace Bindings
private void on_notify(GLib.Object object, GLib.ParamSpec pspec)
{
+ debug("asdf");
foreach (var binding in bindings())
{
if (binding.silence) continue;
@@ -150,6 +157,32 @@ namespace Bindings
}
}
+ private void connect_signals(GLib.Object obj1, string prop1,
+ GLib.Object obj2, string prop2)
+ {
+ bool has1 = false, has2 = false;
+
+ foreach (var binding in bindings())
+ {
+ if ((binding.obj1 == obj1 && binding.prop1 == prop1) ||
+ (binding.obj2 == obj1 && binding.prop2 == prop1))
+ {
+ has1 = true;
+ }
+ if ((binding.obj1 == obj2 && binding.prop1 == prop2) ||
+ (binding.obj2 == obj2 && binding.prop2 == prop2))
+ {
+ has2 = true;
+ }
+ }
+
+ if (!has1) obj1.notify[prop1].connect(on_notify);
+ if (!has2) obj2.notify[prop2].connect(on_notify);
+ }
+
+ public delegate bool DropFunction(GLib.Object object1, string property1,
+ GLib.Object object2, string property2);
+
private class Binding : GLib.Object
{
public weak GLib.Object obj1;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]