Make testable version work in-game
Signed-off-by: Rahix <rahix@rahix.de>
This commit is contained in:
parent
4dd809ba03
commit
fa0c331f8e
9 changed files with 250 additions and 309 deletions
|
|
@ -1,98 +0,0 @@
|
||||||
_bc_backend = { local_addr = "" }
|
|
||||||
|
|
||||||
network = false
|
|
||||||
fn = require("fake_net")
|
|
||||||
|
|
||||||
function _bc_backend:init(cb_handler)
|
|
||||||
local o = {}
|
|
||||||
setmetatable(o, self)
|
|
||||||
self.__index = self
|
|
||||||
o.cb_handler = cb_handler
|
|
||||||
o.network = network
|
|
||||||
o.local_addr = "address_light"
|
|
||||||
local function nw_handler(msg)
|
|
||||||
if msg.type == "noun_return" then
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Init network
|
|
||||||
if network == false then
|
|
||||||
network = fn:init()
|
|
||||||
network:add_node("address_light", nw_handler)
|
|
||||||
-- Add second node
|
|
||||||
o.dbg_node = require("bc"):init("master")
|
|
||||||
o.dbg_node._backend.local_addr = "address_power"
|
|
||||||
o.dbg_node:set_noun("power", 12)
|
|
||||||
else
|
|
||||||
network:add_node("address_power", nw_handler)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
return o
|
|
||||||
end
|
|
||||||
|
|
||||||
function _bc_backend:fetch_list(master_id)
|
|
||||||
return {
|
|
||||||
nouns = {
|
|
||||||
["power"] = "address_power",
|
|
||||||
["light"] = "address_light",
|
|
||||||
},
|
|
||||||
verbs = {
|
|
||||||
["inc_pwr"] = "address_power",
|
|
||||||
["toggle_light"] = "address_light",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
function _bc_backend:request_noun(addr, n)
|
|
||||||
if addr == "address_power" and n == "power" then
|
|
||||||
return self.power
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
function _bc_backend:call_verb(addr, v, param)
|
|
||||||
if addr == "address_power" and v == "inc_pwr" then
|
|
||||||
self.power = param
|
|
||||||
if self.iscb then
|
|
||||||
self.cb_handler("listen", 101010)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function _bc_backend:register_callback(addr, n, query, qparam)
|
|
||||||
self.iscb = true
|
|
||||||
return 101010
|
|
||||||
end
|
|
||||||
|
|
||||||
function _bc_backend:cancel_callback(addr, n, id)
|
|
||||||
self.iscb = false
|
|
||||||
end
|
|
||||||
|
|
||||||
function _bc_backend:call_listener(addr, n, id, value)
|
|
||||||
if id == self.cbid and addr == "foobar" and n == self.cbn then
|
|
||||||
self.cb(value)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Debug handlers
|
|
||||||
function _bc_backend:debug_request_noun(n)
|
|
||||||
-- Ask cb for noun value
|
|
||||||
return self.cb_handler("noun", n)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _bc_backend:debug_call_verb(v, arg)
|
|
||||||
self.cb_handler("verb", v, arg)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _bc_backend:debug_register_cb(n, query, qparam, cb)
|
|
||||||
self.cbid = self.cb_handler("reg_nl", n, {query = query, qparam = qparam, addr = "foobar"})
|
|
||||||
self.cbn = n
|
|
||||||
self.cb = cb
|
|
||||||
end
|
|
||||||
|
|
||||||
function _bc_backend:debug_cancel_cb()
|
|
||||||
self.cb_handler("unreg_nl", self.cbn, self.cbid)
|
|
||||||
end
|
|
||||||
|
|
||||||
return _bc_backend
|
|
||||||
101
bc-old.lua
101
bc-old.lua
|
|
@ -1,101 +0,0 @@
|
||||||
bc = {}
|
|
||||||
|
|
||||||
_bc_backend = require("_bc_backend")
|
|
||||||
|
|
||||||
function bc:init(master_id)
|
|
||||||
local o = {}
|
|
||||||
setmetatable(o, self)
|
|
||||||
self.__index = self
|
|
||||||
-- Init backend and cb handler
|
|
||||||
o._listen_callbacks = {}
|
|
||||||
o._verb_handlers = {}
|
|
||||||
o._listeners = {}
|
|
||||||
local function cb_handler(cb_type, param, arg)
|
|
||||||
if cb_type == "listen" then
|
|
||||||
if type(o._listen_callbacks[param]) == "function" then
|
|
||||||
o._listen_callbacks[param]()
|
|
||||||
end
|
|
||||||
elseif cb_type == "verb" then
|
|
||||||
o._verb_handlers[param](arg)
|
|
||||||
elseif cb_type == "noun" then
|
|
||||||
return o._mynouns[param]
|
|
||||||
elseif cb_type == "reg_nl" then
|
|
||||||
-- Create array if there is not one already
|
|
||||||
o._listeners[param] = o._listeners[param] or {}
|
|
||||||
-- Insert parameters
|
|
||||||
table.insert(o._listeners[param], arg)
|
|
||||||
return #o._listeners[param]
|
|
||||||
elseif cb_type == "unreg_nl" then
|
|
||||||
o._listeners[param][arg] = true;
|
|
||||||
else
|
|
||||||
error("Wrong cb type")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
o._backend = _bc_backend:init(cb_handler)
|
|
||||||
-- Fetch list of nouns and verbs from master
|
|
||||||
local list = o._backend:fetch_list(master_id)
|
|
||||||
o._nouns = list.nouns
|
|
||||||
o._verbs = list.verbs
|
|
||||||
-- Initialize own nouns
|
|
||||||
o._mynouns = {}
|
|
||||||
for noun, addr in pairs(o._nouns) do
|
|
||||||
if addr == o._backend.local_addr then
|
|
||||||
o._mynouns[noun] = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
list = nil
|
|
||||||
return o
|
|
||||||
end
|
|
||||||
|
|
||||||
function bc:get_noun(n)
|
|
||||||
if self._nouns[n] == self._backend.local_addr then
|
|
||||||
return self._mynouns[n]
|
|
||||||
else
|
|
||||||
return self._backend:request_noun(self._nouns[n], n)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function bc:set_noun(n, val)
|
|
||||||
if self._nouns[n] == self._backend.local_addr then
|
|
||||||
-- Call listeners
|
|
||||||
if type(self._listeners[n]) == "table" then
|
|
||||||
for i, listener in ipairs(self._listeners[n]) do
|
|
||||||
-- Check condition
|
|
||||||
if type(listener) == "table" and
|
|
||||||
( (listener.query == "onchange" and self._mynouns[n] ~= val)
|
|
||||||
or (listener.query == "onrising" and self._mynouns[n] < val)
|
|
||||||
or (listener.query == "onfalling" and self._mynouns[n] > val)
|
|
||||||
or (listener.query == "onabove" and val > listener.qparam)
|
|
||||||
or (listener.query == "onbelow" and val < listener.qparam)
|
|
||||||
or (listener.query == "onvalue" and val == listener.qparam)
|
|
||||||
) then
|
|
||||||
self._backend:call_listener(listener.addr, n, i, val)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Set value
|
|
||||||
self._mynouns[n] = val
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function bc:on_verb(v, handler)
|
|
||||||
self._verb_handlers[v] = handler
|
|
||||||
end
|
|
||||||
|
|
||||||
function bc:call_verb(v, param)
|
|
||||||
self._backend:call_verb(self._verbs[v], v, param)
|
|
||||||
end
|
|
||||||
|
|
||||||
function bc:listen_noun(n, query, qparam, cb)
|
|
||||||
local id = self._backend:register_callback(self._nouns[n], n, query, qparam)
|
|
||||||
self._listen_callbacks[id] = cb
|
|
||||||
return id
|
|
||||||
end
|
|
||||||
|
|
||||||
function bc:listen_cancel(n, id)
|
|
||||||
self._backend:cancel_callback(n, id)
|
|
||||||
end
|
|
||||||
|
|
||||||
return bc
|
|
||||||
58
bc.lua
58
bc.lua
|
|
@ -1,9 +1,5 @@
|
||||||
-- For testing
|
event = require("event")
|
||||||
modem = require("modem")
|
modem = require("component").modem
|
||||||
|
|
||||||
-- For deployment
|
|
||||||
-- modem = require("component").modem
|
|
||||||
|
|
||||||
serializer = require("serialization")
|
serializer = require("serialization")
|
||||||
|
|
||||||
List = {last = -1}
|
List = {last = -1}
|
||||||
|
|
@ -62,7 +58,7 @@ CFG_PORT = 1234
|
||||||
|
|
||||||
bc = {}
|
bc = {}
|
||||||
|
|
||||||
function bc:init(my_address, local_nouns, local_verbs)
|
function bc:init(local_nouns, local_verbs)
|
||||||
local_nouns = local_nouns or {}
|
local_nouns = local_nouns or {}
|
||||||
local_verbs = local_verbs or {}
|
local_verbs = local_verbs or {}
|
||||||
local o = {}
|
local o = {}
|
||||||
|
|
@ -74,7 +70,7 @@ function bc:init(my_address, local_nouns, local_verbs)
|
||||||
o.remote_listeners = {}
|
o.remote_listeners = {}
|
||||||
o.listening_remotes = {}
|
o.listening_remotes = {}
|
||||||
-- Modem listener
|
-- Modem listener
|
||||||
function modem_listener(localAddress, remoteAddress, port, dist, message)
|
function modem_listener(moden_msg, localAddress, remoteAddress, port, dist, message)
|
||||||
dbg = message
|
dbg = message
|
||||||
message = serializer.unserialize(message)
|
message = serializer.unserialize(message)
|
||||||
if port == CFG_PORT then
|
if port == CFG_PORT then
|
||||||
|
|
@ -83,10 +79,9 @@ function bc:init(my_address, local_nouns, local_verbs)
|
||||||
noun=message.noun,
|
noun=message.noun,
|
||||||
value=o.local_nouns[message.noun]
|
value=o.local_nouns[message.noun]
|
||||||
}
|
}
|
||||||
o.modem:send(remoteAddress, port, serializer.serialize(msg))
|
modem.send(remoteAddress, port, serializer.serialize(msg))
|
||||||
elseif message.ty == message_type.noun_response then
|
elseif message.ty == message_type.noun_response then
|
||||||
-- TODO: Make this a bit better, this is dumb
|
-- Ignore, this is handled via pull
|
||||||
o._nr = message.value
|
|
||||||
elseif message.ty == message_type.call_verb then
|
elseif message.ty == message_type.call_verb then
|
||||||
o.local_verbs[message.verb](o, message.param)
|
o.local_verbs[message.verb](o, message.param)
|
||||||
elseif message.ty == message_type.hello then
|
elseif message.ty == message_type.hello then
|
||||||
|
|
@ -98,7 +93,7 @@ function bc:init(my_address, local_nouns, local_verbs)
|
||||||
-- Check for potential dormant listeners
|
-- Check for potential dormant listeners
|
||||||
if o.remote_listeners[noun] ~= nil then
|
if o.remote_listeners[noun] ~= nil then
|
||||||
for id, listener in o.remote_listeners[noun]:iter() do
|
for id, listener in o.remote_listeners[noun]:iter() do
|
||||||
o.modem:send(remoteAddress, port, serializer.serialize({
|
modem.send(remoteAddress, port, serializer.serialize({
|
||||||
ty=message_type.request_listening,
|
ty=message_type.request_listening,
|
||||||
noun=noun,
|
noun=noun,
|
||||||
query=listener.query,
|
query=listener.query,
|
||||||
|
|
@ -117,7 +112,7 @@ function bc:init(my_address, local_nouns, local_verbs)
|
||||||
for verb in pairs(o.local_verbs) do
|
for verb in pairs(o.local_verbs) do
|
||||||
table.insert(myverbs, verb)
|
table.insert(myverbs, verb)
|
||||||
end
|
end
|
||||||
o.modem:send(remoteAddress, port, serializer.serialize({ty=message_type.hello_response, verbs=myverbs, nouns=mynouns}))
|
modem.send(remoteAddress, port, serializer.serialize({ty=message_type.hello_response, verbs=myverbs, nouns=mynouns}))
|
||||||
elseif message.ty == message_type.hello_response then
|
elseif message.ty == message_type.hello_response then
|
||||||
for i,verb in ipairs(message.verbs) do
|
for i,verb in ipairs(message.verbs) do
|
||||||
o.remote_verbs[verb] = remoteAddress
|
o.remote_verbs[verb] = remoteAddress
|
||||||
|
|
@ -136,13 +131,14 @@ function bc:init(my_address, local_nouns, local_verbs)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Change this for deployment VVV
|
-- Setup connections
|
||||||
o.modem = modem:init(my_address, modem_listener)
|
modem.open(CFG_PORT)
|
||||||
|
event.listen("modem_message", modem_listener)
|
||||||
-- Save listener function for deinit
|
-- Save listener function for deinit
|
||||||
o.modem_cb = modem_listener
|
o.modem_cb = modem_listener
|
||||||
-- Init local stuff
|
-- Init local stuff
|
||||||
o.local_verbs = local_verbs or {}
|
o.local_verbs = local_verbs
|
||||||
o.local_nouns = local_nouns or {}
|
o.local_nouns = local_nouns
|
||||||
-- Send own nouns and verbs and request all remotes to send theirs
|
-- Send own nouns and verbs and request all remotes to send theirs
|
||||||
local mynouns = {}
|
local mynouns = {}
|
||||||
for noun in pairs(local_nouns) do
|
for noun in pairs(local_nouns) do
|
||||||
|
|
@ -152,7 +148,7 @@ function bc:init(my_address, local_nouns, local_verbs)
|
||||||
for verb in pairs(local_verbs) do
|
for verb in pairs(local_verbs) do
|
||||||
table.insert(myverbs, verb)
|
table.insert(myverbs, verb)
|
||||||
end
|
end
|
||||||
o.modem:broadcast(CFG_PORT, serializer.serialize({ty=message_type.hello, verbs=myverbs, nouns=mynouns}))
|
modem.broadcast(CFG_PORT, serializer.serialize({ty=message_type.hello, verbs=myverbs, nouns=mynouns}))
|
||||||
return o
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -160,13 +156,19 @@ function bc:get_noun(n)
|
||||||
if self.local_nouns[n] ~= nil then -- This noun is local, makes it easy
|
if self.local_nouns[n] ~= nil then -- This noun is local, makes it easy
|
||||||
return self.local_nouns[n]
|
return self.local_nouns[n]
|
||||||
elseif self.remote_nouns[n] ~= nil then -- This noun is remote
|
elseif self.remote_nouns[n] ~= nil then -- This noun is remote
|
||||||
self.modem:send(self.remote_nouns[n], CFG_PORT, serializer.serialize({ty=message_type.request_noun, noun=n}))
|
modem.send(self.remote_nouns[n], CFG_PORT, serializer.serialize({ty=message_type.request_noun, noun=n}))
|
||||||
if self._nr == nil then
|
local i = 0
|
||||||
return nil
|
while i < 5 do
|
||||||
|
local _, _, remoteAddr, port, _, msg = event.pull("modem_message")
|
||||||
|
if port == CFG_PORT and remoteAddr == self.remote_nouns[n] then
|
||||||
|
message = serializer.unserialize(msg)
|
||||||
|
if message.ty == message_type.noun_response and message.noun == n then
|
||||||
|
return message.value
|
||||||
end
|
end
|
||||||
local value = self._nr
|
end
|
||||||
self._nr = nil -- Reset
|
i = i + 1
|
||||||
return value
|
end
|
||||||
|
return nil
|
||||||
else
|
else
|
||||||
-- Noun not found
|
-- Noun not found
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -207,7 +209,7 @@ function bc:set_noun(n, value)
|
||||||
then
|
then
|
||||||
self.local_nouns[n] = value -- Apply here, too, because else there could be glitches
|
self.local_nouns[n] = value -- Apply here, too, because else there could be glitches
|
||||||
-- Send update
|
-- Send update
|
||||||
self.modem:send(address, CFG_PORT, serializer.serialize({ty=message_type.listener_update, noun=n, value=value, id=id}))
|
modem.send(address, CFG_PORT, serializer.serialize({ty=message_type.listener_update, noun=n, value=value, id=id}))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -225,7 +227,7 @@ function bc:call_verb(v, param)
|
||||||
self.local_verbs[v](self, param)
|
self.local_verbs[v](self, param)
|
||||||
return true
|
return true
|
||||||
elseif self.remote_verbs[v] ~= nil then
|
elseif self.remote_verbs[v] ~= nil then
|
||||||
self.modem:send(self.remote_verbs[v], CFG_PORT, serializer.serialize({ty=message_type.call_verb, verb=v, param=param}))
|
modem.send(self.remote_verbs[v], CFG_PORT, serializer.serialize({ty=message_type.call_verb, verb=v, param=param}))
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
|
|
@ -245,7 +247,7 @@ function bc:listen_noun(n, query, qparam, callback)
|
||||||
self.remote_listeners[n] = self.remote_listeners[n] or List:new()
|
self.remote_listeners[n] = self.remote_listeners[n] or List:new()
|
||||||
local id = self.remote_listeners[n]:insert({query=query, qparam=qparam, callback=callback})
|
local id = self.remote_listeners[n]:insert({query=query, qparam=qparam, callback=callback})
|
||||||
-- Request remote listening
|
-- Request remote listening
|
||||||
self.modem:send(self.remote_nouns[n], CFG_PORT, serializer.serialize({ty=message_type.request_listening, noun=n, query=query, qparam=qparam, id=id}))
|
modem.send(self.remote_nouns[n], CFG_PORT, serializer.serialize({ty=message_type.request_listening, noun=n, query=query, qparam=qparam, id=id}))
|
||||||
return id
|
return id
|
||||||
else
|
else
|
||||||
-- Install it, with hope, that the node will come online later
|
-- Install it, with hope, that the node will come online later
|
||||||
|
|
@ -263,7 +265,7 @@ function bc:listen_cancel(n, id)
|
||||||
elseif self.remote_nouns[n] ~= nil then -- Remote listening
|
elseif self.remote_nouns[n] ~= nil then -- Remote listening
|
||||||
if self.remote_listeners[n] ~= nil then
|
if self.remote_listeners[n] ~= nil then
|
||||||
self.remote_listeners[n]:remove(id)
|
self.remote_listeners[n]:remove(id)
|
||||||
self.modem:send(self.remote_nouns[n], CFG_PORT, serializer.serialize({ty=message_type.request_stop_listening, noun=n, id=id}))
|
modem.send(self.remote_nouns[n], CFG_PORT, serializer.serialize({ty=message_type.request_stop_listening, noun=n, id=id}))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
error("Trying to cancel non existing listener")
|
error("Trying to cancel non existing listener")
|
||||||
|
|
|
||||||
21
component.lua
Normal file
21
component.lua
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
network = require("network")
|
||||||
|
|
||||||
|
component = {}
|
||||||
|
|
||||||
|
modem = {}
|
||||||
|
|
||||||
|
function modem.open(port)
|
||||||
|
-- Nothing
|
||||||
|
end
|
||||||
|
|
||||||
|
function modem.send(addr, port, msg)
|
||||||
|
network.send(addr, port, msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
function modem.broadcast(port, msg)
|
||||||
|
network.broadcast(port, msg)
|
||||||
|
end
|
||||||
|
|
||||||
|
component.modem = modem
|
||||||
|
|
||||||
|
return component
|
||||||
44
event.lua
Normal file
44
event.lua
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
network = require("network")
|
||||||
|
|
||||||
|
event = {}
|
||||||
|
|
||||||
|
addr_num = 0
|
||||||
|
last_msg = nil
|
||||||
|
|
||||||
|
function event.listen(event, callback)
|
||||||
|
if event ~= "modem_message" then
|
||||||
|
error("Event '"..event"' is not supported!")
|
||||||
|
end
|
||||||
|
addr = "A"..addr_num
|
||||||
|
addr_num = addr_num + 1
|
||||||
|
function ev_callback(ev, addr1, addr2, port, dist, msg)
|
||||||
|
last_msg = {
|
||||||
|
ev=ev,
|
||||||
|
addr1=addr1,
|
||||||
|
addr2=addr2,
|
||||||
|
port=port,
|
||||||
|
dist=dist,
|
||||||
|
msg=msg,
|
||||||
|
}
|
||||||
|
callback(ev, addr1, addr2, port, dist, msg)
|
||||||
|
end
|
||||||
|
network.register(addr, ev_callback)
|
||||||
|
end
|
||||||
|
|
||||||
|
function event.ignore(event, callback)
|
||||||
|
if event ~= "modem_message" then
|
||||||
|
error("Event '"..event"' is not supported!")
|
||||||
|
end
|
||||||
|
error("Not implemented yet")
|
||||||
|
end
|
||||||
|
|
||||||
|
function event.pull(event, callback)
|
||||||
|
-- Just return the last message and hope it is the
|
||||||
|
-- right one ...
|
||||||
|
if last_msg == nil then
|
||||||
|
error("No previous message found")
|
||||||
|
end
|
||||||
|
return last_msg.ev, last_msg.addr1, last_msg.addr2, last_msg.port, last_msg.dist, last_msg.msg
|
||||||
|
end
|
||||||
|
|
||||||
|
return event
|
||||||
37
modem.lua
37
modem.lua
|
|
@ -1,37 +0,0 @@
|
||||||
modem = {}
|
|
||||||
|
|
||||||
network = {}
|
|
||||||
|
|
||||||
function modem:init(addr, handler)
|
|
||||||
local o = {}
|
|
||||||
setmetatable(o, self)
|
|
||||||
self.__index = self
|
|
||||||
o.network = network
|
|
||||||
o.address = addr
|
|
||||||
o.network[addr] = handler
|
|
||||||
return o
|
|
||||||
end
|
|
||||||
|
|
||||||
function modem:open(port)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
function modem:send(address, port, msg)
|
|
||||||
if self.network[address] ~= nil then
|
|
||||||
self.network[address](address, self.address, port, 0, msg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function modem:broadcast(port, msg)
|
|
||||||
for addr in pairs(self.network) do
|
|
||||||
if addr ~= self.address then
|
|
||||||
self:send(addr, port, msg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function modem:remove_self()
|
|
||||||
self.network[self.address] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
return modem
|
|
||||||
59
network.lua
Normal file
59
network.lua
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
network = {}
|
||||||
|
|
||||||
|
nodes = {}
|
||||||
|
|
||||||
|
active_node = {}
|
||||||
|
|
||||||
|
function network.register(addr, callback)
|
||||||
|
if nodes[addr] ~= nil then
|
||||||
|
error("Address "..addr.." already registered!")
|
||||||
|
end
|
||||||
|
nodes[addr] = callback
|
||||||
|
|
||||||
|
active_node = {}
|
||||||
|
table.insert(active_node, addr)
|
||||||
|
end
|
||||||
|
|
||||||
|
function network.deregister(addr, callback)
|
||||||
|
if nodes[addr] ~= callback then
|
||||||
|
error("Callback was not registered for "..addr)
|
||||||
|
end
|
||||||
|
nodes[addr] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function network.send(addr, port, msg)
|
||||||
|
local callback = nodes[addr]
|
||||||
|
if callback == nil then
|
||||||
|
error("Sent message to offline node ("..addr..")!")
|
||||||
|
end
|
||||||
|
|
||||||
|
local current_node = active_node[#active_node]
|
||||||
|
-- Push target onto node-stack
|
||||||
|
table.insert(active_node, addr)
|
||||||
|
-- print("Sending from "..current_node.." to "..addr..": "..msg)
|
||||||
|
-- print(require("inspect").inspect(active_node))
|
||||||
|
callback("modem_message", addr, current_node, port, 0, msg)
|
||||||
|
-- Remove again
|
||||||
|
active_node[#active_node] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function network.broadcast(port, msg)
|
||||||
|
local current_node = active_node[#active_node]
|
||||||
|
-- print("Broadcasting from "..current_node)
|
||||||
|
for addr in pairs(nodes) do
|
||||||
|
if addr ~= current_node then
|
||||||
|
network.send(addr, port, msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function network.set_scene(addr)
|
||||||
|
active_node = {}
|
||||||
|
table.insert(active_node, addr)
|
||||||
|
end
|
||||||
|
|
||||||
|
function network.get_scene(addr)
|
||||||
|
return active_node[#active_node]
|
||||||
|
end
|
||||||
|
|
||||||
|
return network
|
||||||
21
scratch.lua
Normal file
21
scratch.lua
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
inspect = require("inspect").inspect
|
||||||
|
bc = require("bc")
|
||||||
|
network = require("network")
|
||||||
|
|
||||||
|
|
||||||
|
bc1 = bc:init({["light"]=true}, {["toggle_light"]=function(b)
|
||||||
|
b:set_noun("light", not b:get_noun("light"))
|
||||||
|
end})
|
||||||
|
a1 = network.get_scene()
|
||||||
|
bc2 = bc:init({}, {})
|
||||||
|
a2 = network.get_scene()
|
||||||
|
|
||||||
|
network.set_scene(a1)
|
||||||
|
print(true, bc1:call_verb("toggle_light"))
|
||||||
|
print(false, bc1:get_noun("light"))
|
||||||
|
|
||||||
|
network.set_scene(a2)
|
||||||
|
print(true, bc2:call_verb("toggle_light"))
|
||||||
|
|
||||||
|
network.set_scene(a1)
|
||||||
|
print(true, bc1:get_noun("light"))
|
||||||
120
test_bc.lua
120
test_bc.lua
|
|
@ -1,77 +1,99 @@
|
||||||
require "lunit"
|
require "lunit"
|
||||||
|
|
||||||
|
network = require("network")
|
||||||
bc = require("bc")
|
bc = require("bc")
|
||||||
ser = require("serialization")
|
ser = require("serialization")
|
||||||
|
|
||||||
module("test_bc", package.seeall, lunit.testcase)
|
module("test_bc", package.seeall, lunit.testcase)
|
||||||
|
|
||||||
function test_init()
|
function test_init()
|
||||||
local bci = bc:init("a1", {["light"]=false}, {["toggle_light"]=function() end})
|
local bci = bc:init({["light"]=false}, {["toggle_light"]=function() end})
|
||||||
assert_true(bci:has_noun("light"), "Nouns were not initialized")
|
assert_true(bci:has_noun("light"), "Nouns were not initialized")
|
||||||
assert_true(bci:has_verb("toggle_light"), "Verbs were not initialized")
|
assert_true(bci:has_verb("toggle_light"), "Verbs were not initialized")
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_set_get_noun()
|
function test_set_get_noun()
|
||||||
local bci = bc:init("a1", {["light"]=true}, {["toggle_light"]=function() end})
|
local bci = bc:init({["light"]=true}, {["toggle_light"]=function() end})
|
||||||
assert_equal(true, bci:get_noun("light"), "First get failed with wrong value")
|
assert_equal(true, bci:get_noun("light"), "First get failed with wrong value")
|
||||||
bci:set_noun("light", false)
|
bci:set_noun("light", false)
|
||||||
assert_equal(false, bci:get_noun("light"), "Second get failed with wrong value")
|
assert_equal(false, bci:get_noun("light"), "Second get failed with wrong value")
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_request_noun()
|
function test_request_noun()
|
||||||
local bci = bc:init("a1", {["light"]=true}, {["toggle_light"]=function() end})
|
local bci = bc:init({["light"]=true}, {["toggle_light"]=function() end})
|
||||||
|
local addr = network.get_scene()
|
||||||
local i = false
|
local i = false
|
||||||
local expct = true
|
local expct = true
|
||||||
remote = require("modem"):init("some_addr", function(laddr, raddr, p, d, msg)
|
|
||||||
|
network.register("tester0", function(m, laddr, raddr, p, d, msg)
|
||||||
m = ser.unserialize(msg)
|
m = ser.unserialize(msg)
|
||||||
if m.ty == 3 and m.noun == "light" and m.value == expct then
|
if m.ty == 3 and m.noun == "light" and m.value == expct then
|
||||||
i = true
|
i = true
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
remote:send("a1", 1234, ser.serialize({ty=1, noun="light"}))
|
|
||||||
|
network.send(addr, 1234, ser.serialize({ty=1, noun="light"}))
|
||||||
assert_true(i, "Noun response did not happen or was incorrect")
|
assert_true(i, "Noun response did not happen or was incorrect")
|
||||||
-- Reset and change noun
|
-- Reset and change noun
|
||||||
i = false
|
i = false
|
||||||
bci:set_noun("light", false)
|
bci:set_noun("light", false)
|
||||||
expct = false
|
expct = false
|
||||||
remote:send("a1", 1234, ser.serialize({ty=1, noun="light"}))
|
network.send(addr, 1234, ser.serialize({ty=1, noun="light"}))
|
||||||
assert_true(i, "Noun response did not happen or was incorrect")
|
assert_true(i, "Noun response did not happen or was incorrect")
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_call_verb()
|
function test_call_verb()
|
||||||
local bci = bc:init("a1", {["light"]=true}, {["toggle_light"]=function(b)
|
local bci = bc:init({["light"]=true}, {["toggle_light"]=function(b)
|
||||||
b:set_noun("light", not b:get_noun("light"))
|
b:set_noun("light", not b:get_noun("light"))
|
||||||
end})
|
end})
|
||||||
remote = require("modem"):init("some_addr", function(laddr, raddr, p, d, msg) end)
|
local addr = network.get_scene()
|
||||||
-- Call verb
|
-- Call verb
|
||||||
remote:send("a1", 1234, ser.serialize({ty=2, verb="toggle_light"}))
|
network.send(addr, 1234, ser.serialize({ty=2, verb="toggle_light"}))
|
||||||
assert_equal(false, bci:get_noun("light"), "Verb did not do its job")
|
assert_equal(false, bci:get_noun("light"), "Verb did not do its job")
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_multinode_call_verb()
|
function test_multinode_call_verb()
|
||||||
local bc1 = bc:init("a1", {["light"]=true}, {["toggle_light"]=function(b)
|
local bc1 = bc:init({["light0"]=true}, {["toggle_light0"]=function(b)
|
||||||
b:set_noun("light", not b:get_noun("light"))
|
b:set_noun("light0", not b:get_noun("light0"))
|
||||||
end})
|
end})
|
||||||
local bc2 = bc:init("a2", {}, {})
|
local a1 = network.get_scene()
|
||||||
assert_true(bc1:call_verb("toggle_light"))
|
local bc2 = bc:init({}, {})
|
||||||
assert_equal(false, bc1:get_noun("light"), "First verb invokation did not go to plan")
|
local a2 = network.get_scene()
|
||||||
assert_true(bc2:call_verb("toggle_light"))
|
|
||||||
assert_equal(true, bc1:get_noun("light"), "Second verb invokation did not go to plan")
|
network.set_scene(a1)
|
||||||
|
assert_true(bc1:call_verb("toggle_light0"))
|
||||||
|
assert_equal(false, bc1:get_noun("light0"), "First verb invocation did not go to plan")
|
||||||
|
|
||||||
|
network.set_scene(a2)
|
||||||
|
assert_true(bc2:call_verb("toggle_light0"))
|
||||||
|
|
||||||
|
network.set_scene(a1)
|
||||||
|
assert_equal(true, bc1:get_noun("light0"), "Second verb invocation did not go to plan")
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_multinode_get_noun()
|
function test_multinode_get_noun()
|
||||||
local key = "foobar"
|
local key = "foobar"
|
||||||
local bc1 = bc:init("a1", {["light"]=key}, {["toggle_light"]=function(b)
|
local bc1 = bc:init({["light1"]=key}, {["toggle_light1"]=function(b)
|
||||||
b:set_noun("light", not b:get_noun("light"))
|
b:set_noun("light1", not b:get_noun("light1"))
|
||||||
end})
|
end})
|
||||||
local bc2 = bc:init("a2", {}, {})
|
local a1 = network.get_scene()
|
||||||
assert_equal(key, bc1:get_noun("light"), "Local get failed")
|
local bc2 = bc:init({}, {})
|
||||||
assert_equal(key, bc2:get_noun("light"), "Remote get failed")
|
local a2 = network.get_scene()
|
||||||
|
|
||||||
|
network.set_scene(a1)
|
||||||
|
assert_equal(key, bc1:get_noun("light1"), "Local get failed")
|
||||||
|
|
||||||
|
network.set_scene(a2)
|
||||||
|
assert_equal(key, bc2:get_noun("light1"), "Remote get failed")
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_multinode_listening()
|
function test_multinode_listening()
|
||||||
local bc1 = bc:init("a1", {["foo"]=123}, {})
|
local bc1 = bc:init({["foo"]=123}, {})
|
||||||
local bc2 = bc:init("a2", {}, {})
|
local a1 = network.get_scene()
|
||||||
|
local bc2 = bc:init({}, {})
|
||||||
|
local a2 = network.get_scene()
|
||||||
|
|
||||||
|
network.set_scene(a1)
|
||||||
local i = false
|
local i = false
|
||||||
-- Local listening
|
-- Local listening
|
||||||
local id = bc1:listen_noun("foo", "onchange", nil, function(bc, foo)
|
local id = bc1:listen_noun("foo", "onchange", nil, function(bc, foo)
|
||||||
|
|
@ -81,21 +103,29 @@ function test_multinode_listening()
|
||||||
assert_true(i, "Local listening failed")
|
assert_true(i, "Local listening failed")
|
||||||
i = false
|
i = false
|
||||||
bc1:listen_cancel("foo", id) -- Test wether cancelling works
|
bc1:listen_cancel("foo", id) -- Test wether cancelling works
|
||||||
|
|
||||||
|
network.set_scene(a2)
|
||||||
local j = false
|
local j = false
|
||||||
local rid = bc2:listen_noun("foo", "onchange", nil, function(bc, foo)
|
local rid = bc2:listen_noun("foo", "onchange", nil, function(bc, foo)
|
||||||
j = true
|
j = true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
network.set_scene(a1)
|
||||||
bc1:set_noun("foo", 1234)
|
bc1:set_noun("foo", 1234)
|
||||||
assert_true(j, "Remote listening failed")
|
assert_true(j, "Remote listening failed")
|
||||||
assert_false(i, "Cancelling local listener failed")
|
assert_false(i, "Cancelling local listener failed")
|
||||||
|
|
||||||
|
network.set_scene(a2)
|
||||||
bc2:listen_cancel("foo", rid)
|
bc2:listen_cancel("foo", rid)
|
||||||
j = false
|
j = false
|
||||||
|
|
||||||
|
network.set_scene(a1)
|
||||||
bc1:set_noun("foo", 34)
|
bc1:set_noun("foo", 34)
|
||||||
assert_false(j, "Cancelling remote listener failed")
|
assert_false(j, "Cancelling remote listener failed")
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_listen_modes()
|
function test_listen_modes()
|
||||||
local bci = bc:init("a1", {["noun"]=10}, {})
|
local bci = bc:init({["noun"]=10}, {})
|
||||||
local i = false
|
local i = false
|
||||||
local id = 0
|
local id = 0
|
||||||
-- onchange
|
-- onchange
|
||||||
|
|
@ -158,62 +188,62 @@ function test_listen_modes()
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_get_unknown_noun()
|
function test_get_unknown_noun()
|
||||||
local bci = bc:init("a1")
|
local bci = bc:init()
|
||||||
|
|
||||||
assert_false(bci:has_noun("bar"))
|
assert_false(bci:has_noun("bar"))
|
||||||
assert_equal(nil, bci:get_noun("bar"))
|
assert_equal(nil, bci:get_noun("bar"))
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_get_offline_node()
|
-- function test_get_offline_node()
|
||||||
local bc1 = bc:init("a1")
|
-- local bc1 = bc:init()
|
||||||
local bc2 = bc:init("a2", {["foo"]=true})
|
-- local bc2 = bc:init({["foo"]=true})
|
||||||
|
--
|
||||||
-- Simulate node going offline
|
-- -- Simulate node going offline
|
||||||
bc2.modem:remove_self()
|
-- bc2.modem:remove_self()
|
||||||
bc2 = nil
|
-- bc2 = nil
|
||||||
|
--
|
||||||
local val = bc1:get_noun("foo")
|
-- local val = bc1:get_noun("foo")
|
||||||
assert_equal(nil, val)
|
-- assert_equal(nil, val)
|
||||||
end
|
-- end
|
||||||
|
|
||||||
function test_call_unknown_verb()
|
function test_call_unknown_verb()
|
||||||
local bci = bc:init("a1")
|
local bci = bc:init()
|
||||||
|
|
||||||
assert_false(bci:has_verb("unknown"))
|
assert_false(bci:has_verb("unknown"))
|
||||||
assert_equal(false, bci:call_verb("unknown"))
|
assert_equal(false, bci:call_verb("unknown"))
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_install_listen_on_unknown_noun()
|
function test_install_listen_on_unknown_noun()
|
||||||
local bci = bc:init("a1")
|
local bci = bc:init()
|
||||||
|
|
||||||
assert_false(bci:has_noun("unknown"))
|
assert_false(bci:has_noun("unknown"))
|
||||||
bci:listen_noun("unknown", "onchange", nil, function() end)
|
bci:listen_noun("unknown", "onchange", nil, function() end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_late_install()
|
function test_late_install()
|
||||||
local bc1 = bc:init("a1")
|
local bc1 = bc:init()
|
||||||
|
|
||||||
local i = false
|
local i = false
|
||||||
|
|
||||||
assert_false(bc1:has_noun("foo"))
|
assert_false(bc1:has_noun("foo123"))
|
||||||
bc1:listen_noun("foo", "onchange", nil, function()
|
bc1:listen_noun("foo123", "onchange", nil, function()
|
||||||
i = true
|
i = true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local bc2 = bc:init("a2", {["foo"] = 123})
|
local bc2 = bc:init({["foo123"] = 123})
|
||||||
bc2:set_noun("foo", 321)
|
bc2:set_noun("foo123", 321)
|
||||||
|
|
||||||
assert_true(i, "Listener was not called")
|
assert_true(i, "Listener was not called")
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_verb_multicall_bug()
|
function test_verb_multicall_bug()
|
||||||
local var = 0
|
local var = 0
|
||||||
local bc1 = bc:init("a1", nil, {
|
local bc1 = bc:init(nil, {
|
||||||
["verb"] = function(bc, foo)
|
["verb"] = function(bc, foo)
|
||||||
var = var + foo
|
var = var + foo
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
local bc2 = bc:init("a2")
|
local bc2 = bc:init()
|
||||||
bc2:call_verb("verb", 1)
|
bc2:call_verb("verb", 1)
|
||||||
assert_equal(1, var, "Verb was not called correctly")
|
assert_equal(1, var, "Verb was not called correctly")
|
||||||
bc2:call_verb("verb", 2)
|
bc2:call_verb("verb", 2)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue