summaryrefslogtreecommitdiff
path: root/python/astal/variable.py
diff options
context:
space:
mode:
authorAylur <[email protected]>2024-05-19 02:39:53 +0200
committerAylur <[email protected]>2024-05-19 02:39:53 +0200
commit1425b396b08f0e91d45bbd0f92b1309115c7c870 (patch)
tree8af1a899a14d8a01a9ef50e248c077b48aed25bc /python/astal/variable.py
init 0.1.0
Diffstat (limited to 'python/astal/variable.py')
-rw-r--r--python/astal/variable.py100
1 files changed, 100 insertions, 0 deletions
diff --git a/python/astal/variable.py b/python/astal/variable.py
new file mode 100644
index 0000000..3b6a71d
--- /dev/null
+++ b/python/astal/variable.py
@@ -0,0 +1,100 @@
+from gi.repository import Astal
+
+from .binding import Binding
+
+
+class Variable:
+ def __init__(self, init):
+ v = Astal.Variable.new(init)
+ self._variable = v
+ self._err_handler = print
+ v.connect("error", lambda _, err: self._err_handler(err) if self._err_handler else None)
+
+ def __call__(self, transform=None):
+ if transform:
+ return Binding(self).as_(transform)
+
+ return Binding(self)
+
+ def __str__(self):
+ return f"Variable<{self.get()}>"
+
+ def get(self):
+ return self._variable.get_value()
+
+ def set(self, value):
+ return self._variable.set_value(value)
+
+ def watch(self, cmd):
+ if isinstance(cmd, str):
+ self._variable.watch(cmd)
+ elif isinstance(cmd, list):
+ self._variable.watchv(cmd)
+ return self
+
+ def poll(self, interval, cmd):
+ if isinstance(cmd, str):
+ self._variable.poll(interval, cmd)
+ elif isinstance(cmd, list):
+ self._variable.pollv(interval, cmd)
+ else:
+ self._variable.pollfn(interval, cmd)
+ return self
+
+ def start_watch(self):
+ self._variable.start_watch()
+
+ def start_poll(self):
+ self._variable.start_poll()
+
+ def stop_watch(self):
+ self._variable.stop_watch()
+
+ def stop_poll(self):
+ self._variable.stop_poll()
+
+ def drop(self):
+ self._variable.emit_dropped()
+ self._variable.run_dispose()
+
+ def on_dropped(self, callback):
+ self._variable.connect("dropped", lambda _: callback())
+ return self
+
+ def on_error(self, callback):
+ self._err_handler = None
+ self._variable.connect("error", lambda _, e: callback(e))
+ return self
+
+ def subscribe(self, callback):
+ s = self._variable.connect("changed", lambda _: callback(self.get()))
+ return lambda: self._variable.disconnect(s)
+
+ def observe(self, objs, sigOrFn, callback=None):
+ if callable(sigOrFn):
+ f = sigOrFn
+ elif callable(callback):
+ f = callback
+ else:
+ f = lambda *_: self.get()
+
+ def setter(_, *args):
+ self.set(f(*args))
+
+ if isinstance(objs, list):
+ for obj in objs:
+ obj[0].connect(obj[1], setter)
+ elif isinstance(sigOrFn, str):
+ objs.connect(sigOrFn, setter)
+
+ return self
+
+ @staticmethod
+ def derive(deps, fn):
+ def update():
+ return fn(*[d.get() for d in deps])
+
+ derived = Variable(update())
+ unsubs = [dep.subscribe(lambda _: derived.set(update())) for dep in deps]
+ derived.on_dropped(lambda: ([unsub() for unsub in unsubs]))
+ return derived