#634 moved most monitor connect handling to the backplane and made display indicators on the front panel 3-state

This commit is contained in:
Mikayla
2025-11-07 17:43:12 +00:00
parent 8c8d3faf72
commit 25207f39c0
5 changed files with 71 additions and 61 deletions

View File

@@ -80,7 +80,7 @@ function backplane.init_displays(config)
log.info("BKPLN: DISPLAY LINK_" .. util.trinary(disp, "UP", "DOWN") .. " MAIN/" .. iface)
iocontrol.fp_monitor_state("main", disp ~= nil)
iocontrol.fp_monitor_state("main", util.trinary(disp, 2, 1))
if not disp then
return false, "Main monitor is not connected."
@@ -103,7 +103,7 @@ function backplane.init_displays(config)
log.info("BKPLN: DISPLAY LINK_" .. util.trinary(disp, "UP", "DOWN") .. " FLOW/" .. iface)
iocontrol.fp_monitor_state("flow", disp ~= nil)
iocontrol.fp_monitor_state("flow", util.trinary(disp, 2, 1))
if not disp then
return false, "Flow monitor is not connected."
@@ -127,7 +127,7 @@ function backplane.init_displays(config)
log.info("BKPLN: DISPLAY LINK_" .. util.trinary(disp, "UP", "DOWN") .. " UNIT_" .. i .. "/" .. iface)
iocontrol.fp_monitor_state(i, disp ~= nil)
iocontrol.fp_monitor_state(i, util.trinary(disp, 2, 1))
if not disp then
return false, "Unit " .. i .. " monitor is not connected."
@@ -297,7 +297,46 @@ function backplane.attach(type, device, iface)
end
elseif type == "monitor" then
---@cast device Monitor
_bp.smem.q.mq_render.push_data(MQ__RENDER_DATA.MON_CONNECT, { name = iface, device = device })
local is_used = false
log.info("BKPLN: DISPLAY LINK_UP " .. iface)
if _bp.displays.main_iface == iface then
is_used = true
_bp.displays.main = device
log.info("BKPLN: main display connected")
iocontrol.fp_monitor_state("main", 2)
elseif _bp.displays.flow_iface == iface then
is_used = true
_bp.displays.flow = device
log.info("BKPLN: flow display connected")
iocontrol.fp_monitor_state("flow", 2)
else
for idx, monitor in ipairs(_bp.displays.unit_ifaces) do
if monitor == iface then
is_used = true
_bp.displays.unit_displays[idx] = device
log.info("BKPLN: unit " .. idx .. " display connected")
iocontrol.fp_monitor_state(idx, 2)
break
end
end
end
-- notify renderer if it is using it
if is_used then
log_sys(util.c("configured monitor ", iface, " connected"))
_bp.smem.q.mq_render.push_data(MQ__RENDER_DATA.MON_CONNECT, iface)
else
log_sys(util.c("unused monitor ", iface, " connected"))
end
elseif type == "speaker" then
---@cast device Speaker
log_sys("alarm sounder speaker reconnected")
@@ -393,25 +432,25 @@ function backplane.detach(type, device, iface)
local is_used = false
log.info("BKPLN: MONITOR LINK_DOWN " .. iface)
log.info("BKPLN: DISPLAY LINK_DOWN " .. iface)
if _bp.displays.main == device then
is_used = true
log.info("BKPLN: lost the main display")
iocontrol.fp_monitor_state("main", false)
log.info("BKPLN: main display disconnected")
iocontrol.fp_monitor_state("main", 1)
elseif _bp.displays.flow == device then
is_used = true
log.info("BKPLN: lost the flow display")
iocontrol.fp_monitor_state("flow", false)
log.info("BKPLN: flow display disconnected")
iocontrol.fp_monitor_state("flow", 1)
else
for idx, monitor in pairs(_bp.displays.unit_displays) do
if monitor == device then
is_used = true
log.info("BKPLN: lost the unit " .. idx .. " display")
iocontrol.fp_monitor_state(idx, false)
log.info("BKPLN: unit " .. idx .. " display disconnected")
iocontrol.fp_monitor_state(idx, 1)
break
end
end

View File

@@ -308,6 +308,7 @@ function iocontrol.fp_link_state(state) io.fp.ps.publish("link_state", state) en
-- report monitor connection state
---@param id string|integer unit ID for unit monitor, "main" for main monitor, or "flow" for flow monitor
---@param connected 1|2|3 1 for disconnected, 2 for connected but no view (may not fit), 3 for connected with view shown
function iocontrol.fp_monitor_state(id, connected)
local name = nil

View File

@@ -308,39 +308,10 @@ end
-- handle a monitor peripheral being reconnected
---@param name string monitor name
---@param device Monitor monitor
---@return boolean is_used if the monitor is one of the configured monitors
function renderer.handle_reconnect(name, device)
local is_used = false
if not engine.monitors then return false end
function renderer.handle_reconnect(name)
-- note: handle_resize is a more adaptive way of re-initializing a connected monitor
-- since it can handle a monitor being reconnected that isn't the right size
if engine.monitors.main_iface == name then
is_used = true
engine.monitors.main = device
renderer.handle_resize(name)
elseif engine.monitors.flow_iface == name then
is_used = true
engine.monitors.flow = device
renderer.handle_resize(name)
else
for idx, monitor in ipairs(engine.monitors.unit_ifaces) do
if monitor == name then
is_used = true
engine.monitors.unit_displays[idx] = device
renderer.handle_resize(name)
break
end
end
end
return is_used
renderer.handle_resize(name)
end
-- handle a monitor being resized<br>
@@ -372,7 +343,7 @@ function renderer.handle_resize(name)
ui.main_display = nil
end
iocontrol.fp_monitor_state("main", true)
iocontrol.fp_monitor_state("main", 2)
engine.dmesg_window.setVisible(not engine.ui_ready)
@@ -384,6 +355,8 @@ function renderer.handle_resize(name)
end)
if ok then
iocontrol.fp_monitor_state("main", 3)
log_render("main view re-draw completed in " .. (util.time_ms() - draw_start) .. "ms")
else
if ui.main_display then
@@ -393,7 +366,6 @@ function renderer.handle_resize(name)
_print_too_small(device)
iocontrol.fp_monitor_state("main", false)
is_ok = false
end
else engine.dmesg_window.redraw() end
@@ -410,7 +382,7 @@ function renderer.handle_resize(name)
ui.flow_display = nil
end
iocontrol.fp_monitor_state("flow", true)
iocontrol.fp_monitor_state("flow", 2)
if engine.ui_ready then
local draw_start = util.time_ms()
@@ -420,6 +392,8 @@ function renderer.handle_resize(name)
end)
if ok then
iocontrol.fp_monitor_state("flow", 3)
log_render("flow view re-draw completed in " .. (util.time_ms() - draw_start) .. "ms")
else
if ui.flow_display then
@@ -429,7 +403,6 @@ function renderer.handle_resize(name)
_print_too_small(device)
iocontrol.fp_monitor_state("flow", false)
is_ok = false
end
end
@@ -448,7 +421,7 @@ function renderer.handle_resize(name)
ui.unit_displays[idx] = nil
end
iocontrol.fp_monitor_state(idx, true)
iocontrol.fp_monitor_state(idx, 2)
if engine.ui_ready then
local draw_start = util.time_ms()
@@ -458,6 +431,8 @@ function renderer.handle_resize(name)
end)
if ok then
iocontrol.fp_monitor_state(idx, 3)
log_render("unit " .. idx .. " view re-draw completed in " .. (util.time_ms() - draw_start) .. "ms")
else
if ui.unit_displays[idx] then
@@ -467,7 +442,6 @@ function renderer.handle_resize(name)
_print_too_small(device)
iocontrol.fp_monitor_state(idx, false)
is_ok = false
end
end

View File

@@ -257,11 +257,7 @@ function threads.thread__render(smem)
if cmd.key == MQ__RENDER_DATA.MON_CONNECT then
-- monitor connected
if renderer.handle_reconnect(cmd.val.name, cmd.val.device) then
log_sys(util.c("configured monitor ", cmd.val.name, " reconnected"))
else
log_sys(util.c("unused monitor ", cmd.val.name, " connected"))
end
renderer.handle_reconnect(cmd.val)
elseif cmd.key == MQ__RENDER_DATA.MON_DISCONNECT then
-- monitor disconnected
renderer.handle_disconnect(cmd.val)

View File

@@ -114,19 +114,19 @@ local function init(panel, num_units)
local comp_id = util.sprintf("(%d)", os.getComputerID())
TextBox{parent=system,x=9,y=4,width=6,text=comp_id,fg_bg=style.fp.disabled_fg}
local monitors = Div{parent=main_page,width=16,height=17,x=18,y=2}
local displays = Div{parent=main_page,width=16,height=17,x=18,y=2}
local main_monitor = LED{parent=monitors,label="MAIN MONITOR",colors=led_grn}
main_monitor.register(ps, "main_monitor", main_monitor.update)
local main_disp = LEDPair{parent=displays,label="MAIN DISPLAY",off=style.fp_ind_bkg,c1=colors.red,c2=colors.green}
main_disp.register(ps, "main_monitor", main_disp.update)
local flow_monitor = LED{parent=monitors,label="FLOW MONITOR",colors=led_grn}
flow_monitor.register(ps, "flow_monitor", flow_monitor.update)
local flow_disp = LEDPair{parent=displays,label="FLOW DISPLAY",off=style.fp_ind_bkg,c1=colors.red,c2=colors.green}
flow_disp.register(ps, "flow_monitor", flow_disp.update)
monitors.line_break()
displays.line_break()
for i = 1, num_units do
local unit_monitor = LED{parent=monitors,label="UNIT "..i.." MONITOR",colors=led_grn}
unit_monitor.register(ps, "unit_monitor_" .. i, unit_monitor.update)
local unit_disp = LEDPair{parent=displays,label="UNIT "..i.." DISPLAY",off=style.fp_ind_bkg,c1=colors.red,c2=colors.green}
unit_disp.register(ps, "unit_monitor_" .. i, unit_disp.update)
end
--