From b17d044bb58292000fe72694ff3a011a47add7a4 Mon Sep 17 00:00:00 2001 From: Rahix Date: Mon, 10 Apr 2017 16:52:41 +0200 Subject: [PATCH] Initial --- _bc_backend.lua | 75 +++++++++++++++++++++++++++++++++++ bc.lua | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 _bc_backend.lua create mode 100644 bc.lua diff --git a/_bc_backend.lua b/_bc_backend.lua new file mode 100644 index 000000000000..95db0efdbbf3 --- /dev/null +++ b/_bc_backend.lua @@ -0,0 +1,75 @@ +_bc_backend = { local_addr = "address_light", power = 12, iscb = false, cbid = 0, cbn = "" } + +function _bc_backend:init(cb_handler) + local o = {} + setmetatable(o, self) + self.__index = self + o.cb_handler = cb_handler + 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 diff --git a/bc.lua b/bc.lua new file mode 100644 index 000000000000..4cc0f4df14c1 --- /dev/null +++ b/bc.lua @@ -0,0 +1,101 @@ +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