summaryrefslogtreecommitdiff
path: root/core/lua/astal/binding.lua
diff options
context:
space:
mode:
Diffstat (limited to 'core/lua/astal/binding.lua')
-rw-r--r--core/lua/astal/binding.lua65
1 files changed, 65 insertions, 0 deletions
diff --git a/core/lua/astal/binding.lua b/core/lua/astal/binding.lua
new file mode 100644
index 0000000..50509d1
--- /dev/null
+++ b/core/lua/astal/binding.lua
@@ -0,0 +1,65 @@
+local lgi = require("lgi")
+local GObject = lgi.require("GObject", "2.0")
+
+---@class Binding
+---@field emitter table|Variable
+---@field property? string
+---@field transformFn function
+local Binding = {}
+
+---@param emitter table
+---@param property? string
+---@return Binding
+function Binding.new(emitter, property)
+ return setmetatable({
+ emitter = emitter,
+ property = property,
+ transformFn = function(v)
+ return v
+ end,
+ }, Binding)
+end
+
+function Binding:__tostring()
+ local str = "Binding<" .. tostring(self.emitter)
+ if self.property ~= nil then
+ str = str .. ", " .. self.property
+ end
+ return str .. ">"
+end
+
+function Binding:get()
+ if type(self.emitter.get) == "function" then
+ return self.transformFn(self.emitter:get())
+ end
+ return self.transformFn(self.emitter[self.property])
+end
+
+---@param transform fun(value: any): any
+---@return Binding
+function Binding:as(transform)
+ local b = Binding.new(self.emitter, self.property)
+ b.transformFn = function(v)
+ return transform(self.transformFn(v))
+ end
+ return b
+end
+
+---@param callback fun(value: any)
+---@return function
+function Binding:subscribe(callback)
+ if type(self.emitter.subscribe) == "function" then
+ return self.emitter:subscribe(function()
+ callback(self:get())
+ end)
+ end
+ local id = self.emitter.on_notify:connect(function()
+ callback(self:get())
+ end, self.property, false)
+ return function()
+ GObject.signal_handler_disconnect(self.emitter, id)
+ end
+end
+
+Binding.__index = Binding
+return Binding