home · contact · privacy
Allow Client updates to diversify into zero to many TUI updates.
authorChristian Heller <c.heller@plomlompom.de>
Thu, 11 Sep 2025 20:02:50 +0000 (22:02 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Thu, 11 Sep 2025 20:02:50 +0000 (22:02 +0200)
ircplom/client.py
ircplom/client_tui.py

index 6f324a6e9aac89ece904a0f2f0012c04bf44de9b..dc5ee3b3820e9bd33bc1e74723f67be386179cf2 100644 (file)
@@ -198,30 +198,29 @@ class _CompletableStringsOrdered(_Clearable, _CompletableStringsCollection):
         self._collected = tuple()
 
 
-class IntoUpdateValueMixin(AutoAttrMixin):
-    'Provides .into_update_value(), exportable for module-external consumers.'
+class IntoEndnodeUpdatesMixin(AutoAttrMixin):
+    'Provides .into_endnode_updates exportable for module-external consumers.'
 
-    def into_update_value(self) -> Any:
-        'Return non-updating copy of self.'
-        if isinstance(self, _Dict):
-            return None
+    def into_endnode_updates(self, path: tuple[str, ...]
+                             ) -> list[tuple[tuple[str, ...], Any]]:
+        'Return path-value pairs for any update-worthy sub-elements.'
         if isinstance(self, _CompletableStringsCollection):
-            return self._completed
+            return ([(path, self._completed)] if self._completed is not None
+                    else [])
         if isinstance(self, _CompletableTopic):
-            return Topic(*self._completed)
-        for cls in [cls for cls in self.__class__.__mro__
-                    if AutoAttrMixin not in cls.__mro__]:
-            obj = cls()
-            break
-        for key in self._deep_annotations():
-            attr_val = getattr(self, key)
-            setattr(obj, key,
-                    attr_val if not isinstance(attr_val, _UpdatingMixin)
-                    else attr_val.static_copy)
-        return obj
-
-
-class _UpdatingMixin(IntoUpdateValueMixin):
+            return [(path, Topic(*self._completed))]
+        updates = []
+        for key, val in (self._dict.items() if isinstance(self, Dict)
+                         else ((k, getattr(self, k))
+                               for k in self._deep_annotations())):
+            p = path + (key,)
+            updates += (val.into_endnode_updates(p)
+                        if isinstance(val, IntoEndnodeUpdatesMixin)
+                        else [(p, val)])
+        return updates
+
+
+class _UpdatingMixin(IntoEndnodeUpdatesMixin):
     _on_update: Callable
 
     def __init__(self, on_update: Callable, **kwargs) -> None:
index e9e02348770a0199c2a7bb3713042bd584cb86ab..1a96377c07f1cb836fb5a97fbb34930ed135124a 100644 (file)
@@ -9,7 +9,7 @@ from ircplom.tui_base import (BaseTui, PromptWidget, TuiEvent, Window,
                               CMD_SHORTCUTS)
 from ircplom.client import (
         AutoAttrMixin, Client, ClientQueueMixin, Dict, DictItem,
-        IntoUpdateValueMixin, IrcConnSetup, LogScope, NewClientEvent,
+        IntoEndnodeUpdatesMixin, IrcConnSetup, LogScope, NewClientEvent,
         NickUserHost, ServerCapability, SharedClientDbFields, Topic)
 
 CMD_SHORTCUTS['disconnect'] = 'window.disconnect'
@@ -512,6 +512,7 @@ class _ClientKnowingTui(Client):
         value = ((parent[last_step] if last_step in parent.keys()
                   else None) if isinstance(parent, Dict)
                  else getattr(parent, last_step))
-        if isinstance(value, IntoUpdateValueMixin):
-            value = value.into_update_value()
-        self._client_tui_trigger('update_db', update=_Update(path, value))
+        for path, value in (value.into_endnode_updates(path)
+                            if isinstance(value, IntoEndnodeUpdatesMixin)
+                            else [(path, value)]):
+            self._client_tui_trigger('update_db', update=_Update(path, value))