Implement listen cancelling
Signed-off-by: Rahix <rahix@rahix.de>
This commit is contained in:
parent
719201e950
commit
c33fdd41a6
3 changed files with 86 additions and 5 deletions
|
|
@ -184,7 +184,7 @@ bc:listen("some_noun", bc.Query.Below(0), function(value)
|
||||||
end)
|
end)
|
||||||
```
|
```
|
||||||
|
|
||||||
### `BaseControl:cancel(id)`
|
### `BaseControl:cancel(noun, id)`
|
||||||
Cancel a previously installed listener. The id will be invalid after this call.
|
Cancel a previously installed listener. The id will be invalid after this call.
|
||||||
```lua
|
```lua
|
||||||
local listenid = bc:listen("some_noun", bc.Query.Change, function(value)
|
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)
|
end)
|
||||||
|
|
||||||
-- Later ...
|
-- Later ...
|
||||||
bc:cancel(listenid)
|
bc:cancel("some_noun", listenid)
|
||||||
```
|
```
|
||||||
|
|
||||||
### `BaseControl:close()`
|
### `BaseControl:close()`
|
||||||
|
|
|
||||||
26
bc.lua
26
bc.lua
|
|
@ -390,7 +390,7 @@ function BaseControl:listen(noun, query, callback)
|
||||||
callback=callback,
|
callback=callback,
|
||||||
}
|
}
|
||||||
if self.local_nouns[noun] ~= nil then
|
if self.local_nouns[noun] ~= nil then
|
||||||
return true
|
return id, true
|
||||||
elseif self.remote_nouns[noun] ~= nil then
|
elseif self.remote_nouns[noun] ~= nil then
|
||||||
self.network:send(self.remote_nouns[noun], {
|
self.network:send(self.remote_nouns[noun], {
|
||||||
ty=Message.ListenRequest,
|
ty=Message.ListenRequest,
|
||||||
|
|
@ -398,11 +398,25 @@ function BaseControl:listen(noun, query, callback)
|
||||||
id=id,
|
id=id,
|
||||||
query=query,
|
query=query,
|
||||||
})
|
})
|
||||||
return true
|
return id, true
|
||||||
else
|
else
|
||||||
return false
|
return id, false
|
||||||
end
|
end
|
||||||
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
|
||||||
-- }}}
|
-- }}}
|
||||||
|
|
||||||
-- Network Handler {{{
|
-- Network Handler {{{
|
||||||
|
|
@ -469,6 +483,12 @@ function BaseControl:_network_handler(remote, msg)
|
||||||
if self.listeners[msg.noun][msg.id] ~= nil then
|
if self.listeners[msg.noun][msg.id] ~= nil then
|
||||||
self.listeners[msg.noun][msg.id].callback(msg.value)
|
self.listeners[msg.noun][msg.id].callback(msg.value)
|
||||||
end
|
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
|
else
|
||||||
error("TODO: MessageType Unknown")
|
error("TODO: MessageType Unknown")
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -134,3 +134,64 @@ do
|
||||||
end
|
end
|
||||||
end
|
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…
Add table
Add a link
Reference in a new issue