Merge branch 'psychon-weak_connect'
Closes https://github.com/awesomeWM/awesome/pull/263
This commit is contained in:
commit
61275ccba0
|
@ -38,7 +38,10 @@ function object:add_signal(name)
|
|||
check(self)
|
||||
assert(type(name) == "string", "name must be a string, got: " .. type(name))
|
||||
if not self._signals[name] then
|
||||
self._signals[name] = {}
|
||||
self._signals[name] = {
|
||||
strong = {},
|
||||
weak = setmetatable({}, { __mode = "k" })
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -48,7 +51,19 @@ end
|
|||
function object:connect_signal(name, func)
|
||||
assert(type(func) == "function", "callback must be a function, got: " .. type(func))
|
||||
local sig = find_signal(self, name, "connect to")
|
||||
sig[func] = func
|
||||
assert(sig.weak[func] == nil, "Trying to connect a strong callback which is already connected weakly")
|
||||
sig.strong[func] = true
|
||||
end
|
||||
|
||||
--- Connect to a signal weakly. This allows the callback function to be garbage
|
||||
-- collected and automatically disconnects the signal when that happens.
|
||||
-- @param name The name of the signal
|
||||
-- @param func The callback to call when the signal is emitted
|
||||
function object:weak_connect_signal(name, func)
|
||||
assert(type(func) == "function", "callback must be a function, got: " .. type(func))
|
||||
local sig = find_signal(self, name, "connect to")
|
||||
assert(sig.strong[func] == nil, "Trying to connect a weak callback which is already connected strongly")
|
||||
sig.weak[func] = true
|
||||
end
|
||||
|
||||
--- Disonnect to a signal
|
||||
|
@ -56,7 +71,8 @@ end
|
|||
-- @param func The callback that should be disconnected
|
||||
function object:disconnect_signal(name, func)
|
||||
local sig = find_signal(self, name, "disconnect from")
|
||||
sig[func] = nil
|
||||
sig.weak[func] = nil
|
||||
sig.strong[func] = nil
|
||||
end
|
||||
|
||||
--- Emit a signal
|
||||
|
@ -67,7 +83,10 @@ end
|
|||
-- that are given to emit_signal()
|
||||
function object:emit_signal(name, ...)
|
||||
local sig = find_signal(self, name, "emit")
|
||||
for func in pairs(sig) do
|
||||
for func in pairs(sig.strong) do
|
||||
func(self, ...)
|
||||
end
|
||||
for func in pairs(sig.weak) do
|
||||
func(self, ...)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -120,7 +120,7 @@ function drawable:set_widget(widget)
|
|||
|
||||
self.widget = widget
|
||||
if widget then
|
||||
widget:connect_signal("widget::updated", self.draw)
|
||||
widget:weak_connect_signal("widget::updated", self.draw)
|
||||
end
|
||||
|
||||
-- Make sure the widget gets drawn
|
||||
|
|
|
@ -140,7 +140,7 @@ local function widget_changed(layout, old_w, new_w)
|
|||
end
|
||||
if new_w then
|
||||
widget_base.check_widget(new_w)
|
||||
new_w:connect_signal("widget::updated", layout._emit_updated)
|
||||
new_w:weak_connect_signal("widget::updated", layout._emit_updated)
|
||||
end
|
||||
layout._emit_updated()
|
||||
end
|
||||
|
|
|
@ -48,7 +48,7 @@ function constraint:set_widget(widget)
|
|||
end
|
||||
if widget then
|
||||
widget_base.check_widget(widget)
|
||||
widget:connect_signal("widget::updated", self._emit_updated)
|
||||
widget:weak_connect_signal("widget::updated", self._emit_updated)
|
||||
end
|
||||
self.widget = widget
|
||||
self:emit_signal("widget::updated")
|
||||
|
|
|
@ -54,7 +54,7 @@ end
|
|||
function fixed:add(widget)
|
||||
widget_base.check_widget(widget)
|
||||
table.insert(self.widgets, widget)
|
||||
widget:connect_signal("widget::updated", self._emit_updated)
|
||||
widget:weak_connect_signal("widget::updated", self._emit_updated)
|
||||
self._emit_updated()
|
||||
end
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ end
|
|||
function flex:add(widget)
|
||||
widget_base.check_widget(widget)
|
||||
table.insert(self.widgets, widget)
|
||||
widget:connect_signal("widget::updated", self._emit_updated)
|
||||
widget:weak_connect_signal("widget::updated", self._emit_updated)
|
||||
self._emit_updated()
|
||||
end
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ function margin:set_widget(widget)
|
|||
end
|
||||
if widget then
|
||||
widget_base.check_widget(widget)
|
||||
widget:connect_signal("widget::updated", self._emit_updated)
|
||||
widget:weak_connect_signal("widget::updated", self._emit_updated)
|
||||
end
|
||||
self.widget = widget
|
||||
self._emit_updated()
|
||||
|
|
|
@ -60,7 +60,7 @@ function mirror:set_widget(widget)
|
|||
end
|
||||
if widget then
|
||||
widget_base.check_widget(widget)
|
||||
widget:connect_signal("widget::updated", self._emit_updated)
|
||||
widget:weak_connect_signal("widget::updated", self._emit_updated)
|
||||
end
|
||||
self.widget = widget
|
||||
self._emit_updated()
|
||||
|
|
|
@ -61,7 +61,7 @@ function rotate:set_widget(widget)
|
|||
end
|
||||
if widget then
|
||||
widget_base.check_widget(widget)
|
||||
widget:connect_signal("widget::updated", self._emit_updated)
|
||||
widget:weak_connect_signal("widget::updated", self._emit_updated)
|
||||
end
|
||||
self.widget = widget
|
||||
self._emit_updated()
|
||||
|
|
|
@ -62,7 +62,7 @@ function background:set_widget(widget)
|
|||
end
|
||||
if widget then
|
||||
base.check_widget(widget)
|
||||
widget:connect_signal("widget::updated", self._emit_updated)
|
||||
widget:weak_connect_signal("widget::updated", self._emit_updated)
|
||||
end
|
||||
self.widget = widget
|
||||
self._emit_updated()
|
||||
|
|
|
@ -12,13 +12,19 @@ describe("gears.object", function()
|
|||
obj:add_signal("signal")
|
||||
end)
|
||||
|
||||
it("connect non-existent signal", function()
|
||||
it("strong connect non-existent signal", function()
|
||||
assert.has.errors(function()
|
||||
obj:connect_signal("foo", function() end)
|
||||
end)
|
||||
end)
|
||||
|
||||
it("disconnect non-existent signal", function()
|
||||
it("weak connect non-existent signal", function()
|
||||
assert.has.errors(function()
|
||||
obj:weak_connect_signal("foo", function() end)
|
||||
end)
|
||||
end)
|
||||
|
||||
it("strong disconnect non-existent signal", function()
|
||||
assert.has.errors(function()
|
||||
obj:disconnect_signal("foo", function() end)
|
||||
end)
|
||||
|
@ -30,16 +36,27 @@ describe("gears.object", function()
|
|||
end)
|
||||
end)
|
||||
|
||||
it("connecting and emitting signal", function()
|
||||
it("strong connecting and emitting signal", function()
|
||||
local called = false
|
||||
obj:connect_signal("signal", function()
|
||||
local function cb()
|
||||
called = true
|
||||
end)
|
||||
end
|
||||
obj:connect_signal("signal", cb)
|
||||
obj:emit_signal("signal")
|
||||
assert.is_true(called)
|
||||
end)
|
||||
|
||||
it("connecting, disconnecting and emitting signal", function()
|
||||
it("weak connecting and emitting signal", function()
|
||||
local called = false
|
||||
local function cb()
|
||||
called = true
|
||||
end
|
||||
obj:weak_connect_signal("signal", cb)
|
||||
obj:emit_signal("signal")
|
||||
assert.is_true(called)
|
||||
end)
|
||||
|
||||
it("strong connecting, disconnecting and emitting signal", function()
|
||||
local called = false
|
||||
local function cb()
|
||||
called = true
|
||||
|
@ -50,13 +67,64 @@ describe("gears.object", function()
|
|||
assert.is_false(called)
|
||||
end)
|
||||
|
||||
it("weak connecting, disconnecting and emitting signal", function()
|
||||
local called = false
|
||||
local function cb()
|
||||
called = true
|
||||
end
|
||||
obj:weak_connect_signal("signal", cb)
|
||||
obj:disconnect_signal("signal", cb)
|
||||
obj:emit_signal("signal")
|
||||
assert.is_false(called)
|
||||
end)
|
||||
|
||||
it("arguments to signal", function()
|
||||
obj:connect_signal("signal", function(arg1, arg2)
|
||||
assert.is.equal(obj, arg1)
|
||||
assert.is.same(42, arg2)
|
||||
end)
|
||||
obj:weak_connect_signal("signal", function(arg1, arg2)
|
||||
assert.is.equal(obj, arg1)
|
||||
assert.is.same(42, arg2)
|
||||
end)
|
||||
obj:emit_signal("signal", 42)
|
||||
end)
|
||||
|
||||
it("strong non-auto disconnect", function()
|
||||
local called = false
|
||||
obj:connect_signal("signal", function()
|
||||
called = true
|
||||
end)
|
||||
collectgarbage("collect")
|
||||
obj:emit_signal("signal")
|
||||
assert.is_true(called)
|
||||
end)
|
||||
|
||||
it("weak auto disconnect", function()
|
||||
local called = false
|
||||
obj:weak_connect_signal("signal", function()
|
||||
called = true
|
||||
end)
|
||||
collectgarbage("collect")
|
||||
obj:emit_signal("signal")
|
||||
assert.is_false(called)
|
||||
end)
|
||||
|
||||
it("strong connect after weak connect", function()
|
||||
local function cb() end
|
||||
obj:weak_connect_signal("signal", cb)
|
||||
assert.has.errors(function()
|
||||
obj:connect_signal("signal", cb)
|
||||
end)
|
||||
end)
|
||||
|
||||
it("weak connect after strong connect", function()
|
||||
local function cb() end
|
||||
obj:connect_signal("signal", cb)
|
||||
assert.has.errors(function()
|
||||
obj:weak_connect_signal("signal", cb)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||
|
|
Loading…
Reference in New Issue