Implement listen cancelling

Signed-off-by: Rahix <rahix@rahix.de>
dev
rahix 7 years ago
parent 719201e950
commit c33fdd41a6

@ -184,7 +184,7 @@ bc:listen("some_noun", bc.Query.Below(0), function(value)
end)
```
### `BaseControl:cancel(id)`
### `BaseControl:cancel(noun, id)`
Cancel a previously installed listener. The id will be invalid after this call.
```lua
local listenid = bc:listen("some_noun", bc.Query.Change, function(value)
@ -192,7 +192,7 @@ local listenid = bc:listen("some_noun", bc.Query.Change, function(value)
end)
-- Later ...
bc:cancel(listenid)
bc:cancel("some_noun", listenid)
```
### `BaseControl:close()`

@ -390,7 +390,7 @@ function BaseControl:listen(noun, query, callback)
callback=callback,
}
if self.local_nouns[noun] ~= nil then
return true
return id, true
elseif self.remote_nouns[noun] ~= nil then
self.network:send(self.remote_nouns[noun], {
ty=Message.ListenRequest,
@ -398,10 +398,24 @@ function BaseControl:listen(noun, query, callback)
id=id,
query=query,
})
return true
return id, true
else
return false
return id, false
end
end
function BaseControl:cancel(noun, id)
if self.listeners[noun] == nil or self.listeners[noun][id] == nil then
error("can't cancel unknown listener on \""..noun.."\"")
end
if self.local_nouns[noun] == nil and self.remote_nouns[noun] ~= nil then
self.network:send(self.remote_nouns[noun], {
ty=Message.ListenCancel,
noun=noun,
id=id,
})
end
self.listeners[noun][id] = nil
end
-- }}}
@ -469,6 +483,12 @@ function BaseControl:_network_handler(remote, msg)
if self.listeners[msg.noun][msg.id] ~= nil then
self.listeners[msg.noun][msg.id].callback(msg.value)
end
elseif msg.ty == Message.ListenCancel then
if self.listeners[msg.noun][msg.id] ~= nil then
if self.listeners[msg.noun][msg.id].addr == remote then
self.listeners[msg.noun][msg.id] = nil
end
end
else
error("TODO: MessageType Unknown")
end

@ -134,3 +134,64 @@ do
end
end
end
function test_listen_cancel()
local bc = BaseControl:new()
bc:register("lcan1", 123)
bc:finalize()
local n = 0
local id = bc:listen("lcan1", BaseControl.Query.Change, function()
n = n + 1
end)
assert_equal(0, n, "wrong number of listener invokations")
bc:set("lcan1", 321)
assert_equal(1, n, "wrong number of listener invokations")
-- Cancel the listener
bc:cancel("lcan1", id)
bc:set("lcan1", 12)
assert_equal(1, n, "wrong number of listener invokations")
assert_error_match("unknown", function()
bc:cancel("lcan1", id)
end)
assert_error_match("unknown", function()
bc:cancel("lcan2", "fooid")
end)
end
function test_listen_cancel_remote()
local bc1 = BaseControl:new()
local addr1 = network.get_scene()
bc1:register("lcanr1", 123)
bc1:finalize()
local bc2 = BaseControl:new()
local addr2 = network.get_scene()
local n = 0
local id, ok = bc2:listen("lcanr1", BaseControl.Query.Change, function()
n = n + 1
end)
assert_true(ok, "failed installing")
network.set_scene(addr1)
assert_equal(0, n, "wrong number of listener invokations")
bc1:set("lcanr1", 34)
assert_equal(1, n, "wrong number of listener invokations")
-- Dirty hack to get the test working
local save = bc2.listeners["lcanr1"][id]
network.set_scene(addr2)
bc2:cancel("lcanr1", id)
bc2.listeners["lcanr1"][id] = save
network.set_scene(addr1)
bc1:set("lcanr1", 21)
assert_equal(1, n, "wrong number of listener invokations")
end

Loading…
Cancel
Save