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)
|
check(self)
|
||||||
assert(type(name) == "string", "name must be a string, got: " .. type(name))
|
assert(type(name) == "string", "name must be a string, got: " .. type(name))
|
||||||
if not self._signals[name] then
|
if not self._signals[name] then
|
||||||
self._signals[name] = {}
|
self._signals[name] = {
|
||||||
|
strong = {},
|
||||||
|
weak = setmetatable({}, { __mode = "k" })
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -48,7 +51,19 @@ end
|
||||||
function object:connect_signal(name, func)
|
function object:connect_signal(name, func)
|
||||||
assert(type(func) == "function", "callback must be a function, got: " .. type(func))
|
assert(type(func) == "function", "callback must be a function, got: " .. type(func))
|
||||||
local sig = find_signal(self, name, "connect to")
|
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
|
end
|
||||||
|
|
||||||
--- Disonnect to a signal
|
--- Disonnect to a signal
|
||||||
|
@ -56,7 +71,8 @@ end
|
||||||
-- @param func The callback that should be disconnected
|
-- @param func The callback that should be disconnected
|
||||||
function object:disconnect_signal(name, func)
|
function object:disconnect_signal(name, func)
|
||||||
local sig = find_signal(self, name, "disconnect from")
|
local sig = find_signal(self, name, "disconnect from")
|
||||||
sig[func] = nil
|
sig.weak[func] = nil
|
||||||
|
sig.strong[func] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Emit a signal
|
--- Emit a signal
|
||||||
|
@ -67,7 +83,10 @@ end
|
||||||
-- that are given to emit_signal()
|
-- that are given to emit_signal()
|
||||||
function object:emit_signal(name, ...)
|
function object:emit_signal(name, ...)
|
||||||
local sig = find_signal(self, name, "emit")
|
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, ...)
|
func(self, ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -120,7 +120,7 @@ function drawable:set_widget(widget)
|
||||||
|
|
||||||
self.widget = widget
|
self.widget = widget
|
||||||
if widget then
|
if widget then
|
||||||
widget:connect_signal("widget::updated", self.draw)
|
widget:weak_connect_signal("widget::updated", self.draw)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Make sure the widget gets drawn
|
-- Make sure the widget gets drawn
|
||||||
|
|
|
@ -140,7 +140,7 @@ local function widget_changed(layout, old_w, new_w)
|
||||||
end
|
end
|
||||||
if new_w then
|
if new_w then
|
||||||
widget_base.check_widget(new_w)
|
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
|
end
|
||||||
layout._emit_updated()
|
layout._emit_updated()
|
||||||
end
|
end
|
||||||
|
|
|
@ -48,7 +48,7 @@ function constraint:set_widget(widget)
|
||||||
end
|
end
|
||||||
if widget then
|
if widget then
|
||||||
widget_base.check_widget(widget)
|
widget_base.check_widget(widget)
|
||||||
widget:connect_signal("widget::updated", self._emit_updated)
|
widget:weak_connect_signal("widget::updated", self._emit_updated)
|
||||||
end
|
end
|
||||||
self.widget = widget
|
self.widget = widget
|
||||||
self:emit_signal("widget::updated")
|
self:emit_signal("widget::updated")
|
||||||
|
|
|
@ -54,7 +54,7 @@ end
|
||||||
function fixed:add(widget)
|
function fixed:add(widget)
|
||||||
widget_base.check_widget(widget)
|
widget_base.check_widget(widget)
|
||||||
table.insert(self.widgets, 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()
|
self._emit_updated()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ end
|
||||||
function flex:add(widget)
|
function flex:add(widget)
|
||||||
widget_base.check_widget(widget)
|
widget_base.check_widget(widget)
|
||||||
table.insert(self.widgets, 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()
|
self._emit_updated()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ function margin:set_widget(widget)
|
||||||
end
|
end
|
||||||
if widget then
|
if widget then
|
||||||
widget_base.check_widget(widget)
|
widget_base.check_widget(widget)
|
||||||
widget:connect_signal("widget::updated", self._emit_updated)
|
widget:weak_connect_signal("widget::updated", self._emit_updated)
|
||||||
end
|
end
|
||||||
self.widget = widget
|
self.widget = widget
|
||||||
self._emit_updated()
|
self._emit_updated()
|
||||||
|
|
|
@ -60,7 +60,7 @@ function mirror:set_widget(widget)
|
||||||
end
|
end
|
||||||
if widget then
|
if widget then
|
||||||
widget_base.check_widget(widget)
|
widget_base.check_widget(widget)
|
||||||
widget:connect_signal("widget::updated", self._emit_updated)
|
widget:weak_connect_signal("widget::updated", self._emit_updated)
|
||||||
end
|
end
|
||||||
self.widget = widget
|
self.widget = widget
|
||||||
self._emit_updated()
|
self._emit_updated()
|
||||||
|
|
|
@ -61,7 +61,7 @@ function rotate:set_widget(widget)
|
||||||
end
|
end
|
||||||
if widget then
|
if widget then
|
||||||
widget_base.check_widget(widget)
|
widget_base.check_widget(widget)
|
||||||
widget:connect_signal("widget::updated", self._emit_updated)
|
widget:weak_connect_signal("widget::updated", self._emit_updated)
|
||||||
end
|
end
|
||||||
self.widget = widget
|
self.widget = widget
|
||||||
self._emit_updated()
|
self._emit_updated()
|
||||||
|
|
|
@ -62,7 +62,7 @@ function background:set_widget(widget)
|
||||||
end
|
end
|
||||||
if widget then
|
if widget then
|
||||||
base.check_widget(widget)
|
base.check_widget(widget)
|
||||||
widget:connect_signal("widget::updated", self._emit_updated)
|
widget:weak_connect_signal("widget::updated", self._emit_updated)
|
||||||
end
|
end
|
||||||
self.widget = widget
|
self.widget = widget
|
||||||
self._emit_updated()
|
self._emit_updated()
|
||||||
|
|
|
@ -12,13 +12,19 @@ describe("gears.object", function()
|
||||||
obj:add_signal("signal")
|
obj:add_signal("signal")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("connect non-existent signal", function()
|
it("strong connect non-existent signal", function()
|
||||||
assert.has.errors(function()
|
assert.has.errors(function()
|
||||||
obj:connect_signal("foo", function() end)
|
obj:connect_signal("foo", function() end)
|
||||||
end)
|
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()
|
assert.has.errors(function()
|
||||||
obj:disconnect_signal("foo", function() end)
|
obj:disconnect_signal("foo", function() end)
|
||||||
end)
|
end)
|
||||||
|
@ -30,16 +36,27 @@ describe("gears.object", function()
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("connecting and emitting signal", function()
|
it("strong connecting and emitting signal", function()
|
||||||
local called = false
|
local called = false
|
||||||
obj:connect_signal("signal", function()
|
local function cb()
|
||||||
called = true
|
called = true
|
||||||
end)
|
end
|
||||||
|
obj:connect_signal("signal", cb)
|
||||||
obj:emit_signal("signal")
|
obj:emit_signal("signal")
|
||||||
assert.is_true(called)
|
assert.is_true(called)
|
||||||
end)
|
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 called = false
|
||||||
local function cb()
|
local function cb()
|
||||||
called = true
|
called = true
|
||||||
|
@ -50,13 +67,64 @@ describe("gears.object", function()
|
||||||
assert.is_false(called)
|
assert.is_false(called)
|
||||||
end)
|
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()
|
it("arguments to signal", function()
|
||||||
obj:connect_signal("signal", function(arg1, arg2)
|
obj:connect_signal("signal", function(arg1, arg2)
|
||||||
assert.is.equal(obj, arg1)
|
assert.is.equal(obj, arg1)
|
||||||
assert.is.same(42, arg2)
|
assert.is.same(42, arg2)
|
||||||
end)
|
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)
|
obj:emit_signal("signal", 42)
|
||||||
end)
|
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)
|
end)
|
||||||
|
|
||||||
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|
||||||
|
|
Loading…
Reference in New Issue