diff options
Diffstat (limited to 'core/lua/astal/binding.lua')
-rw-r--r-- | core/lua/astal/binding.lua | 65 |
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 |