Browse Source

using weakref to store bindings -- this makes sure we do not keep unused objects around

Rodja Trappe 3 years ago
parent
commit
d59663690d
1 changed files with 11 additions and 3 deletions
  1. 11 3
      nicegui/binding.py

+ 11 - 3
nicegui/binding.py

@@ -2,6 +2,7 @@
 import asyncio
 from collections import defaultdict
 from justpy.htmlcomponents import HTMLBaseComponent
+import weakref
 
 bindings = defaultdict(list)
 bindable_properties = set()
@@ -27,22 +28,29 @@ def propagate(source_obj, source_name, visited=None):
     if visited is None:
         visited = set()
     visited.add((id(source_obj), source_name))
-    for _, target_obj, target_name, transform in bindings[(id(source_obj), source_name)]:
+    invalid_targets = []
+    binding_sources = bindings[(id(source_obj), source_name)]
+    for _, target_weakref, target_name, transform in binding_sources:
+        target_obj = target_weakref()  # unpack weak ref
+        if target_obj is None:
+            invalid_targets.append(target_weakref)
+            continue
         if (id(target_obj), target_name) in visited:
             continue
         target_value = transform(getattr(source_obj, source_name))
         if getattr(target_obj, target_name) != target_value:
             setattr(target_obj, target_name, target_value)
             propagate(target_obj, target_name, visited)
+    bindings[(id(source_obj), source_name)] = [b for b in binding_sources if b[1] not in invalid_targets]
 
 def bind_to(self_obj, self_name, other_obj, other_name, forward):
-    bindings[(id(self_obj), self_name)].append((self_obj, other_obj, other_name, forward))
+    bindings[(id(self_obj), self_name)].append((weakref.ref(self_obj), weakref.ref(other_obj), other_name, forward))
     if (id(self_obj), self_name) not in bindable_properties:
         active_links.append((self_obj, self_name, other_obj, other_name, forward))
     propagate(self_obj, self_name)
 
 def bind_from(self_obj, self_name, other_obj, other_name, backward):
-    bindings[(id(other_obj), other_name)].append((other_obj, self_obj, self_name, backward))
+    bindings[(id(other_obj), other_name)].append((weakref.ref(other_obj), weakref.ref(self_obj), self_name, backward))
     if (id(other_obj), other_name) not in bindable_properties:
         active_links.append((other_obj, other_name, self_obj, self_name, backward))
     propagate(other_obj, other_name)