From 8fb07e22cccdb7a301d28c899632820926ec0a86 Mon Sep 17 00:00:00 2001 From: Rahix Date: Wed, 17 Apr 2019 01:05:49 +0200 Subject: [PATCH] Implement close() Signed-off-by: Rahix --- bc.lua | 29 ++++++++++++++++++++ component.lua | 4 +++ tests/cleanup.lua | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 tests/cleanup.lua diff --git a/bc.lua b/bc.lua index 180b9a5a40a8..e15bf4a85533 100644 --- a/bc.lua +++ b/bc.lua @@ -205,6 +205,24 @@ function BaseControl:finalize(waits, timeout) return self end +function BaseControl:close() + if self.live == true then + -- Deregister own nouns and verbs if we were live + local nouns, verbs = self:nouns(true), self:verbs(true) + if #nouns > 0 or #verbs > 0 then + self.network:broadcast{ + ty=Message.Deregister, + nouns=nouns, + verbs=verbs, + } + end + end + + self.network:stop() + + setmetatable(self, nil) +end + -- Nouns {{{ function BaseControl:has_noun(noun) return self.local_nouns[noun] ~= nil or self.remote_nouns[noun] ~= nil @@ -347,6 +365,17 @@ function BaseControl:_network_handler(remote, msg) for _, verb in ipairs(msg.verbs or {}) do self.remote_verbs[verb] = remote end + elseif msg.ty == Message.Deregister then + for _, noun in ipairs(msg.nouns or {}) do + if self.remote_nouns[noun] == remote then + self.remote_nouns[noun] = nil + end + end + for _, verb in ipairs(msg.verbs or {}) do + if self.remote_verbs[verb] == remote then + self.remote_verbs[verb] = nil + end + end elseif msg.ty == Message.NounRequest then self.network:send(remote, { ty=Message.NounResponse, diff --git a/component.lua b/component.lua index 215d3d123f0c..9b7f161f1a5e 100644 --- a/component.lua +++ b/component.lua @@ -10,6 +10,10 @@ function modem.send(addr, port, msg) network.send(addr, port, msg) end +function modem.close(port) + -- Nothing +end + function modem.broadcast(port, msg) network.broadcast(port, msg) end diff --git a/tests/cleanup.lua b/tests/cleanup.lua new file mode 100644 index 000000000000..bb5ac9a18577 --- /dev/null +++ b/tests/cleanup.lua @@ -0,0 +1,68 @@ +require("lunit") + +local network = require("network") +local serialization = require("serialization") +local BaseControl = require("bc") + +module("cleanup", package.seeall, lunit.testcase) + +function test_clean_simple() + local bc = BaseControl:new() + bc:close() + + local bc = BaseControl:finalize() + bc:close() + + assert_error(function() + bc:nouns() + end) +end + +function test_clean_network() + local bc1 = BaseControl:new() + local addr1 = network.get_scene() + bc1:register("cln1", 123) + bc1:register("cln2v", function() end) + bc1:finalize() + + local bc2 = BaseControl:new() + local addr2 = network.get_scene() + + assert_true(bc2:has_noun("cln1"), "init failed") + assert_true(bc2:has_verb("cln2v"), "init failed") + + network.set_scene(addr1) + bc1:close() + + network.set_scene(addr2) + assert_false(bc2:has_noun("cln1"), "close failed") + assert_false(bc2:has_verb("cln2v"), "close failed") +end + +function test_clean_network2() + local bc1 = BaseControl:new() + local addr1 = network.get_scene() + local n = 0 + bc1:register("cln3", 1231) + bc1:register("cln4v", function() + n = n + 1 + end) + bc1:finalize() + + local bc2 = BaseControl:new() + local addr2 = network.get_scene() + + assert_equal(0, n, "verb called too much/little") + assert_true(bc2:call("cln4v"), "verb not called") + assert_equal(1, n, "verb called too much/little") + assert_equal(1231, bc2:get("cln3"), "noun not retrieved correctly") + + network.set_scene(addr1) + bc1:close() + + assert_false(bc2:call("cln4v"), "verb called") + assert_equal(1, n, "verb called too much/little") + assert_error_match("unknown", function() + bc2:get("cln3") + end) +end