#497 unload apps when required connections are lost

This commit is contained in:
Mikayla 2024-06-14 16:10:04 +00:00
parent 0b97d4d4b0
commit 00cacd6d0a
5 changed files with 114 additions and 34 deletions

View File

@ -103,6 +103,7 @@ pocket.APP_ID = APP_ID
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

View File

@ -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)
---------------------------------------- ----------------------------------------

View File

@ -55,6 +55,12 @@ 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)
app.set_sidebar({{ label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = function () db.nav.open_app(APP_ID.ROOT) end }})
local page_div = nil ---@type nil|graphics_element
-- load the app (create the elements)
local function load()
local list = { local list = {
{ 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 = " \x14 ", color = core.cpair(colors.black, colors.cyan), callback = function () app.switcher(1) end },
@ -63,8 +69,7 @@ local function new_view(root)
app.set_sidebar(list) app.set_sidebar(list)
local function load() page_div = Div{parent=main,y=2}
local 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

View File

@ -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