mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
#497 unload apps when required connections are lost
This commit is contained in:
parent
0b97d4d4b0
commit
00cacd6d0a
@ -102,7 +102,8 @@ pocket.APP_ID = APP_ID
|
|||||||
---@param render_queue mqueue
|
---@param render_queue mqueue
|
||||||
function pocket.init_nav(render_queue)
|
function pocket.init_nav(render_queue)
|
||||||
local self = {
|
local self = {
|
||||||
pane = nil, ---@type graphics_element
|
pane = nil, ---@type graphics_element
|
||||||
|
sidebar = nil, ---@type graphics_element
|
||||||
apps = {},
|
apps = {},
|
||||||
containers = {},
|
containers = {},
|
||||||
help_map = {},
|
help_map = {},
|
||||||
@ -117,23 +118,22 @@ function pocket.init_nav(render_queue)
|
|||||||
|
|
||||||
-- set the root pane element to switch between apps with
|
-- set the root pane element to switch between apps with
|
||||||
---@param root_pane graphics_element
|
---@param root_pane graphics_element
|
||||||
function nav.set_pane(root_pane)
|
function nav.set_pane(root_pane) self.pane = root_pane end
|
||||||
self.pane = root_pane
|
|
||||||
end
|
|
||||||
|
|
||||||
function nav.set_sidebar(sidebar)
|
-- link sidebar element
|
||||||
self.sidebar = sidebar
|
---@param sidebar graphics_element
|
||||||
end
|
function nav.set_sidebar(sidebar) self.sidebar = sidebar end
|
||||||
|
|
||||||
-- register an app
|
-- register an app
|
||||||
---@param app_id POCKET_APP_ID app ID
|
---@param app_id POCKET_APP_ID app ID
|
||||||
---@param container graphics_element element that contains this app (usually a Div)
|
---@param container graphics_element element that contains this app (usually a Div)
|
||||||
---@param pane graphics_element? multipane if this is a simple paned app, then nav_to must be a number
|
---@param pane graphics_element? multipane if this is a simple paned app, then nav_to must be a number
|
||||||
function nav.register_app(app_id, container, pane)
|
---@param require_sv boolean? true or false/nil otherwise to specifiy if this app should be unloaded when the supervisor connection is lost
|
||||||
|
---@param require_api boolean? true or false/nil otherwise to specifiy if this app should be unloaded when the api connection is lost
|
||||||
|
function nav.register_app(app_id, container, pane, require_sv, require_api)
|
||||||
---@class pocket_app
|
---@class pocket_app
|
||||||
local app = {
|
local app = {
|
||||||
loaded = false,
|
loaded = false,
|
||||||
load = nil,
|
|
||||||
cur_page = nil, ---@type nav_tree_page
|
cur_page = nil, ---@type nav_tree_page
|
||||||
pane = pane,
|
pane = pane,
|
||||||
paned_pages = {},
|
paned_pages = {},
|
||||||
@ -141,6 +141,11 @@ function pocket.init_nav(render_queue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.load = function () app.loaded = true end
|
app.load = function () app.loaded = true end
|
||||||
|
app.unload = function () app.loaded = false end
|
||||||
|
|
||||||
|
-- check which connections this requires
|
||||||
|
---@return boolean requires_sv, boolean requires_api
|
||||||
|
function app.check_requires() return require_sv or false, require_api or false end
|
||||||
|
|
||||||
-- delayed set of the pane if it wasn't ready at the start
|
-- delayed set of the pane if it wasn't ready at the start
|
||||||
---@param root_pane graphics_element multipane
|
---@param root_pane graphics_element multipane
|
||||||
@ -155,13 +160,22 @@ function pocket.init_nav(render_queue)
|
|||||||
|
|
||||||
-- function to run on initial load into memory
|
-- function to run on initial load into memory
|
||||||
---@param on_load function callback
|
---@param on_load function callback
|
||||||
function app.set_on_load(on_load)
|
function app.set_load(on_load)
|
||||||
app.load = function ()
|
app.load = function ()
|
||||||
on_load()
|
on_load()
|
||||||
app.loaded = true
|
app.loaded = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- function to run to close out the app
|
||||||
|
---@param on_unload function callback
|
||||||
|
function app.set_unload(on_unload)
|
||||||
|
app.unload = function ()
|
||||||
|
on_unload()
|
||||||
|
app.loaded = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- if a pane was provided, this will switch between numbered pages
|
-- if a pane was provided, this will switch between numbered pages
|
||||||
---@param idx integer page index
|
---@param idx integer page index
|
||||||
function app.switcher(idx)
|
function app.switcher(idx)
|
||||||
@ -207,6 +221,12 @@ function pocket.init_nav(render_queue)
|
|||||||
return page
|
return page
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- delete paned pages and clear the current page
|
||||||
|
function app.delete_pages()
|
||||||
|
app.paned_pages = {}
|
||||||
|
app.cur_page = nil
|
||||||
|
end
|
||||||
|
|
||||||
-- get the currently active page
|
-- get the currently active page
|
||||||
function app.get_current_page() return app.cur_page end
|
function app.get_current_page() return app.cur_page end
|
||||||
|
|
||||||
@ -251,6 +271,22 @@ function pocket.init_nav(render_queue)
|
|||||||
self.apps[app_id].load()
|
self.apps[app_id].load()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- unload api-dependent apps
|
||||||
|
function nav.unload_api()
|
||||||
|
for _, app in pairs(self.apps) do
|
||||||
|
local _, api = app.check_requires()
|
||||||
|
if app.loaded and api then app.unload() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- unload supervisor-dependent apps
|
||||||
|
function nav.unload_sv()
|
||||||
|
for _, app in pairs(self.apps) do
|
||||||
|
local sv, _ = app.check_requires()
|
||||||
|
if app.loaded and sv then app.unload() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- get a list of the app containers (usually Div elements)
|
-- get a list of the app containers (usually Div elements)
|
||||||
function nav.get_containers() return self.containers end
|
function nav.get_containers() return self.containers end
|
||||||
|
|
||||||
@ -300,7 +336,8 @@ end
|
|||||||
---@param nic nic network interface device
|
---@param nic nic network interface device
|
||||||
---@param sv_watchdog watchdog
|
---@param sv_watchdog watchdog
|
||||||
---@param api_watchdog watchdog
|
---@param api_watchdog watchdog
|
||||||
function pocket.comms(version, nic, sv_watchdog, api_watchdog)
|
---@param nav pocket_nav
|
||||||
|
function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
||||||
local self = {
|
local self = {
|
||||||
sv = {
|
sv = {
|
||||||
linked = false,
|
linked = false,
|
||||||
@ -399,6 +436,7 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog)
|
|||||||
-- close connection to the supervisor
|
-- close connection to the supervisor
|
||||||
function public.close_sv()
|
function public.close_sv()
|
||||||
sv_watchdog.cancel()
|
sv_watchdog.cancel()
|
||||||
|
nav.unload_sv()
|
||||||
self.sv.linked = false
|
self.sv.linked = false
|
||||||
self.sv.r_seq_num = nil
|
self.sv.r_seq_num = nil
|
||||||
self.sv.addr = comms.BROADCAST
|
self.sv.addr = comms.BROADCAST
|
||||||
@ -408,6 +446,7 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog)
|
|||||||
-- close connection to coordinator API server
|
-- close connection to coordinator API server
|
||||||
function public.close_api()
|
function public.close_api()
|
||||||
api_watchdog.cancel()
|
api_watchdog.cancel()
|
||||||
|
nav.unload_api()
|
||||||
self.api.linked = false
|
self.api.linked = false
|
||||||
self.api.r_seq_num = nil
|
self.api.r_seq_num = nil
|
||||||
self.api.addr = comms.BROADCAST
|
self.api.addr = comms.BROADCAST
|
||||||
@ -589,6 +628,7 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog)
|
|||||||
elseif packet.type == MGMT_TYPE.CLOSE then
|
elseif packet.type == MGMT_TYPE.CLOSE then
|
||||||
-- handle session close
|
-- handle session close
|
||||||
api_watchdog.cancel()
|
api_watchdog.cancel()
|
||||||
|
nav.unload_api()
|
||||||
self.api.linked = false
|
self.api.linked = false
|
||||||
self.api.r_seq_num = nil
|
self.api.r_seq_num = nil
|
||||||
self.api.addr = comms.BROADCAST
|
self.api.addr = comms.BROADCAST
|
||||||
@ -694,6 +734,7 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog)
|
|||||||
elseif packet.type == MGMT_TYPE.CLOSE then
|
elseif packet.type == MGMT_TYPE.CLOSE then
|
||||||
-- handle session close
|
-- handle session close
|
||||||
sv_watchdog.cancel()
|
sv_watchdog.cancel()
|
||||||
|
nav.unload_sv()
|
||||||
self.sv.linked = false
|
self.sv.linked = false
|
||||||
self.sv.r_seq_num = nil
|
self.sv.r_seq_num = nil
|
||||||
self.sv.addr = comms.BROADCAST
|
self.sv.addr = comms.BROADCAST
|
||||||
|
@ -122,6 +122,8 @@ local function main()
|
|||||||
-- setup system
|
-- setup system
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
|
smem_sys.nav = pocket.init_nav(__shared_memory.q.mq_render)
|
||||||
|
|
||||||
-- message authentication init
|
-- message authentication init
|
||||||
if type(config.AuthKey) == "string" and string.len(config.AuthKey) > 0 then
|
if type(config.AuthKey) == "string" and string.len(config.AuthKey) > 0 then
|
||||||
network.init_mac(config.AuthKey)
|
network.init_mac(config.AuthKey)
|
||||||
@ -145,11 +147,10 @@ local function main()
|
|||||||
|
|
||||||
-- create network interface then setup comms
|
-- create network interface then setup comms
|
||||||
smem_sys.nic = network.nic(smem_dev.modem)
|
smem_sys.nic = network.nic(smem_dev.modem)
|
||||||
smem_sys.pocket_comms = pocket.comms(POCKET_VERSION, smem_sys.nic, smem_sys.sv_wd, smem_sys.api_wd)
|
smem_sys.pocket_comms = pocket.comms(POCKET_VERSION, smem_sys.nic, smem_sys.sv_wd, smem_sys.api_wd, smem_sys.nav)
|
||||||
log.debug("startup> comms init")
|
log.debug("startup> comms init")
|
||||||
|
|
||||||
-- init nav and I/O handler
|
-- init I/O control
|
||||||
smem_sys.nav = pocket.init_nav(__shared_memory.q.mq_render)
|
|
||||||
iocontrol.init_core(smem_sys.pocket_comms, smem_sys.nav)
|
iocontrol.init_core(smem_sys.pocket_comms, smem_sys.nav)
|
||||||
|
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local mqueue = require("scada-common.mqueue")
|
local mqueue = require("scada-common.mqueue")
|
||||||
local ppm = require("scada-common.ppm")
|
local ppm = require("scada-common.ppm")
|
||||||
local tcd = require("scada-common.tcd")
|
local tcd = require("scada-common.tcd")
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local pocket = require("pocket.pocket")
|
local pocket = require("pocket.pocket")
|
||||||
local renderer = require("pocket.renderer")
|
local renderer = require("pocket.renderer")
|
||||||
|
|
||||||
local core = require("graphics.core")
|
local core = require("graphics.core")
|
||||||
|
|
||||||
local threads = {}
|
local threads = {}
|
||||||
|
|
||||||
|
@ -55,16 +55,21 @@ local function new_view(root)
|
|||||||
local btn_active = cpair(colors.white, colors.black)
|
local btn_active = cpair(colors.white, colors.black)
|
||||||
local btn_disable = cpair(colors.gray, colors.black)
|
local btn_disable = cpair(colors.gray, colors.black)
|
||||||
|
|
||||||
local list = {
|
app.set_sidebar({{ label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = function () db.nav.open_app(APP_ID.ROOT) end }})
|
||||||
{ label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = function () db.nav.open_app(APP_ID.ROOT) end },
|
|
||||||
{ label = " \x14 ", color = core.cpair(colors.black, colors.cyan), callback = function () app.switcher(1) end },
|
|
||||||
{ label = "__?", color = core.cpair(colors.black, colors.lightGray), callback = function () app.switcher(2) end }
|
|
||||||
}
|
|
||||||
|
|
||||||
app.set_sidebar(list)
|
local page_div = nil ---@type nil|graphics_element
|
||||||
|
|
||||||
|
-- load the app (create the elements)
|
||||||
local function load()
|
local function load()
|
||||||
local page_div = Div{parent=main,y=2}
|
local list = {
|
||||||
|
{ label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = function () db.nav.open_app(APP_ID.ROOT) end },
|
||||||
|
{ label = " \x14 ", color = core.cpair(colors.black, colors.cyan), callback = function () app.switcher(1) end },
|
||||||
|
{ label = "__?", color = core.cpair(colors.black, colors.lightGray), callback = function () app.switcher(2) end }
|
||||||
|
}
|
||||||
|
|
||||||
|
app.set_sidebar(list)
|
||||||
|
|
||||||
|
page_div = Div{parent=main,y=2}
|
||||||
local p_width = page_div.get_width() - 2
|
local p_width = page_div.get_width() - 2
|
||||||
|
|
||||||
local main_page = app.new_page(nil, 1)
|
local main_page = app.new_page(nil, 1)
|
||||||
@ -219,7 +224,22 @@ local function new_view(root)
|
|||||||
load_pane.set_value(2)
|
load_pane.set_value(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
app.set_on_load(load)
|
-- delete the elements and switch back to the loading screen
|
||||||
|
local function unload()
|
||||||
|
if page_div then
|
||||||
|
page_div.delete()
|
||||||
|
page_div = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = function () db.nav.open_app(APP_ID.ROOT) end } })
|
||||||
|
app.delete_pages()
|
||||||
|
|
||||||
|
-- show loading screen
|
||||||
|
load_pane.set_value(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
app.set_load(load)
|
||||||
|
app.set_unload(unload)
|
||||||
|
|
||||||
return main
|
return main
|
||||||
end
|
end
|
||||||
|
@ -56,7 +56,7 @@ local function new_view(root)
|
|||||||
|
|
||||||
local frame = Div{parent=root,x=1,y=1}
|
local frame = Div{parent=root,x=1,y=1}
|
||||||
|
|
||||||
local app = db.nav.register_app(APP_ID.UNITS, frame)
|
local app = db.nav.register_app(APP_ID.UNITS, frame, nil, false, true)
|
||||||
|
|
||||||
local load_div = Div{parent=frame,x=1,y=1}
|
local load_div = Div{parent=frame,x=1,y=1}
|
||||||
local main = Div{parent=frame,x=1,y=1}
|
local main = Div{parent=frame,x=1,y=1}
|
||||||
@ -66,13 +66,15 @@ local function new_view(root)
|
|||||||
|
|
||||||
local load_pane = MultiPane{parent=main,x=1,y=1,panes={load_div,main}}
|
local load_pane = MultiPane{parent=main,x=1,y=1,panes={load_div,main}}
|
||||||
|
|
||||||
TextBox{parent=main,y=4,text="Loading...",height=1,alignment=ALIGN.CENTER}
|
app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = function () db.nav.open_app(APP_ID.ROOT) end } })
|
||||||
|
|
||||||
local btn_fg_bg = cpair(colors.yellow, colors.black)
|
local btn_fg_bg = cpair(colors.yellow, colors.black)
|
||||||
local btn_active = cpair(colors.white, colors.black)
|
local btn_active = cpair(colors.white, colors.black)
|
||||||
|
|
||||||
local nav_links = {}
|
local nav_links = {}
|
||||||
|
local page_div = nil ---@type nil|graphics_element
|
||||||
|
|
||||||
|
-- set sidebar to display unit-specific fields based on a specified unit
|
||||||
local function set_sidebar(id)
|
local function set_sidebar(id)
|
||||||
local unit = db.units[id] ---@type pioctl_unit
|
local unit = db.units[id] ---@type pioctl_unit
|
||||||
|
|
||||||
@ -96,8 +98,9 @@ local function new_view(root)
|
|||||||
app.set_sidebar(list)
|
app.set_sidebar(list)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- load the app (create the elements)
|
||||||
local function load()
|
local function load()
|
||||||
local page_div = Div{parent=main,y=2,width=main.get_width()}
|
page_div = Div{parent=main,y=2,width=main.get_width()}
|
||||||
|
|
||||||
local panes = {}
|
local panes = {}
|
||||||
|
|
||||||
@ -376,7 +379,22 @@ local function new_view(root)
|
|||||||
load_pane.set_value(2)
|
load_pane.set_value(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
app.set_on_load(load)
|
-- delete the elements and switch back to the loading screen
|
||||||
|
local function unload()
|
||||||
|
if page_div then
|
||||||
|
page_div.delete()
|
||||||
|
page_div = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
app.set_sidebar({ { label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = function () db.nav.open_app(APP_ID.ROOT) end } })
|
||||||
|
app.delete_pages()
|
||||||
|
|
||||||
|
-- show loading screen
|
||||||
|
load_pane.set_value(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
app.set_load(load)
|
||||||
|
app.set_unload(unload)
|
||||||
|
|
||||||
return main
|
return main
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user