Merge pull request #548 from MikaylaFischler/updated-annotations

Updated Annotations
This commit is contained in:
Mikayla 2024-09-28 18:24:08 -04:00 committed by GitHub
commit 4e3330d4b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
138 changed files with 1568 additions and 1643 deletions

View File

@ -13,20 +13,20 @@ local util = require("scada-common.util")
local core = require("graphics.core") local core = require("graphics.core")
local themes = require("graphics.themes") local themes = require("graphics.themes")
local DisplayBox = require("graphics.elements.displaybox") local DisplayBox = require("graphics.elements.DisplayBox")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local ListBox = require("graphics.elements.listbox") local ListBox = require("graphics.elements.ListBox")
local MultiPane = require("graphics.elements.multipane") local MultiPane = require("graphics.elements.MultiPane")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local CheckBox = require("graphics.elements.controls.checkbox") local Checkbox = require("graphics.elements.controls.Checkbox")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local RadioButton = require("graphics.elements.controls.radio_button") local RadioButton = require("graphics.elements.controls.RadioButton")
local NumberField = require("graphics.elements.form.number_field") local NumberField = require("graphics.elements.form.NumberField")
local TextField = require("graphics.elements.form.text_field") local TextField = require("graphics.elements.form.TextField")
local IndLight = require("graphics.elements.indicators.light") local IndLight = require("graphics.elements.indicators.IndicatorLight")
local println = util.println local println = util.println
local tri = util.trinary local tri = util.trinary
@ -71,7 +71,7 @@ local tool_ctl = {
net_listen = false, net_listen = false,
sv_addr = comms.BROADCAST, sv_addr = comms.BROADCAST,
sv_seq_num = util.time_ms() * 10, sv_seq_num = util.time_ms() * 10,
sv_cool_conf = nil, ---@type table list of boiler & turbine counts sv_cool_conf = nil, ---@type [ integer, integer ][] list of boiler & turbine counts
show_sv_cfg = nil, ---@type function show_sv_cfg = nil, ---@type function
start_fail = 0, start_fail = 0,
@ -81,36 +81,36 @@ local tool_ctl = {
importing_legacy = false, importing_legacy = false,
jumped_to_color = false, jumped_to_color = false,
view_cfg = nil, ---@type graphics_element view_cfg = nil, ---@type PushButton
color_cfg = nil, ---@type graphics_element color_cfg = nil, ---@type PushButton
color_next = nil, ---@type graphics_element color_next = nil, ---@type PushButton
color_apply = nil, ---@type graphics_element color_apply = nil, ---@type PushButton
settings_apply = nil, ---@type graphics_element settings_apply = nil, ---@type PushButton
gen_summary = nil, ---@type function gen_summary = nil, ---@type function
show_current_cfg = nil, ---@type function show_current_cfg = nil, ---@type function
load_legacy = nil, ---@type function load_legacy = nil, ---@type function
show_auth_key = nil, ---@type function show_auth_key = nil, ---@type function
show_key_btn = nil, ---@type graphics_element show_key_btn = nil, ---@type PushButton
auth_key_textbox = nil, ---@type graphics_element auth_key_textbox = nil, ---@type TextBox
auth_key_value = "", auth_key_value = "",
sv_connect = nil, ---@type function sv_connect = nil, ---@type function
sv_conn_button = nil, ---@type graphics_element sv_conn_button = nil, ---@type PushButton
sv_conn_status = nil, ---@type graphics_element sv_conn_status = nil, ---@type TextBox
sv_conn_detail = nil, ---@type graphics_element sv_conn_detail = nil, ---@type TextBox
sv_skip = nil, ---@type graphics_element sv_skip = nil, ---@type PushButton
sv_next = nil, ---@type graphics_element sv_next = nil, ---@type PushButton
apply_mon = nil, ---@type graphics_element apply_mon = nil, ---@type PushButton
update_mon_reqs = nil, ---@type function update_mon_reqs = nil, ---@type function
gen_mon_list = function () end, gen_mon_list = function () end,
edit_monitor = nil, ---@type function edit_monitor = nil, ---@type function
mon_iface = "", mon_iface = "",
mon_expect = {} mon_expect = {} ---@type integer[]
} }
---@class crd_config ---@class crd_config
@ -302,7 +302,7 @@ local function load_settings(target, raw)
end end
-- create the config view -- create the config view
---@param display graphics_element ---@param display DisplayBox
local function config_view(display) local function config_view(display)
---@diagnostic disable-next-line: undefined-field ---@diagnostic disable-next-line: undefined-field
local function exit() os.queueEvent("terminate") end local function exit() os.queueEvent("terminate") end
@ -460,11 +460,11 @@ local function config_view(display)
TextBox{parent=net_c_4,x=1,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for security on multiplayer servers. All devices on the same network MUST use the same key if any device has a key. This does result in some extra compution (can slow things down).",fg_bg=g_lg_fg_bg} TextBox{parent=net_c_4,x=1,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for security on multiplayer servers. All devices on the same network MUST use the same key if any device has a key. This does result in some extra compution (can slow things down).",fg_bg=g_lg_fg_bg}
TextBox{parent=net_c_4,x=1,y=11,text="Facility Auth Key"} TextBox{parent=net_c_4,x=1,y=11,text="Facility Auth Key"}
local key, _, censor = TextField{parent=net_c_4,x=1,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg} local key, _ = TextField{parent=net_c_4,x=1,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg}
local function censor_key(enable) censor(util.trinary(enable, "*", nil)) end local function censor_key(enable) key.censor(util.trinary(enable, "*", nil)) end
local hide_key = CheckBox{parent=net_c_4,x=34,y=12,label="Hide",box_fg_bg=cpair(colors.lightBlue,colors.black),callback=censor_key} local hide_key = Checkbox{parent=net_c_4,x=34,y=12,label="Hide",box_fg_bg=cpair(colors.lightBlue,colors.black),callback=censor_key}
hide_key.set_value(true) hide_key.set_value(true)
censor_key(true) censor_key(true)
@ -622,7 +622,7 @@ local function config_view(display)
local mon_desc = TextBox{parent=mon_c_3,x=1,y=1,height=4,text=""} local mon_desc = TextBox{parent=mon_c_3,x=1,y=1,height=4,text=""}
local mon_unit_l, mon_unit = nil, nil ---@type graphics_element, graphics_element local mon_unit_l, mon_unit = nil, nil ---@type TextBox, NumberField
local mon_warn = TextBox{parent=mon_c_3,x=1,y=11,height=2,text="",fg_bg=cpair(colors.red,colors.lightGray)} local mon_warn = TextBox{parent=mon_c_3,x=1,y=11,height=2,text="",fg_bg=cpair(colors.red,colors.lightGray)}
@ -706,7 +706,7 @@ local function config_view(display)
TextBox{parent=mon_c_4,x=1,y=1,height=3,text="For legacy compatibility with facilities built without space for a flow monitor, you can disable the flow monitor requirement here."} TextBox{parent=mon_c_4,x=1,y=1,height=3,text="For legacy compatibility with facilities built without space for a flow monitor, you can disable the flow monitor requirement here."}
TextBox{parent=mon_c_4,x=1,y=5,height=3,text="Please be aware that THIS OPTION WILL BE REMOVED ON RELEASE. Disabling it will only be available for the remainder of the beta."} TextBox{parent=mon_c_4,x=1,y=5,height=3,text="Please be aware that THIS OPTION WILL BE REMOVED ON RELEASE. Disabling it will only be available for the remainder of the beta."}
local dis_flow_view = CheckBox{parent=mon_c_4,x=1,y=9,default=ini_cfg.DisableFlowView,label="Disable Flow View Monitor",box_fg_bg=cpair(colors.blue,colors.black)} local dis_flow_view = Checkbox{parent=mon_c_4,x=1,y=9,default=ini_cfg.DisableFlowView,label="Disable Flow View Monitor",box_fg_bg=cpair(colors.blue,colors.black)}
local function back_from_legacy() local function back_from_legacy()
tmp_cfg.DisableFlowView = dis_flow_view.get_value() tmp_cfg.DisableFlowView = dis_flow_view.get_value()
@ -790,7 +790,7 @@ local function config_view(display)
TextBox{parent=log_c_1,x=1,y=7,text="Log File Path"} TextBox{parent=log_c_1,x=1,y=7,text="Log File Path"}
local path = TextField{parent=log_c_1,x=1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg} local path = TextField{parent=log_c_1,x=1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
local en_dbg = CheckBox{parent=log_c_1,x=1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)} local en_dbg = Checkbox{parent=log_c_1,x=1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
TextBox{parent=log_c_1,x=3,y=11,height=2,text="This results in much larger log files. It is best to only use this when there is a problem.",fg_bg=g_lg_fg_bg} TextBox{parent=log_c_1,x=3,y=11,height=2,text="This results in much larger log files. It is best to only use this when there is a problem.",fg_bg=g_lg_fg_bg}
local path_err = TextBox{parent=log_c_1,x=8,y=14,width=35,text="Please provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true} local path_err = TextBox{parent=log_c_1,x=8,y=14,width=35,text="Please provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
@ -1263,7 +1263,7 @@ local function config_view(display)
-- list connected monitors -- list connected monitors
local monitors = ppm.get_monitor_list() local monitors = ppm.get_monitor_list()
for iface, device in pairs(monitors) do for iface, device in pairs(monitors) do
local dev = device.dev local dev = device.dev ---@type Monitor
dev.setTextScale(0.5) dev.setTextScale(0.5)
dev.setTextColor(colors.white) dev.setTextColor(colors.white)

View File

@ -111,12 +111,12 @@ function coordinator.load_config()
---@class monitors_struct ---@class monitors_struct
local monitors = { local monitors = {
main = nil, ---@type table|nil main = nil, ---@type Monitor|nil
main_name = "", main_name = "",
flow = nil, ---@type table|nil flow = nil, ---@type Monitor|nil
flow_name = "", flow_name = "",
unit_displays = {}, unit_displays = {}, ---@type Monitor[]
unit_name_map = {} unit_name_map = {} ---@type string[]
} }
local mon_cfv = util.new_validator() local mon_cfv = util.new_validator()
@ -623,7 +623,7 @@ function coordinator.comms(version, nic, sv_watchdog)
local unit_id = packet.data[2] local unit_id = packet.data[2]
local ack = packet.data[3] == true local ack = packet.data[3] == true
local unit = iocontrol.get_db().units[unit_id] ---@type ioctl_unit local unit = iocontrol.get_db().units[unit_id]
if unit ~= nil then if unit ~= nil then
if cmd == UNIT_COMMAND.SCRAM then if cmd == UNIT_COMMAND.SCRAM then

View File

@ -29,15 +29,6 @@ local iocontrol = {}
---@class ioctl ---@class ioctl
local io = {} local io = {}
-- luacheck: no unused args
-- placeholder acknowledge function for type hinting
---@param success boolean
---@diagnostic disable-next-line: unused-local
local function __generic_ack(success) end
-- luacheck: unused args
-- initialize front panel PSIL -- initialize front panel PSIL
---@param firmware_v string coordinator version ---@param firmware_v string coordinator version
---@param comms_v string comms version ---@param comms_v string comms version
@ -115,25 +106,23 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
radiation = types.new_zero_radiation_reading(), radiation = types.new_zero_radiation_reading(),
save_cfg_ack = __generic_ack, save_cfg_ack = nil, ---@type fun(success: boolean)
start_ack = __generic_ack, start_ack = nil, ---@type fun(success: boolean)
stop_ack = __generic_ack, stop_ack = nil, ---@type fun(success: boolean)
---@type { [TONE]: boolean }
alarm_tones = { false, false, false, false, false, false, false, false }, alarm_tones = { false, false, false, false, false, false, false, false },
ps = psil.create(), ps = psil.create(),
induction_ps_tbl = {}, induction_ps_tbl = {}, ---@type psil[]
induction_data_tbl = {}, induction_data_tbl = {}, ---@type imatrix_session_db[]
sps_ps_tbl = {}, sps_ps_tbl = {}, ---@type psil[]
sps_data_tbl = {}, sps_data_tbl = {}, ---@type sps_session_db[]
tank_ps_tbl = {}, tank_ps_tbl = {}, ---@type psil[]
tank_data_tbl = {}, tank_data_tbl = {} ---@type dynamicv_session_db[]
env_d_ps = psil.create(),
env_d_data = {}
} }
-- create induction and SPS tables (currently only 1 of each is supported) -- create induction and SPS tables (currently only 1 of each is supported)
@ -151,7 +140,7 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
end end
-- create unit data structures -- create unit data structures
io.units = {} io.units = {} ---@type ioctl_unit[]
for i = 1, conf.num_units do for i = 1, conf.num_units do
local function ack(alarm) process.ack_alarm(i, alarm) end local function ack(alarm) process.ack_alarm(i, alarm) end
local function reset(alarm) process.reset_alarm(i, alarm) end local function reset(alarm) process.reset_alarm(i, alarm) end
@ -160,7 +149,10 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
local entry = { local entry = {
unit_id = i, unit_id = i,
connected = false, connected = false,
rtu_hw = { boilers = {}, turbines = {} }, rtu_hw = {
boilers = {}, ---@type { connected: boolean, faulted: boolean }[]
turbines = {} ---@type { connected: boolean, faulted: boolean }[]
},
num_boilers = 0, num_boilers = 0,
num_turbines = 0, num_turbines = 0,
@ -208,7 +200,7 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
t_trip = { ack = function () ack(12) end, reset = function () reset(12) end } t_trip = { ack = function () ack(12) end, reset = function () reset(12) end }
}, },
---@type alarms ---@type { [ALARM]: ALARM_STATE }
alarms = { alarms = {
ALARM_STATE.INACTIVE, -- containment breach ALARM_STATE.INACTIVE, -- containment breach
ALARM_STATE.INACTIVE, -- containment radiation ALARM_STATE.INACTIVE, -- containment radiation
@ -229,14 +221,14 @@ function iocontrol.init(conf, comms, temp_scale, energy_scale)
unit_ps = psil.create(), unit_ps = psil.create(),
reactor_data = {}, ---@type reactor_db reactor_data = {}, ---@type reactor_db
boiler_ps_tbl = {}, boiler_ps_tbl = {}, ---@type psil[]
boiler_data_tbl = {}, boiler_data_tbl = {}, ---@type boilerv_session_db[]
turbine_ps_tbl = {}, turbine_ps_tbl = {}, ---@type psil[]
turbine_data_tbl = {}, turbine_data_tbl = {}, ---@type turbinev_session_db[]
tank_ps_tbl = {}, tank_ps_tbl = {}, ---@type psil[]
tank_data_tbl = {} tank_data_tbl = {} ---@type dynamicv_session_db[]
} }
-- on other facility modes, overwrite unit TANK option with facility tank defs -- on other facility modes, overwrite unit TANK option with facility tank defs
@ -357,8 +349,8 @@ end
-- record and publish multiblock RTU build data -- record and publish multiblock RTU build data
---@param id integer ---@param id integer
---@param entry table ---@param entry table
---@param data_tbl table ---@param data_tbl (imatrix_session_db|sps_session_db|dynamicv_session_db|turbinev_session_db|boilerv_session_db)[]
---@param ps_tbl table ---@param ps_tbl psil[]
---@param create boolean? true to create an entry if non exists, false to fail on missing ---@param create boolean? true to create an entry if non exists, false to fail on missing
---@return boolean ok true if data saved, false if invalid ID ---@return boolean ok true if data saved, false if invalid ID
local function _record_multiblock_build(id, entry, data_tbl, ps_tbl, create) local function _record_multiblock_build(id, entry, data_tbl, ps_tbl, create)
@ -369,8 +361,8 @@ local function _record_multiblock_build(id, entry, data_tbl, ps_tbl, create)
data_tbl[id] = {} data_tbl[id] = {}
end end
data_tbl[id].formed = entry[1] ---@type boolean data_tbl[id].formed = entry[1]
data_tbl[id].build = entry[2] ---@type table data_tbl[id].build = entry[2]
ps_tbl[id].publish("formed", entry[1]) ps_tbl[id].publish("formed", entry[1])
@ -444,7 +436,7 @@ function iocontrol.record_unit_builds(builds)
else else
-- reactor build -- reactor build
if type(build.reactor) == "table" then if type(build.reactor) == "table" then
unit.reactor_data.mek_struct = build.reactor ---@type mek_struct unit.reactor_data.mek_struct = build.reactor
for key, val in pairs(unit.reactor_data.mek_struct) do for key, val in pairs(unit.reactor_data.mek_struct) do
unit.unit_ps.publish(key, val) unit.unit_ps.publish(key, val)
end end
@ -497,10 +489,10 @@ end
---@param ps psil ---@param ps psil
---@return boolean is_faulted ---@return boolean is_faulted
local function _record_multiblock_status(entry, data, ps) local function _record_multiblock_status(entry, data, ps)
local is_faulted = entry[1] ---@type boolean local is_faulted = entry[1]
data.formed = entry[2] ---@type boolean data.formed = entry[2]
data.state = entry[3] ---@type table data.state = entry[3]
data.tanks = entry[4] ---@type table data.tanks = entry[4]
ps.publish("formed", data.formed) ps.publish("formed", data.formed)
ps.publish("faulted", is_faulted) ps.publish("faulted", is_faulted)
@ -600,8 +592,8 @@ function iocontrol.update_facility_status(status)
-- power statistics -- power statistics
if type(rtu_statuses.power) == "table" and #rtu_statuses.power == 4 then if type(rtu_statuses.power) == "table" and #rtu_statuses.power == 4 then
local data = fac.induction_data_tbl[1] ---@type imatrix_session_db local data = fac.induction_data_tbl[1]
local ps = fac.induction_ps_tbl[1] ---@type psil local ps = fac.induction_ps_tbl[1]
local chg = tonumber(rtu_statuses.power[1]) local chg = tonumber(rtu_statuses.power[1])
local in_f = tonumber(rtu_statuses.power[2]) local in_f = tonumber(rtu_statuses.power[2])
@ -636,8 +628,8 @@ function iocontrol.update_facility_status(status)
for id, matrix in pairs(rtu_statuses.induction) do for id, matrix in pairs(rtu_statuses.induction) do
if type(fac.induction_data_tbl[id]) == "table" then if type(fac.induction_data_tbl[id]) == "table" then
local data = fac.induction_data_tbl[id] ---@type imatrix_session_db local data = fac.induction_data_tbl[id]
local ps = fac.induction_ps_tbl[id] ---@type psil local ps = fac.induction_ps_tbl[id]
local rtu_faulted = _record_multiblock_status(matrix, data, ps) local rtu_faulted = _record_multiblock_status(matrix, data, ps)
@ -674,8 +666,8 @@ function iocontrol.update_facility_status(status)
for id, sps in pairs(rtu_statuses.sps) do for id, sps in pairs(rtu_statuses.sps) do
if type(fac.sps_data_tbl[id]) == "table" then if type(fac.sps_data_tbl[id]) == "table" then
local data = fac.sps_data_tbl[id] ---@type sps_session_db local data = fac.sps_data_tbl[id]
local ps = fac.sps_ps_tbl[id] ---@type psil local ps = fac.sps_ps_tbl[id]
local rtu_faulted = _record_multiblock_status(sps, data, ps) local rtu_faulted = _record_multiblock_status(sps, data, ps)
@ -712,8 +704,8 @@ function iocontrol.update_facility_status(status)
for id, tank in pairs(rtu_statuses.tanks) do for id, tank in pairs(rtu_statuses.tanks) do
if type(fac.tank_data_tbl[id]) == "table" then if type(fac.tank_data_tbl[id]) == "table" then
local data = fac.tank_data_tbl[id] ---@type dynamicv_session_db local data = fac.tank_data_tbl[id]
local ps = fac.tank_ps_tbl[id] ---@type psil local ps = fac.tank_ps_tbl[id]
local rtu_faulted = _record_multiblock_status(tank, data, ps) local rtu_faulted = _record_multiblock_status(tank, data, ps)
@ -812,7 +804,7 @@ function iocontrol.update_unit_statuses(statuses)
for i = 1, #statuses do for i = 1, #statuses do
local log_header = util.c("iocontrol.update_unit_statuses[unit ", i, "]: ") local log_header = util.c("iocontrol.update_unit_statuses[unit ", i, "]: ")
local unit = io.units[i] ---@type ioctl_unit local unit = io.units[i]
local status = statuses[i] local status = statuses[i]
local burn_rate = 0.0 local burn_rate = 0.0
@ -848,8 +840,8 @@ function iocontrol.update_unit_statuses(statuses)
log.debug(log_header .. "reactor general status length mismatch") log.debug(log_header .. "reactor general status length mismatch")
end end
unit.reactor_data.rps_status = rps_status ---@type rps_status unit.reactor_data.rps_status = rps_status
unit.reactor_data.mek_status = mek_status ---@type mek_status unit.reactor_data.mek_status = mek_status
-- if status hasn't been received, mek_status = {} -- if status hasn't been received, mek_status = {}
if type(unit.reactor_data.mek_status.act_burn_rate) == "number" then if type(unit.reactor_data.mek_status.act_burn_rate) == "number" then
@ -917,8 +909,8 @@ function iocontrol.update_unit_statuses(statuses)
for id, boiler in pairs(rtu_statuses.boilers) do for id, boiler in pairs(rtu_statuses.boilers) do
if type(unit.boiler_data_tbl[id]) == "table" then if type(unit.boiler_data_tbl[id]) == "table" then
local data = unit.boiler_data_tbl[id] ---@type boilerv_session_db local data = unit.boiler_data_tbl[id]
local ps = unit.boiler_ps_tbl[id] ---@type psil local ps = unit.boiler_ps_tbl[id]
local rtu_faulted = _record_multiblock_status(boiler, data, ps) local rtu_faulted = _record_multiblock_status(boiler, data, ps)
unit.rtu_hw.boilers[id].faulted = rtu_faulted unit.rtu_hw.boilers[id].faulted = rtu_faulted
@ -964,8 +956,8 @@ function iocontrol.update_unit_statuses(statuses)
for id, turbine in pairs(rtu_statuses.turbines) do for id, turbine in pairs(rtu_statuses.turbines) do
if type(unit.turbine_data_tbl[id]) == "table" then if type(unit.turbine_data_tbl[id]) == "table" then
local data = unit.turbine_data_tbl[id] ---@type turbinev_session_db local data = unit.turbine_data_tbl[id]
local ps = unit.turbine_ps_tbl[id] ---@type psil local ps = unit.turbine_ps_tbl[id]
local rtu_faulted = _record_multiblock_status(turbine, data, ps) local rtu_faulted = _record_multiblock_status(turbine, data, ps)
unit.rtu_hw.turbines[id].faulted = rtu_faulted unit.rtu_hw.turbines[id].faulted = rtu_faulted
@ -1008,8 +1000,8 @@ function iocontrol.update_unit_statuses(statuses)
for id, tank in pairs(rtu_statuses.tanks) do for id, tank in pairs(rtu_statuses.tanks) do
if type(unit.tank_data_tbl[id]) == "table" then if type(unit.tank_data_tbl[id]) == "table" then
local data = unit.tank_data_tbl[id] ---@type dynamicv_session_db local data = unit.tank_data_tbl[id]
local ps = unit.tank_ps_tbl[id] ---@type psil local ps = unit.tank_ps_tbl[id]
local rtu_faulted = _record_multiblock_status(tank, data, ps) local rtu_faulted = _record_multiblock_status(tank, data, ps)

View File

@ -29,13 +29,13 @@ local pctl = {
burn_target = 0.0, burn_target = 0.0,
charge_target = 0.0, charge_target = 0.0,
gen_target = 0.0, gen_target = 0.0,
limits = {}, limits = {}, ---@type number[]
waste_product = PRODUCT.PLUTONIUM, waste_product = PRODUCT.PLUTONIUM,
pu_fallback = false, pu_fallback = false,
sps_low_power = false sps_low_power = false
}, },
waste_modes = {}, waste_modes = {}, ---@type WASTE_MODE[]
priority_groups = {} priority_groups = {} ---@type AUTO_GROUP[]
}, },
commands = { commands = {
unit = {}, ---@type process_command_state[][] unit = {}, ---@type process_command_state[][]
@ -46,7 +46,7 @@ local pctl = {
---@class process_command_state ---@class process_command_state
---@field active boolean if this command is live ---@field active boolean if this command is live
---@field timeout integer expiration time of this command request ---@field timeout integer expiration time of this command request
---@field requestors table list of callbacks from the requestors ---@field requestors function[] list of callbacks from the requestors
-- write auto process control to config file -- write auto process control to config file
local function _write_auto_config() local function _write_auto_config()
@ -80,8 +80,8 @@ function process.init(iocontrol, coord_comms)
ctl_proc.limits[i] = 0.1 ctl_proc.limits[i] = 0.1
end end
local ctrl_states = settings.get("ControlStates", {}) local ctrl_states = settings.get("ControlStates", {}) ---@type sys_control_states
local config = ctrl_states.process ---@type sys_auto_config local config = ctrl_states.process
-- facility auto control configuration -- facility auto control configuration
if type(config) == "table" then if type(config) == "table" then
@ -103,7 +103,7 @@ function process.init(iocontrol, coord_comms)
pctl.io.facility.ps.publish("process_sps_low_power", ctl_proc.sps_low_power) pctl.io.facility.ps.publish("process_sps_low_power", ctl_proc.sps_low_power)
for id = 1, math.min(#ctl_proc.limits, pctl.io.facility.num_units) do for id = 1, math.min(#ctl_proc.limits, pctl.io.facility.num_units) do
local unit = pctl.io.units[id] ---@type ioctl_unit local unit = pctl.io.units[id]
unit.unit_ps.publish("burn_limit", ctl_proc.limits[id]) unit.unit_ps.publish("burn_limit", ctl_proc.limits[id])
end end
@ -116,7 +116,7 @@ function process.init(iocontrol, coord_comms)
end end
-- unit waste states -- unit waste states
local waste_modes = ctrl_states.waste_modes ---@type table|nil local waste_modes = ctrl_states.waste_modes
if type(waste_modes) == "table" then if type(waste_modes) == "table" then
for id, mode in pairs(waste_modes) do for id, mode in pairs(waste_modes) do
pctl.control_states.waste_modes[id] = mode pctl.control_states.waste_modes[id] = mode
@ -127,7 +127,7 @@ function process.init(iocontrol, coord_comms)
end end
-- unit priority groups -- unit priority groups
local prio_groups = ctrl_states.priority_groups ---@type table|nil local prio_groups = ctrl_states.priority_groups
if type(prio_groups) == "table" then if type(prio_groups) == "table" then
for id, group in pairs(prio_groups) do for id, group in pairs(prio_groups) do
pctl.control_states.priority_groups[id] = group pctl.control_states.priority_groups[id] = group
@ -443,7 +443,7 @@ end
---@param burn_target number burn rate target ---@param burn_target number burn rate target
---@param charge_target number charge target ---@param charge_target number charge target
---@param gen_target number generation rate target ---@param gen_target number generation rate target
---@param limits table unit burn rate limits ---@param limits number[] unit burn rate limits
function process.save(mode, burn_target, charge_target, gen_target, limits) function process.save(mode, burn_target, charge_target, gen_target, limits)
log.debug("PROCESS: SAVE") log.debug("PROCESS: SAVE")
@ -473,7 +473,7 @@ function process.start_ack_handle(response)
for i = 1, math.min(#response[6], pctl.io.facility.num_units) do for i = 1, math.min(#response[6], pctl.io.facility.num_units) do
ctl_proc.limits[i] = response[6][i] ctl_proc.limits[i] = response[6][i]
local unit = pctl.io.units[i] ---@type ioctl_unit local unit = pctl.io.units[i]
unit.unit_ps.publish("burn_limit", ctl_proc.limits[i]) unit.unit_ps.publish("burn_limit", ctl_proc.limits[i])
end end

View File

@ -19,7 +19,7 @@ local unit_view = require("coordinator.ui.layout.unit_view")
local core = require("graphics.core") local core = require("graphics.core")
local flasher = require("graphics.flasher") local flasher = require("graphics.flasher")
local DisplayBox = require("graphics.elements.displaybox") local DisplayBox = require("graphics.elements.DisplayBox")
local log_render = coordinator.log_render local log_render = coordinator.log_render
@ -30,20 +30,20 @@ local renderer = {}
local engine = { local engine = {
color_mode = 1, ---@type COLOR_MODE color_mode = 1, ---@type COLOR_MODE
monitors = nil, ---@type monitors_struct|nil monitors = nil, ---@type monitors_struct|nil
dmesg_window = nil, ---@type table|nil dmesg_window = nil, ---@type Window|nil
ui_ready = false, ui_ready = false,
fp_ready = false, fp_ready = false,
ui = { ui = {
front_panel = nil, ---@type graphics_element|nil front_panel = nil, ---@type DisplayBox|nil
main_display = nil, ---@type graphics_element|nil main_display = nil, ---@type DisplayBox|nil
flow_display = nil, ---@type graphics_element|nil flow_display = nil, ---@type DisplayBox|nil
unit_displays = {} unit_displays = {} ---@type (DisplayBox|nil)[]
}, },
disable_flow_view = false disable_flow_view = false
} }
-- init a display to the "default", but set text scale to 0.5 -- init a display to the "default", but set text scale to 0.5
---@param monitor table monitor ---@param monitor Monitor monitor
local function _init_display(monitor) local function _init_display(monitor)
monitor.setTextScale(0.5) monitor.setTextScale(0.5)
monitor.setTextColor(colors.white) monitor.setTextColor(colors.white)
@ -64,7 +64,7 @@ local function _init_display(monitor)
end end
-- print out that the monitor is too small -- print out that the monitor is too small
---@param monitor table monitor ---@param monitor Monitor monitor
local function _print_too_small(monitor) local function _print_too_small(monitor)
monitor.setCursorPos(1, 1) monitor.setCursorPos(1, 1)
monitor.setBackgroundColor(colors.black) monitor.setBackgroundColor(colors.black)
@ -275,7 +275,7 @@ function renderer.fp_ready() return engine.fp_ready end
function renderer.ui_ready() return engine.ui_ready end function renderer.ui_ready() return engine.ui_ready end
-- handle a monitor peripheral being disconnected -- handle a monitor peripheral being disconnected
---@param device table monitor ---@param device Monitor monitor
---@return boolean is_used if the monitor is one of the configured monitors ---@return boolean is_used if the monitor is one of the configured monitors
function renderer.handle_disconnect(device) function renderer.handle_disconnect(device)
local is_used = false local is_used = false
@ -326,7 +326,7 @@ end
-- handle a monitor peripheral being reconnected -- handle a monitor peripheral being reconnected
---@param name string monitor name ---@param name string monitor name
---@param device table monitor ---@param device Monitor monitor
---@return boolean is_used if the monitor is one of the configured monitors ---@return boolean is_used if the monitor is one of the configured monitors
function renderer.handle_reconnect(name, device) function renderer.handle_reconnect(name, device)
local is_used = false local is_used = false
@ -373,7 +373,7 @@ function renderer.handle_resize(name)
if not engine.monitors then return false, false end if not engine.monitors then return false, false end
if engine.monitors.main_name == name and engine.monitors.main then if engine.monitors.main_name == name and engine.monitors.main then
local device = engine.monitors.main ---@type table local device = engine.monitors.main ---@type Monitor
-- this is necessary if the bottom left block was broken and on reconnect -- this is necessary if the bottom left block was broken and on reconnect
_init_display(device) _init_display(device)
@ -416,7 +416,7 @@ function renderer.handle_resize(name)
end end
else engine.dmesg_window.redraw() end else engine.dmesg_window.redraw() end
elseif engine.monitors.flow_name == name and engine.monitors.flow then elseif engine.monitors.flow_name == name and engine.monitors.flow then
local device = engine.monitors.flow ---@type table local device = engine.monitors.flow ---@type Monitor
-- this is necessary if the bottom left block was broken and on reconnect -- this is necessary if the bottom left block was broken and on reconnect
_init_display(device) _init_display(device)

View File

@ -13,7 +13,7 @@ local self = {
nic = nil, ---@type nic nic = nil, ---@type nic
config = nil, ---@type crd_config config = nil, ---@type crd_config
next_id = 0, next_id = 0,
sessions = {} sessions = {} ---@type pkt_session_struct[]
} }
-- PRIVATE FUNCTIONS -- -- PRIVATE FUNCTIONS --
@ -129,7 +129,7 @@ end
---@param timer_event number ---@param timer_event number
function apisessions.check_all_watchdogs(timer_event) function apisessions.check_all_watchdogs(timer_event)
for i = 1, #self.sessions do for i = 1, #self.sessions do
local session = self.sessions[i] ---@type pkt_session_struct local session = self.sessions[i]
if session.open then if session.open then
local triggered = session.instance.check_wd(timer_event) local triggered = session.instance.check_wd(timer_event)
if triggered then if triggered then
@ -143,7 +143,7 @@ end
-- iterate all the API sessions -- iterate all the API sessions
function apisessions.iterate_all() function apisessions.iterate_all()
for i = 1, #self.sessions do for i = 1, #self.sessions do
local session = self.sessions[i] ---@type pkt_session_struct local session = self.sessions[i]
if session.open and session.instance.iterate() then if session.open and session.instance.iterate() then
_api_handle_outq(session) _api_handle_outq(session)
@ -168,7 +168,7 @@ end
-- close all open connections -- close all open connections
function apisessions.close_all() function apisessions.close_all()
for i = 1, #self.sessions do for i = 1, #self.sessions do
local session = self.sessions[i] ---@type pkt_session_struct local session = self.sessions[i]
if session.open then _shutdown(session) end if session.open then _shutdown(session) end
end end

View File

@ -217,7 +217,7 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout)
_send(CRDN_TYPE.API_GET_FAC, data) _send(CRDN_TYPE.API_GET_FAC, data)
elseif pkt.type == CRDN_TYPE.API_GET_UNIT then elseif pkt.type == CRDN_TYPE.API_GET_UNIT then
if pkt.length == 1 and type(pkt.data[1]) == "number" then if pkt.length == 1 and type(pkt.data[1]) == "number" then
local u = db.units[pkt.data[1]] ---@type ioctl_unit local u = db.units[pkt.data[1]]
if u then if u then
local data = { local data = {

View File

@ -9,7 +9,7 @@ local log = require("scada-common.log")
local sounder = {} local sounder = {}
local alarm_ctl = { local alarm_ctl = {
speaker = nil, speaker = nil, ---@type Speaker
volume = 0.5, volume = 0.5,
stream = audio.new_stream() stream = audio.new_stream()
} }
@ -24,7 +24,7 @@ local function play()
end end
-- initialize the annunciator alarm system -- initialize the annunciator alarm system
---@param speaker table speaker peripheral ---@param speaker Speaker speaker peripheral
---@param volume number speaker volume ---@param volume number speaker volume
function sounder.init(speaker, volume) function sounder.init(speaker, volume)
alarm_ctl.speaker = speaker alarm_ctl.speaker = speaker
@ -36,7 +36,7 @@ function sounder.init(speaker, volume)
end end
-- reconnect the speaker peripheral -- reconnect the speaker peripheral
---@param speaker table speaker peripheral ---@param speaker Speaker speaker peripheral
function sounder.reconnect(speaker) function sounder.reconnect(speaker)
alarm_ctl.speaker = speaker alarm_ctl.speaker = speaker
alarm_ctl.playing = false alarm_ctl.playing = false
@ -44,7 +44,7 @@ function sounder.reconnect(speaker)
end end
-- set alarm tones -- set alarm tones
---@param states table alarm tone commands from supervisor ---@param states { [TONE]: boolean } alarm tone commands from supervisor
function sounder.set(states) function sounder.set(states)
-- set tone states -- set tone states
for id = 1, #states do alarm_ctl.stream.set_active(id, states[id]) end for id = 1, #states do alarm_ctl.stream.set_active(id, states[id]) end

View File

@ -19,7 +19,7 @@ local renderer = require("coordinator.renderer")
local sounder = require("coordinator.sounder") local sounder = require("coordinator.sounder")
local threads = require("coordinator.threads") local threads = require("coordinator.threads")
local COORDINATOR_VERSION = "v1.5.8" local COORDINATOR_VERSION = "v1.5.9"
local CHUNK_LOAD_DELAY_S = 30.0 local CHUNK_LOAD_DELAY_S = 30.0
@ -152,7 +152,7 @@ local function main()
-- core coordinator devices -- core coordinator devices
crd_dev = { crd_dev = {
modem = ppm.get_wireless_modem(), modem = ppm.get_wireless_modem(),
speaker = ppm.get_device("speaker") speaker = ppm.get_device("speaker") ---@type Speaker|nil
}, },
-- system objects -- system objects

View File

@ -68,6 +68,7 @@ function threads.thread__main(smem)
if type ~= nil and device ~= nil then if type ~= nil and device ~= nil then
if type == "modem" then if type == "modem" then
---@cast device Modem
-- we only really care if this is our wireless modem -- we only really care if this is our wireless modem
-- if it is another modem, handle other peripheral losses separately -- if it is another modem, handle other peripheral losses separately
if nic.is_modem(device) then if nic.is_modem(device) then
@ -91,8 +92,10 @@ function threads.thread__main(smem)
log_sys("non-comms modem disconnected") log_sys("non-comms modem disconnected")
end end
elseif type == "monitor" then elseif type == "monitor" then
---@cast device Monitor
smem.q.mq_render.push_data(MQ__RENDER_DATA.MON_DISCONNECT, device) smem.q.mq_render.push_data(MQ__RENDER_DATA.MON_DISCONNECT, device)
elseif type == "speaker" then elseif type == "speaker" then
---@cast device Speaker
log_sys("lost alarm sounder speaker") log_sys("lost alarm sounder speaker")
iocontrol.fp_has_speaker(false) iocontrol.fp_has_speaker(false)
end end
@ -102,6 +105,7 @@ function threads.thread__main(smem)
if type ~= nil and device ~= nil then if type ~= nil and device ~= nil then
if type == "modem" then if type == "modem" then
---@cast device Modem
if device.isWireless() and not nic.is_connected() then if device.isWireless() and not nic.is_connected() then
-- reconnected modem -- reconnected modem
log_sys("comms modem reconnected") log_sys("comms modem reconnected")
@ -113,8 +117,10 @@ function threads.thread__main(smem)
log_sys("wired modem reconnected") log_sys("wired modem reconnected")
end end
elseif type == "monitor" then elseif type == "monitor" then
---@cast device Monitor
smem.q.mq_render.push_data(MQ__RENDER_DATA.MON_CONNECT, { name = param1, device = device }) smem.q.mq_render.push_data(MQ__RENDER_DATA.MON_CONNECT, { name = param1, device = device })
elseif type == "speaker" then elseif type == "speaker" then
---@cast device Speaker
log_sys("alarm sounder speaker reconnected") log_sys("alarm sounder speaker reconnected")
sounder.reconnect(device) sounder.reconnect(device)
iocontrol.fp_has_speaker(true) iocontrol.fp_has_speaker(true)

View File

@ -4,18 +4,18 @@ local style = require("coordinator.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Rectangle = require("graphics.elements.rectangle") local Rectangle = require("graphics.elements.Rectangle")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local StateIndicator = require("graphics.elements.indicators.state") local StateIndicator = require("graphics.elements.indicators.StateIndicator")
local VerticalBar = require("graphics.elements.indicators.vbar") local VerticalBar = require("graphics.elements.indicators.VerticalBar")
local cpair = core.cpair local cpair = core.cpair
local border = core.border local border = core.border
-- new boiler view -- new boiler view
---@param root graphics_element parent ---@param root Container parent
---@param x integer top left x ---@param x integer top left x
---@param y integer top left y ---@param y integer top left y
---@param ps psil ps interface ---@param ps psil ps interface

View File

@ -6,15 +6,15 @@ local style = require("coordinator.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local Rectangle = require("graphics.elements.rectangle") local Rectangle = require("graphics.elements.Rectangle")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local IndicatorLight = require("graphics.elements.indicators.light") local IndicatorLight = require("graphics.elements.indicators.IndicatorLight")
local PowerIndicator = require("graphics.elements.indicators.power") local PowerIndicator = require("graphics.elements.indicators.PowerIndicator")
local StateIndicator = require("graphics.elements.indicators.state") local StateIndicator = require("graphics.elements.indicators.StateIndicator")
local VerticalBar = require("graphics.elements.indicators.vbar") local VerticalBar = require("graphics.elements.indicators.VerticalBar")
local cpair = core.cpair local cpair = core.cpair
local border = core.border local border = core.border
@ -22,7 +22,7 @@ local border = core.border
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
-- new induction matrix view -- new induction matrix view
---@param root graphics_element parent ---@param root Container parent
---@param x integer top left x ---@param x integer top left x
---@param y integer top left y ---@param y integer top left y
---@param data imatrix_session_db matrix data ---@param data imatrix_session_db matrix data

View File

@ -8,17 +8,17 @@ local style = require("coordinator.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
local cpair = core.cpair local cpair = core.cpair
-- create a pocket list entry -- create a pocket list entry
---@param parent graphics_element parent ---@param parent ListBox parent
---@param id integer PKT session ID ---@param id integer PKT session ID
local function init(parent, id) local function init(parent, id)
local s_hi_box = style.fp_theme.highlight_box local s_hi_box = style.fp_theme.highlight_box

View File

@ -8,20 +8,20 @@ local style = require("coordinator.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local Rectangle = require("graphics.elements.rectangle") local Rectangle = require("graphics.elements.Rectangle")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local IndicatorLight = require("graphics.elements.indicators.light") local IndicatorLight = require("graphics.elements.indicators.IndicatorLight")
local RadIndicator = require("graphics.elements.indicators.rad") local RadIndicator = require("graphics.elements.indicators.RadIndicator")
local StateIndicator = require("graphics.elements.indicators.state") local StateIndicator = require("graphics.elements.indicators.StateIndicator")
local TriIndicatorLight = require("graphics.elements.indicators.trilight") local TriIndicatorLight = require("graphics.elements.indicators.TriIndicatorLight")
local Checkbox = require("graphics.elements.controls.checkbox") local Checkbox = require("graphics.elements.controls.Checkbox")
local HazardButton = require("graphics.elements.controls.hazard_button") local HazardButton = require("graphics.elements.controls.HazardButton")
local RadioButton = require("graphics.elements.controls.radio_button") local NumericSpinbox = require("graphics.elements.controls.NumericSpinbox")
local SpinboxNumeric = require("graphics.elements.controls.spinbox_numeric") local RadioButton = require("graphics.elements.controls.RadioButton")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
@ -33,7 +33,7 @@ local bw_fg_bg = style.bw_fg_bg
local period = core.flasher.PERIOD local period = core.flasher.PERIOD
-- new process control view -- new process control view
---@param root graphics_element parent ---@param root Container parent
---@param x integer top left x ---@param x integer top left x
---@param y integer top left y ---@param y integer top left y
local function new_view(root, x, y) local function new_view(root, x, y)
@ -131,7 +131,7 @@ local function new_view(root, x, y)
TextBox{parent=burn_tag,x=2,y=2,text="Burn Target",width=7,height=2} TextBox{parent=burn_tag,x=2,y=2,text="Burn Target",width=7,height=2}
local burn_target = Div{parent=targets,x=9,y=1,width=23,height=3,fg_bg=s_hi_box} local burn_target = Div{parent=targets,x=9,y=1,width=23,height=3,fg_bg=s_hi_box}
local b_target = SpinboxNumeric{parent=burn_target,x=11,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled} local b_target = NumericSpinbox{parent=burn_target,x=11,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled}
TextBox{parent=burn_target,x=18,y=2,text="mB/t",fg_bg=style.theme.label_fg} TextBox{parent=burn_target,x=18,y=2,text="mB/t",fg_bg=style.theme.label_fg}
local burn_sum = DataIndicator{parent=targets,x=9,y=4,label="",format="%18.1f",value=0,unit="mB/t",commas=true,lu_colors=black,width=23,fg_bg=blk_brn} local burn_sum = DataIndicator{parent=targets,x=9,y=4,label="",format="%18.1f",value=0,unit="mB/t",commas=true,lu_colors=black,width=23,fg_bg=blk_brn}
@ -142,7 +142,7 @@ local function new_view(root, x, y)
TextBox{parent=chg_tag,x=2,y=2,text="Charge Target",width=7,height=2} TextBox{parent=chg_tag,x=2,y=2,text="Charge Target",width=7,height=2}
local chg_target = Div{parent=targets,x=9,y=6,width=23,height=3,fg_bg=s_hi_box} local chg_target = Div{parent=targets,x=9,y=6,width=23,height=3,fg_bg=s_hi_box}
local c_target = SpinboxNumeric{parent=chg_target,x=2,y=1,whole_num_precision=15,fractional_precision=0,min=0,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled} local c_target = NumericSpinbox{parent=chg_target,x=2,y=1,whole_num_precision=15,fractional_precision=0,min=0,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled}
TextBox{parent=chg_target,x=18,y=2,text="M"..db.energy_label,fg_bg=style.theme.label_fg} TextBox{parent=chg_target,x=18,y=2,text="M"..db.energy_label,fg_bg=style.theme.label_fg}
local cur_charge = DataIndicator{parent=targets,x=9,y=9,label="",format="%19d",value=0,unit="M"..db.energy_label,commas=true,lu_colors=black,width=23,fg_bg=blk_brn} local cur_charge = DataIndicator{parent=targets,x=9,y=9,label="",format="%19d",value=0,unit="M"..db.energy_label,commas=true,lu_colors=black,width=23,fg_bg=blk_brn}
@ -153,7 +153,7 @@ local function new_view(root, x, y)
TextBox{parent=gen_tag,x=2,y=2,text="Gen. Target",width=7,height=2} TextBox{parent=gen_tag,x=2,y=2,text="Gen. Target",width=7,height=2}
local gen_target = Div{parent=targets,x=9,y=11,width=23,height=3,fg_bg=s_hi_box} local gen_target = Div{parent=targets,x=9,y=11,width=23,height=3,fg_bg=s_hi_box}
local g_target = SpinboxNumeric{parent=gen_target,x=8,y=1,whole_num_precision=9,fractional_precision=0,min=0,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled} local g_target = NumericSpinbox{parent=gen_target,x=8,y=1,whole_num_precision=9,fractional_precision=0,min=0,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled}
TextBox{parent=gen_target,x=18,y=2,text="k"..db.energy_label.."/t",fg_bg=style.theme.label_fg} TextBox{parent=gen_target,x=18,y=2,text="k"..db.energy_label.."/t",fg_bg=style.theme.label_fg}
local cur_gen = DataIndicator{parent=targets,x=9,y=14,label="",format="%17d",value=0,unit="k"..db.energy_label.."/t",commas=true,lu_colors=black,width=23,fg_bg=blk_brn} local cur_gen = DataIndicator{parent=targets,x=9,y=14,label="",format="%17d",value=0,unit="k"..db.energy_label.."/t",commas=true,lu_colors=black,width=23,fg_bg=blk_brn}
@ -177,7 +177,7 @@ local function new_view(root, x, y)
local cur_lu = style.theme.disabled local cur_lu = style.theme.disabled
if i <= facility.num_units then if i <= facility.num_units then
unit = units[i] ---@type ioctl_unit unit = units[i]
tag_fg_bg = cpair(colors.black, colors.lightBlue) tag_fg_bg = cpair(colors.black, colors.lightBlue)
lim_fg_bg = s_hi_box lim_fg_bg = s_hi_box
label_fg = style.theme.label_fg label_fg = style.theme.label_fg
@ -191,7 +191,7 @@ local function new_view(root, x, y)
TextBox{parent=unit_tag,x=2,y=2,text="Unit "..i.." Limit",width=7,height=2} TextBox{parent=unit_tag,x=2,y=2,text="Unit "..i.." Limit",width=7,height=2}
local lim_ctl = Div{parent=limit_div,x=9,y=_y,width=14,height=3,fg_bg=s_hi_box} local lim_ctl = Div{parent=limit_div,x=9,y=_y,width=14,height=3,fg_bg=s_hi_box}
local lim = SpinboxNumeric{parent=lim_ctl,x=2,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled,fg_bg=lim_fg_bg} local lim = NumericSpinbox{parent=lim_ctl,x=2,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled,fg_bg=lim_fg_bg}
TextBox{parent=lim_ctl,x=9,y=2,text="mB/t",width=4,fg_bg=label_fg} TextBox{parent=lim_ctl,x=9,y=2,text="mB/t",width=4,fg_bg=label_fg}
local cur_burn = DataIndicator{parent=limit_div,x=9,y=_y+3,label="",format="%7.1f",value=0,unit="mB/t",commas=false,lu_colors=cpair(cur_lu,cur_lu),width=14,fg_bg=cur_fg_bg} local cur_burn = DataIndicator{parent=limit_div,x=9,y=_y+3,label="",format="%7.1f",value=0,unit="mB/t",commas=false,lu_colors=cpair(cur_lu,cur_lu),width=14,fg_bg=cur_fg_bg}
@ -234,7 +234,7 @@ local function new_view(root, x, y)
local degraded = IndicatorLight{parent=lights,x=2,y=3,label="Degraded",colors=cpair(ind_red.fgd,ind_off),flash=true,period=period.BLINK_250_MS} local degraded = IndicatorLight{parent=lights,x=2,y=3,label="Degraded",colors=cpair(ind_red.fgd,ind_off),flash=true,period=period.BLINK_250_MS}
if i <= facility.num_units then if i <= facility.num_units then
local unit = units[i] ---@type ioctl_unit local unit = units[i]
ready.register(unit.unit_ps, "U_AutoReady", ready.update) ready.register(unit.unit_ps, "U_AutoReady", ready.update)
degraded.register(unit.unit_ps, "U_AutoDegraded", degraded.update) degraded.register(unit.unit_ps, "U_AutoDegraded", degraded.update)
@ -323,7 +323,7 @@ local function new_view(root, x, y)
local waste_status = Div{parent=proc,width=24,height=4,x=57,y=1,} local waste_status = Div{parent=proc,width=24,height=4,x=57,y=1,}
for i = 1, facility.num_units do for i = 1, facility.num_units do
local unit = units[i] ---@type ioctl_unit local unit = units[i]
TextBox{parent=waste_status,y=i,text="U"..i.." Waste",width=8} TextBox{parent=waste_status,y=i,text="U"..i.." Waste",width=8}
local a_waste = IndicatorLight{parent=waste_status,x=10,y=i,label="Auto",colors=ind_wht} local a_waste = IndicatorLight{parent=waste_status,x=10,y=i,label="Auto",colors=ind_wht}

View File

@ -6,18 +6,18 @@ local style = require("coordinator.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Rectangle = require("graphics.elements.rectangle") local Rectangle = require("graphics.elements.Rectangle")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local HorizontalBar = require("graphics.elements.indicators.hbar") local HorizontalBar = require("graphics.elements.indicators.HorizontalBar")
local StateIndicator = require("graphics.elements.indicators.state") local StateIndicator = require("graphics.elements.indicators.StateIndicator")
local cpair = core.cpair local cpair = core.cpair
local border = core.border local border = core.border
-- create new reactor view -- create new reactor view
---@param root graphics_element parent ---@param root Container parent
---@param x integer top left x ---@param x integer top left x
---@param y integer top left y ---@param y integer top left y
---@param ps psil ps interface ---@param ps psil ps interface

View File

@ -4,19 +4,19 @@ local style = require("coordinator.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Rectangle = require("graphics.elements.rectangle") local Rectangle = require("graphics.elements.Rectangle")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local PowerIndicator = require("graphics.elements.indicators.power") local PowerIndicator = require("graphics.elements.indicators.PowerIndicator")
local StateIndicator = require("graphics.elements.indicators.state") local StateIndicator = require("graphics.elements.indicators.StateIndicator")
local VerticalBar = require("graphics.elements.indicators.vbar") local VerticalBar = require("graphics.elements.indicators.VerticalBar")
local cpair = core.cpair local cpair = core.cpair
local border = core.border local border = core.border
-- new turbine view -- new turbine view
---@param root graphics_element parent ---@param root Container parent
---@param x integer top left x ---@param x integer top left x
---@param y integer top left y ---@param y integer top left y
---@param ps psil ps interface ---@param ps psil ps interface

View File

@ -11,23 +11,23 @@ local style = require("coordinator.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local Rectangle = require("graphics.elements.rectangle") local Rectangle = require("graphics.elements.Rectangle")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local AlarmLight = require("graphics.elements.indicators.alight") local AlarmLight = require("graphics.elements.indicators.AlarmLight")
local CoreMap = require("graphics.elements.indicators.coremap") local CoreMap = require("graphics.elements.indicators.CoreMap")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local IndicatorLight = require("graphics.elements.indicators.light") local IndicatorLight = require("graphics.elements.indicators.IndicatorLight")
local RadIndicator = require("graphics.elements.indicators.rad") local RadIndicator = require("graphics.elements.indicators.RadIndicator")
local TriIndicatorLight = require("graphics.elements.indicators.trilight") local TriIndicatorLight = require("graphics.elements.indicators.TriIndicatorLight")
local VerticalBar = require("graphics.elements.indicators.vbar") local VerticalBar = require("graphics.elements.indicators.VerticalBar")
local HazardButton = require("graphics.elements.controls.hazard_button") local HazardButton = require("graphics.elements.controls.HazardButton")
local MultiButton = require("graphics.elements.controls.multi_button") local MultiButton = require("graphics.elements.controls.MultiButton")
local PushButton = require("graphics.elements.controls.push_button") local NumericSpinbox = require("graphics.elements.controls.NumericSpinbox")
local RadioButton = require("graphics.elements.controls.radio_button") local PushButton = require("graphics.elements.controls.PushButton")
local SpinboxNumeric = require("graphics.elements.controls.spinbox_numeric") local RadioButton = require("graphics.elements.controls.RadioButton")
local AUTO_GROUP = types.AUTO_GROUP local AUTO_GROUP = types.AUTO_GROUP
@ -42,7 +42,7 @@ local gry_wht = style.gray_white
local period = core.flasher.PERIOD local period = core.flasher.PERIOD
-- create a unit view -- create a unit view
---@param parent graphics_element parent ---@param parent Container parent
---@param id integer ---@param id integer
local function init(parent, id) local function init(parent, id)
local s_hi_box = style.theme.highlight_box local s_hi_box = style.theme.highlight_box
@ -62,7 +62,7 @@ local function init(parent, id)
local ind_wht = style.ind_wht local ind_wht = style.ind_wht
local db = iocontrol.get_db() local db = iocontrol.get_db()
local unit = db.units[id] ---@type ioctl_unit local unit = db.units[id]
local f_ps = db.facility.ps local f_ps = db.facility.ps
local main = Div{parent=parent,x=1,y=1} local main = Div{parent=parent,x=1,y=1}
@ -361,7 +361,7 @@ local function init(parent, id)
---------------------- ----------------------
local burn_control = Div{parent=main,x=12,y=28,width=19,height=3,fg_bg=s_hi_box} local burn_control = Div{parent=main,x=12,y=28,width=19,height=3,fg_bg=s_hi_box}
local burn_rate = SpinboxNumeric{parent=burn_control,x=2,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled} local burn_rate = NumericSpinbox{parent=burn_control,x=2,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=arrow_fg_bg,arrow_disable=style.theme.disabled}
TextBox{parent=burn_control,x=9,y=2,text="mB/t",fg_bg=style.theme.label_fg} TextBox{parent=burn_control,x=9,y=2,text="mB/t",fg_bg=style.theme.label_fg}
local set_burn = function () unit.set_burn(burn_rate.get_value()) end local set_burn = function () unit.set_burn(burn_rate.get_value()) end

View File

@ -8,16 +8,16 @@ local style = require("coordinator.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local PipeNetwork = require("graphics.elements.pipenet") local PipeNetwork = require("graphics.elements.PipeNetwork")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local Rectangle = require("graphics.elements.rectangle") local Rectangle = require("graphics.elements.Rectangle")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local IndicatorLight = require("graphics.elements.indicators.light") local IndicatorLight = require("graphics.elements.indicators.IndicatorLight")
local TriIndicatorLight = require("graphics.elements.indicators.trilight") local TriIndicatorLight = require("graphics.elements.indicators.TriIndicatorLight")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
@ -31,7 +31,7 @@ local wh_gray = style.wh_gray
local lg_gray = style.lg_gray local lg_gray = style.lg_gray
-- make a new unit flow window -- make a new unit flow window
---@param parent graphics_element parent ---@param parent Container parent
---@param x integer top left x ---@param x integer top left x
---@param y integer top left y ---@param y integer top left y
---@param wide boolean whether to render wide version ---@param wide boolean whether to render wide version

View File

@ -10,16 +10,16 @@ local reactor_view = require("coordinator.ui.components.reactor")
local boiler_view = require("coordinator.ui.components.boiler") local boiler_view = require("coordinator.ui.components.boiler")
local turbine_view = require("coordinator.ui.components.turbine") local turbine_view = require("coordinator.ui.components.turbine")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local PipeNetwork = require("graphics.elements.pipenet") local PipeNetwork = require("graphics.elements.PipeNetwork")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
local pipe = core.pipe local pipe = core.pipe
-- make a new unit overview window -- make a new unit overview window
---@param parent graphics_element parent ---@param parent Container parent
---@param x integer top left x ---@param x integer top left x
---@param y integer top left y ---@param y integer top left y
---@param unit ioctl_unit unit database entry ---@param unit ioctl_unit unit database entry

View File

@ -13,15 +13,15 @@ local unit_flow = require("coordinator.ui.components.unit_flow")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local PipeNetwork = require("graphics.elements.pipenet") local PipeNetwork = require("graphics.elements.PipeNetwork")
local Rectangle = require("graphics.elements.rectangle") local Rectangle = require("graphics.elements.Rectangle")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local HorizontalBar = require("graphics.elements.indicators.hbar") local HorizontalBar = require("graphics.elements.indicators.HorizontalBar")
local IndicatorLight = require("graphics.elements.indicators.light") local IndicatorLight = require("graphics.elements.indicators.IndicatorLight")
local StateIndicator = require("graphics.elements.indicators.state") local StateIndicator = require("graphics.elements.indicators.StateIndicator")
local CONTAINER_MODE = types.CONTAINER_MODE local CONTAINER_MODE = types.CONTAINER_MODE
@ -34,7 +34,7 @@ local pipe = core.pipe
local wh_gray = style.wh_gray local wh_gray = style.wh_gray
-- create new flow view -- create new flow view
---@param main graphics_element main displaybox ---@param main DisplayBox main displaybox
local function init(main) local function init(main)
local s_hi_bright = style.theme.highlight_box_bright local s_hi_bright = style.theme.highlight_box_bright
local s_field = style.theme.field_box local s_field = style.theme.field_box
@ -84,8 +84,7 @@ local function init(main)
table.insert(water_pipes, pipe(2, y, 2, y + 3, colors.blue, true)) table.insert(water_pipes, pipe(2, y, 2, y + 3, colors.blue, true))
table.insert(water_pipes, pipe(2, y, 21, y, colors.blue, true)) table.insert(water_pipes, pipe(2, y, 21, y, colors.blue, true))
local u = units[i] ---@type ioctl_unit local x = util.trinary(units[i].num_boilers == 0, 45, 84)
local x = util.trinary(u.num_boilers == 0, 45, 84)
table.insert(water_pipes, pipe(21, y, x, y + 2, colors.blue, true, true)) table.insert(water_pipes, pipe(21, y, x, y + 2, colors.blue, true, true))
end end
end end
@ -102,8 +101,7 @@ local function init(main)
table.insert(water_pipes, pipe(2, y, 21, y, colors.blue, true)) table.insert(water_pipes, pipe(2, y, 21, y, colors.blue, true))
end end
local u = units[i] ---@type ioctl_unit local x = util.trinary(units[i].num_boilers == 0, 45, 84)
local x = util.trinary(u.num_boilers == 0, 45, 84)
table.insert(water_pipes, pipe(21, y, x, y + 2, colors.blue, true, true)) table.insert(water_pipes, pipe(21, y, x, y + 2, colors.blue, true, true))
end end
end end

View File

@ -14,16 +14,16 @@ local pkt_entry = require("coordinator.ui.components.pkt_entry")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local ListBox = require("graphics.elements.listbox") local ListBox = require("graphics.elements.ListBox")
local MultiPane = require("graphics.elements.multipane") local MultiPane = require("graphics.elements.MultiPane")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local TabBar = require("graphics.elements.controls.tabbar") local TabBar = require("graphics.elements.controls.TabBar")
local LED = require("graphics.elements.indicators.led") local LED = require("graphics.elements.indicators.LED")
local LEDPair = require("graphics.elements.indicators.ledpair") local LEDPair = require("graphics.elements.indicators.LEDPair")
local RGBLED = require("graphics.elements.indicators.ledrgb") local RGBLED = require("graphics.elements.indicators.RGBLED")
local LINK_STATE = types.PANEL_LINK_STATE local LINK_STATE = types.PANEL_LINK_STATE
@ -34,7 +34,7 @@ local cpair = core.cpair
local led_grn = style.led_grn local led_grn = style.led_grn
-- create new front panel view -- create new front panel view
---@param panel graphics_element main displaybox ---@param panel DisplayBox main displaybox
---@param num_units integer number of units (number of unit monitors) ---@param num_units integer number of units (number of unit monitors)
local function init(panel, num_units) local function init(panel, num_units)
local ps = iocontrol.get_db().fp.ps local ps = iocontrol.get_db().fp.ps

View File

@ -14,14 +14,14 @@ local unit_overview = require("coordinator.ui.components.unit_overview")
local core = require("graphics.core") local core = require("graphics.core")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
-- create new main view -- create new main view
---@param main graphics_element main displaybox ---@param main DisplayBox main displaybox
local function init(main) local function init(main)
local s_header = style.theme.header local s_header = style.theme.header
@ -37,7 +37,8 @@ local function init(main)
ping.register(facility.ps, "sv_ping", ping.update) ping.register(facility.ps, "sv_ping", ping.update)
datetime.register(facility.ps, "date_time", datetime.set_value) datetime.register(facility.ps, "date_time", datetime.set_value)
local uo_1, uo_2, uo_3, uo_4 ---@type graphics_element ---@type Div, Div, Div, Div
local uo_1, uo_2, uo_3, uo_4
local cnc_y_start = 3 local cnc_y_start = 3
local row_1_height = 0 local row_1_height = 0

View File

@ -5,7 +5,7 @@
local unit_detail = require("coordinator.ui.components.unit_detail") local unit_detail = require("coordinator.ui.components.unit_detail")
-- create a unit view -- create a unit view
---@param main graphics_element main displaybox ---@param main DisplayBox main displaybox
---@param id integer ---@param id integer
local function init(main, id) local function init(main, id)
unit_detail(main, id) unit_detail(main, id)

View File

@ -8,15 +8,17 @@ local util = require("scada-common.util")
local pgi = {} local pgi = {}
local data = { local data = {
pkt_list = nil, ---@type nil|graphics_element pkt_list = nil, ---@type ListBox|nil
pkt_entry = nil, ---@type function pkt_entry = nil, ---@type function
-- session entries -- session entries
s_entries = { pkt = {} } s_entries = {
pkt = {} ---@type Div[]
}
} }
-- link list boxes -- link list boxes
---@param pkt_list graphics_element pocket list element ---@param pkt_list ListBox pocket list element
---@param pkt_entry function pocket entry constructor ---@param pkt_entry fun(parent: ListBox, id: integer) : Div pocket entry constructor
function pgi.link_elements(pkt_list, pkt_entry) function pgi.link_elements(pkt_list, pkt_entry)
data.pkt_list = pkt_list data.pkt_list = pkt_list
data.pkt_entry = pkt_entry data.pkt_entry = pkt_entry

View File

@ -7,7 +7,7 @@ local flasher = require("graphics.flasher")
local core = {} local core = {}
core.version = "2.3.4" core.version = "2.4.0"
core.flasher = flasher core.flasher = flasher
core.events = events core.events = events
@ -17,6 +17,8 @@ core.events = events
---@enum ALIGN ---@enum ALIGN
core.ALIGN = { LEFT = 1, CENTER = 2, RIGHT = 3 } core.ALIGN = { LEFT = 1, CENTER = 2, RIGHT = 3 }
---@alias Container DisplayBox|Div|ListBox|MultiPane|AppMultiPane|Rectangle
---@class graphics_border ---@class graphics_border
---@field width integer ---@field width integer
---@field color color ---@field color color
@ -124,10 +126,10 @@ end
-- Interactive Field Manager -- Interactive Field Manager
---@param e graphics_base element ---@param e graphics_base element
---@param max_len any max value length ---@param max_len integer max value length
---@param fg_bg any enabled fg/bg ---@param fg_bg cpair enabled fg/bg
---@param dis_fg_bg any disabled fg/bg ---@param dis_fg_bg? cpair disabled fg/bg
---@param align_right any true to align content right while unfocused ---@param align_right? boolean true to align content right while unfocused
function core.new_ifield(e, max_len, fg_bg, dis_fg_bg, align_right) function core.new_ifield(e, max_len, fg_bg, dis_fg_bg, align_right)
local self = { local self = {
frame_start = 1, frame_start = 1,

View File

@ -11,8 +11,8 @@ local events = core.events
local element = {} local element = {}
---@class graphics_args_generic ---@class graphics_args
---@field window? table ---@field window? Window
---@field parent? graphics_element ---@field parent? graphics_element
---@field id? string element id ---@field id? string element id
---@field x? integer 1 if omitted ---@field x? integer 1 if omitted
@ -24,47 +24,6 @@ local element = {}
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
---@field can_focus? boolean true if this element can be focused, false by default ---@field can_focus? boolean true if this element can be focused, false by default
---@alias graphics_args graphics_args_generic
---|waiting_args
---|app_button_args
---|checkbox_args
---|hazard_button_args
---|multi_button_args
---|push_button_args
---|radio_2d_args
---|radio_button_args
---|sidebar_args
---|spinbox_args
---|switch_button_args
---|tabbar_args
---|number_field_args
---|text_field_args
---|alarm_indicator_light
---|core_map_args
---|data_indicator_args
---|hbar_args
---|icon_indicator_args
---|indicator_led_args
---|indicator_led_pair_args
---|indicator_led_rgb_args
---|indicator_light_args
---|power_indicator_args
---|rad_indicator_args
---|signal_bar_args
---|state_indicator_args
---|tristate_indicator_light_args
---|vbar_args
---|app_multipane_args
---|colormap_args
---|displaybox_args
---|div_args
---|listbox_args
---|multipane_args
---|pipenet_args
---|rectangle_args
---|textbox_args
---|tiling_args
---@class element_subscription ---@class element_subscription
---@field ps psil ps used ---@field ps psil ps used
---@field key string data key ---@field key string data key
@ -92,14 +51,14 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
is_root = args.parent == nil, is_root = args.parent == nil,
elem_type = debug.getinfo(2).name, elem_type = debug.getinfo(2).name,
define_completed = false, define_completed = false,
p_window = nil, ---@type table p_window = nil, ---@type Window
position = events.new_coord_2d(1, 1), position = events.new_coord_2d(1, 1),
bounds = { x1 = 1, y1 = 1, x2 = 1, y2 = 1 }, ---@class element_bounds bounds = { x1 = 1, y1 = 1, x2 = 1, y2 = 1 }, ---@class element_bounds
offset_x = 0, offset_x = 0,
offset_y = 0, offset_y = 0,
next_y = 1, -- next child y coordinate next_y = 1, -- next child y coordinate
next_id = 0, -- next child ID next_id = 0, -- next child ID
subscriptions = {}, subscriptions = {}, ---@type { ps: psil, key: string, func: function }[]
button_down = { events.new_coord_2d(-1, -1), events.new_coord_2d(-1, -1), events.new_coord_2d(-1, -1) }, button_down = { events.new_coord_2d(-1, -1), events.new_coord_2d(-1, -1), events.new_coord_2d(-1, -1) },
focused = false, focused = false,
mt = {} mt = {}
@ -109,13 +68,13 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
local protected = { local protected = {
enabled = true, enabled = true,
value = nil, ---@type any value = nil, ---@type any
window = nil, ---@type table window = nil, ---@type Window
content_window = nil, ---@type table|nil content_window = nil, ---@type Window|nil
mouse_window_shift = { x = 0, y = 0 }, mouse_window_shift = { x = 0, y = 0 },
fg_bg = core.cpair(colors.white, colors.black), fg_bg = core.cpair(colors.white, colors.black),
frame = core.gframe(1, 1, 1, 1), frame = core.gframe(1, 1, 1, 1),
children = {}, children = {}, ---@type graphics_base[]
child_id_map = {} child_id_map = {} ---@type { [element_id]: integer }
} }
-- element as string -- element as string
@ -128,9 +87,9 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
setmetatable(public, self.mt) setmetatable(public, self.mt)
----------------------- ------------------------------
-- PRIVATE FUNCTIONS -- --#region PRIVATE FUNCTIONS --
----------------------- ------------------------------
-- use tab to jump to the next focusable field -- use tab to jump to the next focusable field
---@param reverse boolean ---@param reverse boolean
@ -168,10 +127,10 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
end end
end end
---@param children table ---@param children graphics_base[]
local function traverse(children) local function traverse(children)
for i = 1, #children do for i = 1, #children do
local child = children[i] ---@type graphics_base local child = children[i]
handle_element(child.get()) handle_element(child.get())
if child.get().is_visible() then traverse(child.children) end if child.get().is_visible() then traverse(child.children) end
end end
@ -191,9 +150,11 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
end end
end end
------------------------- --#endregion
-- PROTECTED FUNCTIONS --
------------------------- --------------------------------
--#region PROTECTED FUNCTIONS --
--------------------------------
-- prepare the template -- prepare the template
---@param offset_x integer x offset for mouse events ---@param offset_x integer x offset for mouse events
@ -286,24 +247,29 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
-- alias functions -- alias functions
-- window set cursor position -- window set cursor position<br>
---@see Window.setCursorPos
---@param x integer ---@param x integer
---@param y integer ---@param y integer
function protected.w_set_cur(x, y) protected.window.setCursorPos(x, y) end function protected.w_set_cur(x, y) protected.window.setCursorPos(x, y) end
-- set background color -- set background color<br>
---@see Window.setBackgroundColor
---@param c color ---@param c color
function protected.w_set_bkg(c) protected.window.setBackgroundColor(c) end function protected.w_set_bkg(c) protected.window.setBackgroundColor(c) end
-- set foreground (text) color -- set foreground (text) color<br>
---@see Window.setTextColor
---@param c color ---@param c color
function protected.w_set_fgd(c) protected.window.setTextColor(c) end function protected.w_set_fgd(c) protected.window.setTextColor(c) end
-- write text -- write text<br>
---@see Window.write
---@param str string ---@param str string
function protected.w_write(str) protected.window.write(str) end function protected.w_write(str) protected.window.write(str) end
-- blit text -- blit text<br>
---@see Window.blit
---@param str string ---@param str string
---@param fg string ---@param fg string
---@param bg string ---@param bg string
@ -335,8 +301,10 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
-- report completion of element instantiation and get the public interface -- report completion of element instantiation and get the public interface
---@nodiscard ---@nodiscard
---@param redraw? boolean true to call redraw as part of completing this element
---@return graphics_element element, element_id id ---@return graphics_element element, element_id id
function protected.complete() function protected.complete(redraw)
if redraw then protected.redraw() end
if args.parent ~= nil then args.parent.__child_ready(self.id, public) end if args.parent ~= nil then args.parent.__child_ready(self.id, public) end
return public, self.id return public, self.id
end end
@ -352,7 +320,7 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
-- focus this element and take away focus from all other elements -- focus this element and take away focus from all other elements
function protected.take_focus() args.parent.__focus_child(public) end function protected.take_focus() args.parent.__focus_child(public) end
-- action handlers -- --#region Action Handlers
-- luacheck: push ignore -- luacheck: push ignore
---@diagnostic disable: unused-local, unused-vararg ---@diagnostic disable: unused-local, unused-vararg
@ -401,14 +369,12 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
function protected.handle_paste(text) end function protected.handle_paste(text) end
-- handle data value changes -- handle data value changes
---@vararg any value(s) ---@param ... any value(s)
function protected.on_update(...) end function protected.on_update(...) end
-- callback on control press responses --#endregion
---@param result any
function protected.response_callback(result) end
-- accessors and control -- --#region Accessors and Control
-- get value -- get value
---@nodiscard ---@nodiscard
@ -427,11 +393,11 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
function protected.set_max(max) end function protected.set_max(max) end
-- custom recolor command, varies by element if implemented -- custom recolor command, varies by element if implemented
---@vararg cpair|color color(s) ---@param ... cpair|color color(s)
function protected.recolor(...) end function protected.recolor(...) end
-- custom resize command, varies by element if implemented -- custom resize command, varies by element if implemented
---@vararg integer sizing ---@param ... integer sizing
function protected.resize(...) end function protected.resize(...) end
-- luacheck: pop -- luacheck: pop
@ -446,9 +412,13 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
-- stop animations -- stop animations
function protected.stop_anim() end function protected.stop_anim() end
----------- --#endregion
-- SETUP --
----------- --#endregion
------------------
--#region SETUP --
------------------
-- get the parent window -- get the parent window
self.p_window = args.window self.p_window = args.window
@ -467,9 +437,11 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
self.id = args.parent.__add_child(args.id, protected) self.id = args.parent.__add_child(args.id, protected)
end end
---------------------- --#endregion
-- PUBLIC FUNCTIONS --
---------------------- -----------------------------
--#region PUBLIC FUNCTIONS --
-----------------------------
-- get the window object -- get the window object
---@nodiscard ---@nodiscard
@ -511,9 +483,10 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
end end
end end
-- ELEMENT TREE -- --#region ELEMENT TREE
-- add a child element -- add a child element
---@package
---@nodiscard ---@nodiscard
---@param key string|nil id ---@param key string|nil id
---@param child graphics_base ---@param child graphics_base
@ -523,7 +496,7 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
self.next_y = child.frame.y + child.frame.h self.next_y = child.frame.y + child.frame.h
local id = key ---@type string|integer|nil local id = key ---@type element_id|nil
if id == nil then if id == nil then
id = self.next_id id = self.next_id
self.next_id = self.next_id + 1 self.next_id = self.next_id + 1
@ -537,6 +510,7 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
end end
-- remove a child element -- remove a child element
---@package
---@param id element_id id ---@param id element_id id
function public.__remove_child(id) function public.__remove_child(id)
local index = protected.child_id_map[id] local index = protected.child_id_map[id]
@ -548,11 +522,13 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
end end
-- actions to take upon a child element becoming ready (initial draw/construction completed) -- actions to take upon a child element becoming ready (initial draw/construction completed)
---@package
---@param key element_id id ---@param key element_id id
---@param child graphics_element ---@param child graphics_element
function public.__child_ready(key, child) protected.on_added(key, child) end function public.__child_ready(key, child) protected.on_added(key, child) end
-- focus solely on this child -- focus solely on this child
---@package
---@param child graphics_element ---@param child graphics_element
function public.__focus_child(child) function public.__focus_child(child)
if self.is_root then if self.is_root then
@ -562,6 +538,7 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
end end
-- a child was focused, used to make sure it is actually visible to the user in the content frame -- a child was focused, used to make sure it is actually visible to the user in the content frame
---@package
---@param child graphics_element ---@param child graphics_element
function public.__child_focused(child) function public.__child_focused(child)
protected.on_child_focused(child) protected.on_child_focused(child)
@ -571,8 +548,8 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
-- get a child element -- get a child element
---@nodiscard ---@nodiscard
---@param id element_id ---@param id element_id
---@return graphics_element ---@return graphics_element element
function public.get_child(id) return protected.children[protected.child_id_map[id]].get() end function public.get_child(id) return ({ protected.children[protected.child_id_map[id]].get() })[1] end
-- get all children -- get all children
---@nodiscard ---@nodiscard
@ -619,29 +596,33 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
local elem = child.get().get_element_by_id(id) local elem = child.get().get_element_by_id(id)
if elem ~= nil then return elem end if elem ~= nil then return elem end
end end
else return protected.children[index].get() end else return ({ protected.children[index].get() })[1] end
end end
-- AUTO-PLACEMENT -- --#endregion
--#region AUTO-PLACEMENT
-- skip a line for automatically placed elements -- skip a line for automatically placed elements
function public.line_break() function public.line_break()
self.next_y = self.next_y + 1 self.next_y = self.next_y + 1
end end
-- PROPERTIES -- --#endregion
-- get element id --#region PROPERTIES
-- get element ID
---@nodiscard ---@nodiscard
---@return element_id ---@return element_id
function public.get_id() return self.id end function public.get_id() return self.id end
-- get element x -- get element relative x position
---@nodiscard ---@nodiscard
---@return integer x ---@return integer x
function public.get_x() return protected.frame.x end function public.get_x() return protected.frame.x end
-- get element y -- get element relative y position
---@nodiscard ---@nodiscard
---@return integer y ---@return integer y
function public.get_y() return protected.frame.y end function public.get_y() return protected.frame.y end
@ -661,12 +642,12 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
---@return cpair fg_bg ---@return cpair fg_bg
function public.get_fg_bg() return protected.fg_bg end function public.get_fg_bg() return protected.fg_bg end
-- get the element value -- get the element's value
---@nodiscard ---@nodiscard
---@return any value ---@return any value
function public.get_value() return protected.get_value() end function public.get_value() return protected.get_value() end
-- set the element value -- set the element's value
---@param value any new value ---@param value any new value
function public.set_value(value) protected.set_value(value) end function public.set_value(value) protected.set_value(value) end
@ -728,11 +709,11 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
end end
-- custom recolor command, varies by element if implemented -- custom recolor command, varies by element if implemented
---@vararg cpair|color color(s) ---@param ... cpair|color color(s)
function public.recolor(...) protected.recolor(...) end function public.recolor(...) protected.recolor(...) end
-- resize attributes of the element value if supported -- resize attributes of the element value if supported
---@vararg number dimensions (element specific) ---@param ... number dimensions (element specific)
function public.resize(...) protected.resize(...) end function public.resize(...) protected.resize(...) end
-- reposition the element window<br> -- reposition the element window<br>
@ -756,7 +737,9 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
self.bounds.y2 = self.position.y + protected.frame.h - 1 self.bounds.y2 = self.position.y + protected.frame.h - 1
end end
-- FUNCTION CALLBACKS -- --#endregion
--#region FUNCTION CALLBACKS
-- handle a monitor touch or mouse click if this element is visible -- handle a monitor touch or mouse click if this element is visible
---@param event mouse_interaction mouse interaction event ---@param event mouse_interaction mouse interaction event
@ -818,13 +801,9 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
end end
-- draw the element given new data -- draw the element given new data
---@vararg any new data ---@param ... any new data
function public.update(...) protected.on_update(...) end function public.update(...) protected.on_update(...) end
-- on a control request response
---@param result any
function public.on_response(result) protected.response_callback(result) end
-- register a callback with a PSIL, allowing for automatic unregister on delete<br> -- register a callback with a PSIL, allowing for automatic unregister on delete<br>
-- do not use graphics elements directly with PSIL subscribe() -- do not use graphics elements directly with PSIL subscribe()
---@param ps psil PSIL to subscribe to ---@param ps psil PSIL to subscribe to
@ -835,7 +814,9 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
ps.subscribe(key, func) ps.subscribe(key, func)
end end
-- VISIBILITY & ANIMATIONS -- --#endregion
--#region VISIBILITY & ANIMATIONS
-- check if this element is visible -- check if this element is visible
function public.is_visible() return protected.window.isVisible() end function public.is_visible() return protected.window.isVisible() end
@ -849,6 +830,7 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
-- hide the element and disables animations<br> -- hide the element and disables animations<br>
-- this alone does not cause an element to be fully hidden, it only prevents updates from being shown<br> -- this alone does not cause an element to be fully hidden, it only prevents updates from being shown<br>
---@see Window.redraw
---@see graphics_element.redraw ---@see graphics_element.redraw
---@see graphics_element.content_redraw ---@see graphics_element.content_redraw
---@param clear? boolean true to visibly hide this element (redraws the parent) ---@param clear? boolean true to visibly hide this element (redraws the parent)
@ -900,6 +882,10 @@ function element.new(args, constraint, child_offset_x, child_offset_y)
end end
end end
--#endregion
--#endregion
return protected return protected
end end

View File

@ -24,15 +24,15 @@ local MOUSE_CLICK = core.events.MOUSE_CLICK
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new app multipane element -- Create a new app multipane container element.
---@nodiscard ---@nodiscard
---@param args app_multipane_args ---@param args app_multipane_args
---@return graphics_element element, element_id id ---@return AppMultiPane element, element_id id
local function multipane(args) return function (args)
element.assert(type(args.panes) == "table", "panes is a required field") element.assert(type(args.panes) == "table", "panes is a required field")
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = 1 e.value = 1
@ -100,10 +100,8 @@ local function multipane(args)
end end
end end
-- initial draw ---@class AppMultiPane:graphics_element
e.redraw() local AppMultiPane, id = e.complete(true)
return e.complete() return AppMultiPane, id
end end
return multipane

View File

@ -9,10 +9,10 @@ local element = require("graphics.element")
---@field y? integer auto incremented if omitted ---@field y? integer auto incremented if omitted
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new color map -- Create a horizontal reference color map. Primarily used for tuning custom colors.
---@param args colormap_args ---@param args colormap_args
---@return graphics_element element, element_id id ---@return ColorMap element, element_id id
local function colormap(args) return function (args)
local bkg = "008877FFCCEE114455DD9933BBAA2266" local bkg = "008877FFCCEE114455DD9933BBAA2266"
local spaces = string.rep(" ", 32) local spaces = string.rep(" ", 32)
@ -20,7 +20,7 @@ local function colormap(args)
args.height = 1 args.height = 1
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
-- draw color map -- draw color map
function e.redraw() function e.redraw()
@ -28,10 +28,8 @@ local function colormap(args)
e.w_blit(spaces, bkg, bkg) e.w_blit(spaces, bkg, bkg)
end end
-- initial draw ---@class ColorMap:graphics_element
e.redraw() local ColorMap, id = e.complete(true)
return e.complete() return ColorMap, id
end end
return colormap

View File

@ -13,13 +13,16 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new root display box -- Create a root display box.
---@nodiscard ---@nodiscard
---@param args displaybox_args ---@param args displaybox_args
---@return graphics_element element, element_id id ---@return DisplayBox element, element_id id
local function displaybox(args) return function (args)
-- create new graphics element base object -- create new graphics element base object
return element.new(args).complete() local e = element.new(args --[[@as graphics_args]])
end
return displaybox ---@class DisplayBox:graphics_element
local DisplayBox, id = e.complete()
return DisplayBox, id
end

View File

@ -13,13 +13,16 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new div element -- Create a new div container element.
---@nodiscard ---@nodiscard
---@param args div_args ---@param args div_args
---@return graphics_element element, element_id id ---@return Div element, element_id id
local function div(args) return function (args)
-- create new graphics element base object -- create new graphics element base object
return element.new(args).complete() local e = element.new(args --[[@as graphics_args]])
end
return div ---@class Div:graphics_element
local Div, id = e.complete()
return Div, id
end

View File

@ -30,15 +30,15 @@ local MOUSE_CLICK = core.events.MOUSE_CLICK
---@field y integer y position ---@field y integer y position
---@field h integer element height ---@field h integer element height
-- new listbox element -- Create a new scrollable listbox container element.
---@nodiscard ---@nodiscard
---@param args listbox_args ---@param args listbox_args
---@return graphics_element element, element_id id ---@return ListBox element, element_id id
local function listbox(args) return function (args)
args.can_focus = true args.can_focus = true
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
-- create content window for child elements -- create content window for child elements
local scroll_frame = window.create(e.window, 1, 1, e.frame.w - 1, args.scroll_height, false) local scroll_frame = window.create(e.window, 1, 1, e.frame.w - 1, args.scroll_height, false)
@ -339,10 +339,8 @@ local function listbox(args)
draw_bar() draw_bar()
end end
-- initial draw ---@class ListBox:graphics_element
e.redraw() local ListBox, id = e.complete(true)
return e.complete() return ListBox, id
end end
return listbox

View File

@ -14,15 +14,15 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new multipane element -- Create a new multipane container element.
---@nodiscard ---@nodiscard
---@param args multipane_args ---@param args multipane_args
---@return graphics_element element, element_id id ---@return MultiPane element, element_id id
local function multipane(args) return function (args)
element.assert(type(args.panes) == "table", "panes is a required field") element.assert(type(args.panes) == "table", "panes is a required field")
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = 1 e.value = 1
@ -41,10 +41,8 @@ local function multipane(args)
end end
end end
-- initial draw ---@class MultiPane:graphics_element
e.redraw() local MultiPane, id = e.complete(true)
return e.complete() return MultiPane, id
end end
return multipane

View File

@ -20,10 +20,10 @@ local element = require("graphics.element")
---@field fg string foreground blit ---@field fg string foreground blit
---@field bg string background blit ---@field bg string background blit
-- new pipe network -- Create a pipe network diagram.
---@param args pipenet_args ---@param args pipenet_args
---@return graphics_element element, element_id id ---@return PipeNetwork element, element_id id
local function pipenet(args) return function (args)
element.assert(type(args.pipes) == "table", "pipes is a required field") element.assert(type(args.pipes) == "table", "pipes is a required field")
args.width = 0 args.width = 0
@ -47,7 +47,7 @@ local function pipenet(args)
end end
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
-- determine if there are any thin pipes involved -- determine if there are any thin pipes involved
local any_thin = false local any_thin = false
@ -322,10 +322,8 @@ local function pipenet(args)
if any_thin then map_draw() else vector_draw() end if any_thin then map_draw() else vector_draw() end
end end
-- initial draw ---@class PipeNetwork:graphics_element
e.redraw() local PipeNetwork, id = e.complete(true)
return e.complete() return PipeNetwork, id
end end
return pipenet

View File

@ -18,10 +18,10 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new rectangle -- Create a new rectangle container element.
---@param args rectangle_args ---@param args rectangle_args
---@return graphics_element element, element_id id ---@return Rectangle element, element_id id
local function rectangle(args) return function (args)
element.assert(args.border ~= nil or args.thin ~= true, "thin requires border to be provided") element.assert(args.border ~= nil or args.thin ~= true, "thin requires border to be provided")
-- if thin, then width will always need to be 1 -- if thin, then width will always need to be 1
@ -45,7 +45,7 @@ local function rectangle(args)
end end
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args, nil, offset_x, offset_y) local e = element.new(args --[[@as graphics_args]], nil, offset_x, offset_y)
-- create content window for child elements -- create content window for child elements
e.content_window = window.create(e.window, 1 + offset_x, 1 + offset_y, e.frame.w - (2 * offset_x), e.frame.h - (2 * offset_y)) e.content_window = window.create(e.window, 1 + offset_x, 1 + offset_y, e.frame.w - (2 * offset_x), e.frame.h - (2 * offset_y))
@ -191,7 +191,8 @@ local function rectangle(args)
e.redraw() e.redraw()
end end
return e.complete() ---@class Rectangle:graphics_element
end local Rectangle, id = e.complete()
return rectangle return Rectangle, id
end

View File

@ -21,10 +21,10 @@ local ALIGN = core.ALIGN
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new text box -- Create a new text box element.
---@param args textbox_args ---@param args textbox_args
---@return graphics_element element, element_id id ---@return TextBox element, element_id id
local function textbox(args) return function (args)
element.assert(type(args.text) == "string", "text is a required field") element.assert(type(args.text) == "string", "text is a required field")
if args.anchor == true then args.can_focus = true end if args.anchor == true then args.can_focus = true end
@ -42,7 +42,7 @@ local function textbox(args)
end end
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args, constrain) local e = element.new(args --[[@as graphics_args]], constrain)
e.value = args.text e.value = args.text
@ -82,10 +82,8 @@ local function textbox(args)
e.redraw() e.redraw()
end end
-- initial draw ---@class TextBox:graphics_element
e.redraw() local TextBox, id = e.complete(true)
return e.complete() return TextBox, id
end end
return textbox

View File

@ -18,14 +18,14 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new tiling box -- Create a new tiling box element.
---@param args tiling_args ---@param args tiling_args
---@return graphics_element element, element_id id ---@return Tiling element, element_id id
local function tiling(args) return function (args)
element.assert(type(args.fill_c) == "table", "fill_c is a required field") element.assert(type(args.fill_c) == "table", "fill_c is a required field")
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
local fill_a = args.fill_c.blit_a local fill_a = args.fill_c.blit_a
local fill_b = args.fill_c.blit_b local fill_b = args.fill_c.blit_b
@ -52,7 +52,7 @@ local function tiling(args)
element.assert(start_x <= inner_width, "start_x > inner_width") element.assert(start_x <= inner_width, "start_x > inner_width")
element.assert(start_y <= inner_height, "start_y > inner_height") element.assert(start_y <= inner_height, "start_y > inner_height")
-- draw tiling box -- draw the tiling box
function e.redraw() function e.redraw()
local alternator = true local alternator = true
@ -86,10 +86,8 @@ local function tiling(args)
end end
end end
-- initial draw ---@class Tiling:graphics_element
e.redraw() local Tiling, id = e.complete(true)
return e.complete() return Tiling, id
end end
return tiling

View File

@ -12,10 +12,10 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new waiting animation element -- Create a new waiting animation element.
---@param args waiting_args ---@param args waiting_args
---@return graphics_element element, element_id id ---@return Waiting element, element_id id
local function waiting(args) return function (args)
local state = 0 local state = 0
local run_animation = false local run_animation = false
@ -23,7 +23,7 @@ local function waiting(args)
args.height = 3 args.height = 3
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
local blit_fg = e.fg_bg.blit_fgd local blit_fg = e.fg_bg.blit_fgd
local blit_bg = e.fg_bg.blit_bkg local blit_bg = e.fg_bg.blit_bkg
@ -103,7 +103,8 @@ local function waiting(args)
e.start_anim() e.start_anim()
return e.complete() ---@class Waiting:graphics_element
end local Waiting, id = e.complete()
return waiting return Waiting, id
end

View File

@ -20,10 +20,10 @@ local MOUSE_CLICK = core.events.MOUSE_CLICK
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new app button -- Create a new app icon style button control element, like on a mobile device.
---@param args app_button_args ---@param args app_button_args
---@return graphics_element element, element_id id ---@return App element, element_id id
local function app_button(args) return function (args)
element.assert(type(args.text) == "string", "text is a required field") element.assert(type(args.text) == "string", "text is a required field")
element.assert(type(args.title) == "string", "title is a required field") element.assert(type(args.title) == "string", "title is a required field")
element.assert(type(args.callback) == "function", "callback is a required field") element.assert(type(args.callback) == "function", "callback is a required field")
@ -33,7 +33,7 @@ local function app_button(args)
args.width = 7 args.width = 7
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
-- draw the app button -- draw the app button
local function draw() local function draw()
@ -123,10 +123,8 @@ local function app_button(args)
draw() draw()
end end
-- initial draw ---@class App:graphics_element
e.redraw() local App, id = e.complete(true)
return e.complete() return App, id
end end
return app_button

View File

@ -15,10 +15,10 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new checkbox control -- Create a new checkbox control element.
---@param args checkbox_args ---@param args checkbox_args
---@return graphics_element element, element_id id ---@return Checkbox element, element_id id
local function checkbox(args) return function (args)
element.assert(type(args.label) == "string", "label is a required field") element.assert(type(args.label) == "string", "label is a required field")
element.assert(type(args.box_fg_bg) == "table", "box_fg_bg is a required field") element.assert(type(args.box_fg_bg) == "table", "box_fg_bg is a required field")
@ -27,7 +27,7 @@ local function checkbox(args)
args.width = 2 + string.len(args.label) args.width = 2 + string.len(args.label)
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = args.default == true e.value = args.default == true
@ -112,10 +112,8 @@ local function checkbox(args)
draw_label() draw_label()
end end
-- initial draw ---@class Checkbox:graphics_element
e.redraw() local Checkbox, id = e.complete(true)
return e.complete() return Checkbox, id
end end
return checkbox

View File

@ -18,10 +18,10 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new hazard button -- Create a new hazard button control element.
---@param args hazard_button_args ---@param args hazard_button_args
---@return graphics_element element, element_id id ---@return HazardButton element, element_id id
local function hazard_button(args) return function (args)
element.assert(type(args.text) == "string", "text is a required field") element.assert(type(args.text) == "string", "text is a required field")
element.assert(type(args.accent) == "number", "accent is a required field") element.assert(type(args.accent) == "number", "accent is a required field")
element.assert(type(args.callback) == "function", "callback is a required field") element.assert(type(args.callback) == "function", "callback is a required field")
@ -32,7 +32,7 @@ local function hazard_button(args)
local timeout = args.timeout or 1.5 local timeout = args.timeout or 1.5
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
-- draw border -- draw border
---@param accent color accent color ---@param accent color accent color
@ -159,13 +159,6 @@ local function hazard_button(args)
end end
end end
-- callback on request response
---@param result boolean true for success, false for failure
function e.response_callback(result)
tcd.abort(on_timeout)
if result then on_success() else on_failure(0) end
end
-- set the value (true simulates pressing the button) -- set the value (true simulates pressing the button)
---@param val boolean new value ---@param val boolean new value
function e.set_value(val) function e.set_value(val)
@ -198,10 +191,15 @@ local function hazard_button(args)
draw_border(args.accent) draw_border(args.accent)
end end
-- initial draw ---@class HazardButton:graphics_element
e.redraw() local HazardButton, id = e.complete(true)
return e.complete() -- callback for request response
---@param success boolean
function HazardButton.on_response(success)
tcd.abort(on_timeout)
if success then on_success() else on_failure(0) end
end end
return hazard_button return HazardButton, id
end

View File

@ -25,10 +25,10 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new multi button (latch selection, exclusively one button at a time) -- Create a new multi button control element (latch selection, exclusively one button at a time).
---@param args multi_button_args ---@param args multi_button_args
---@return graphics_element element, element_id id ---@return MultiButton element, element_id id
local function multi_button(args) return function (args)
element.assert(type(args.options) == "table", "options is a required field") element.assert(type(args.options) == "table", "options is a required field")
element.assert(#args.options > 0, "at least one option is required") element.assert(#args.options > 0, "at least one option is required")
element.assert(type(args.callback) == "function", "callback is a required field") element.assert(type(args.callback) == "function", "callback is a required field")
@ -52,7 +52,7 @@ local function multi_button(args)
args.width = (button_width * #args.options) + #args.options + 1 args.width = (button_width * #args.options) + #args.options + 1
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
-- button state (convert nil to 1 if missing) -- button state (convert nil to 1 if missing)
e.value = args.default or 1 e.value = args.default or 1
@ -126,10 +126,8 @@ local function multi_button(args)
e.redraw() e.redraw()
end end
-- initial draw ---@class MultiButton:graphics_element
e.redraw() local MultiButton, id = e.complete(true)
return e.complete() return MultiButton, id
end end
return multi_button

View File

@ -20,10 +20,10 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new spinbox control (minimum value is 0) -- Create a new spinbox control element (minimum value is 0).
---@param args spinbox_args ---@param args spinbox_args
---@return graphics_element element, element_id id ---@return NumericSpinbox element, element_id id
local function spinbox(args) return function (args)
-- properties -- properties
local digits = {} local digits = {}
local wn_prec = args.whole_num_precision local wn_prec = args.whole_num_precision
@ -51,7 +51,7 @@ local function spinbox(args)
args.height = 3 args.height = 3
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
-- set initial value -- set initial value
e.value = args.default or 0 e.value = args.default or 0
@ -179,10 +179,8 @@ local function spinbox(args)
draw_arrows(util.trinary(e.enabled, args.arrow_fg_bg.fgd, args.arrow_disable or colors.lightGray)) draw_arrows(util.trinary(e.enabled, args.arrow_fg_bg.fgd, args.arrow_disable or colors.lightGray))
end end
-- initial draw ---@class NumericSpinbox:graphics_element
e.redraw() local NumericSpinbox, id = e.complete(true)
return e.complete() return NumericSpinbox, id
end end
return spinbox

View File

@ -25,10 +25,10 @@ local KEY_CLICK = core.events.KEY_CLICK
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new push button -- Create a new push button control element.
---@param args push_button_args ---@param args push_button_args
---@return graphics_element element, element_id id ---@return PushButton element, element_id id
local function push_button(args) return function (args)
element.assert(type(args.text) == "string", "text is a required field") element.assert(type(args.text) == "string", "text is a required field")
element.assert(type(args.callback) == "function", "callback is a required field") element.assert(type(args.callback) == "function", "callback is a required field")
element.assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0), "min_width must be nil or a number > 0") element.assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0), "min_width must be nil or a number > 0")
@ -48,7 +48,7 @@ local function push_button(args)
end end
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args, constrain) local e = element.new(args --[[@as graphics_args]], constrain)
local text_lines = util.strwrap(args.text, e.frame.w) local text_lines = util.strwrap(args.text, e.frame.w)
@ -157,10 +157,8 @@ local function push_button(args)
e.on_focused = show_pressed e.on_focused = show_pressed
e.on_unfocused = show_unpressed e.on_unfocused = show_unpressed
-- initial draw ---@class PushButton:graphics_element
e.redraw() local PushButton, id = e.complete(true)
return e.complete() return PushButton, id
end end
return push_button

View File

@ -23,10 +23,10 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new 2D radio button list (latch selection, exclusively one color at a time) -- Create a new 2-dimensional (rows and columns of options) radio button list control element (latch selection, exclusively one color at a time).
---@param args radio_2d_args ---@param args radio_2d_args
---@return graphics_element element, element_id id ---@return Radio2D element, element_id id
local function radio_2d_button(args) return function (args)
element.assert(type(args.options) == "table" and #args.options > 0, "options should be a table with length >= 1") element.assert(type(args.options) == "table" and #args.options > 0, "options should be a table with length >= 1")
element.assert(util.is_int(args.rows) and util.is_int(args.columns), "rows/columns must be integers") element.assert(util.is_int(args.rows) and util.is_int(args.columns), "rows/columns must be integers")
element.assert((args.rows * args.columns) >= #args.options, "rows x columns size insufficient for provided number of options") element.assert((args.rows * args.columns) >= #args.options, "rows x columns size insufficient for provided number of options")
@ -70,7 +70,7 @@ local function radio_2d_button(args)
args.height = max_rows args.height = max_rows
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
-- selected option (convert nil to 1 if missing) -- selected option (convert nil to 1 if missing)
e.value = args.default or 1 e.value = args.default or 1
@ -194,10 +194,8 @@ local function radio_2d_button(args)
e.on_enabled = e.redraw e.on_enabled = e.redraw
e.on_disabled = e.redraw e.on_disabled = e.redraw
-- initial draw ---@class Radio2D:graphics_element
e.redraw() local Radio2D, id = e.complete(true)
return e.complete() return Radio2D, id
end end
return radio_2d_button

View File

@ -21,10 +21,10 @@ local KEY_CLICK = core.events.KEY_CLICK
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new radio button list (latch selection, exclusively one button at a time) -- Create a new radio button list control element (latch selection, exclusively one button at a time).
---@param args radio_button_args ---@param args radio_button_args
---@return graphics_element element, element_id id ---@return RadioButton element, element_id id
local function radio_button(args) return function (args)
element.assert(type(args.options) == "table", "options is a required field") element.assert(type(args.options) == "table", "options is a required field")
element.assert(#args.options > 0, "at least one option is required") element.assert(#args.options > 0, "at least one option is required")
element.assert(type(args.radio_colors) == "table", "radio_colors is a required field") element.assert(type(args.radio_colors) == "table", "radio_colors is a required field")
@ -49,7 +49,7 @@ local function radio_button(args)
args.height = #args.options -- one line per option args.height = #args.options -- one line per option
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
local focused_opt = 1 local focused_opt = 1
@ -139,10 +139,8 @@ local function radio_button(args)
e.on_enabled = e.redraw e.on_enabled = e.redraw
e.on_disabled = e.redraw e.on_disabled = e.redraw
-- initial draw ---@class RadioButton:graphics_element
e.redraw() local RadioButton, id = e.complete(true)
return e.complete() return RadioButton, id
end end
return radio_button

View File

@ -17,14 +17,14 @@ local MOUSE_CLICK = core.events.MOUSE_CLICK
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new sidebar tab selector -- Create a new sidebar tab selector control element.
---@param args sidebar_args ---@param args sidebar_args
---@return graphics_element element, element_id id ---@return Sidebar element, element_id id
local function sidebar(args) return function (args)
args.width = 3 args.width = 3
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
-- default to 1st tab -- default to 1st tab
e.value = 1 e.value = 1
@ -129,8 +129,14 @@ local function sidebar(args)
end end
-- update the sidebar navigation options -- update the sidebar navigation options
---@param items table sidebar entries ---@param items sidebar_entry[] sidebar entries
function e.on_update(items) function e.on_update(items)
---@class sidebar_entry
---@field label string
---@field tall boolean
---@field color cpair
---@field callback function|nil
local next_y = 1 local next_y = 1
tabs = {} tabs = {}
@ -160,9 +166,8 @@ local function sidebar(args)
-- element redraw -- element redraw
e.redraw = draw e.redraw = draw
e.redraw() ---@class Sidebar:graphics_element
local Sidebar, id = e.complete(true)
return e.complete() return Sidebar, id
end end
return sidebar

View File

@ -17,10 +17,10 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new switch button (latch high/low) -- Create a new latching switch button control element.
---@param args switch_button_args ---@param args switch_button_args
---@return graphics_element element, element_id id ---@return SwitchButton element, element_id id
local function switch_button(args) return function (args)
element.assert(type(args.text) == "string", "text is a required field") element.assert(type(args.text) == "string", "text is a required field")
element.assert(type(args.callback) == "function", "callback is a required field") element.assert(type(args.callback) == "function", "callback is a required field")
element.assert(type(args.active_fg_bg) == "table", "active_fg_bg is a required field") element.assert(type(args.active_fg_bg) == "table", "active_fg_bg is a required field")
@ -33,7 +33,7 @@ local function switch_button(args)
args.width = math.max(text_width, args.min_width) args.width = math.max(text_width, args.min_width)
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = args.default or false e.value = args.default or false
@ -72,10 +72,8 @@ local function switch_button(args)
e.redraw() e.redraw()
end end
-- initial draw ---@class SwitchButton:graphics_element
e.redraw() local SwitchButton, id = e.complete(true)
return e.complete() return SwitchButton, id
end end
return switch_button

View File

@ -23,10 +23,10 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new tab selector -- Create a new tab selector control element.
---@param args tabbar_args ---@param args tabbar_args
---@return graphics_element element, element_id id ---@return TabBar element, element_id id
local function tabbar(args) return function (args)
element.assert(type(args.tabs) == "table", "tabs is a required field") element.assert(type(args.tabs) == "table", "tabs is a required field")
element.assert(#args.tabs > 0, "at least one tab is required") element.assert(#args.tabs > 0, "at least one tab is required")
element.assert(type(args.callback) == "function", "callback is a required field") element.assert(type(args.callback) == "function", "callback is a required field")
@ -46,7 +46,7 @@ local function tabbar(args)
local button_width = math.max(max_width, args.min_width or 0) local button_width = math.max(max_width, args.min_width or 0)
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
element.assert(e.frame.w >= (button_width * #args.tabs), "width insufficent to display all tabs") element.assert(e.frame.w >= (button_width * #args.tabs), "width insufficent to display all tabs")
@ -120,10 +120,8 @@ local function tabbar(args)
e.redraw() e.redraw()
end end
-- initial draw ---@class TabBar:graphics_element
e.redraw() local TabBar, id = e.complete(true)
return e.complete() return TabBar, id
end end
return tabbar

View File

@ -27,10 +27,10 @@ local MOUSE_CLICK = core.events.MOUSE_CLICK
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new numeric entry field -- Create a new numeric entry field.
---@param args number_field_args ---@param args number_field_args
---@return graphics_element element, element_id id ---@return NumberField element, element_id id
local function number_field(args) return function (args)
element.assert(args.max_int_digits == nil or (util.is_int(args.max_int_digits) and args.max_int_digits > 0), "max_int_digits must be an integer greater than zero if supplied") element.assert(args.max_int_digits == nil or (util.is_int(args.max_int_digits) and args.max_int_digits > 0), "max_int_digits must be an integer greater than zero if supplied")
element.assert(args.max_frac_digits == nil or (util.is_int(args.max_frac_digits) and args.max_frac_digits > 0), "max_frac_digits must be an integer greater than zero if supplied") element.assert(args.max_frac_digits == nil or (util.is_int(args.max_frac_digits) and args.max_frac_digits > 0), "max_frac_digits must be an integer greater than zero if supplied")
@ -38,7 +38,7 @@ local function number_field(args)
args.can_focus = true args.can_focus = true
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
local has_decimal = false local has_decimal = false
@ -195,10 +195,8 @@ local function number_field(args)
e.on_disabled = ifield.show e.on_disabled = ifield.show
e.redraw = ifield.show e.redraw = ifield.show
-- initial draw ---@class NumberField:graphics_element
e.redraw() local NumberField, id = e.complete(true)
return e.complete() return NumberField, id
end end
return number_field

View File

@ -19,15 +19,15 @@ local MOUSE_CLICK = core.events.MOUSE_CLICK
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new text entry field -- Create a new text entry field.
---@param args text_field_args ---@param args text_field_args
---@return graphics_element element, element_id id, function censor_ctl ---@return TextField element, element_id id
local function text_field(args) return function (args)
args.height = 1 args.height = 1
args.can_focus = true args.can_focus = true
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
-- set initial value -- set initial value
e.value = args.value or "" e.value = args.value or ""
@ -95,11 +95,10 @@ local function text_field(args)
e.on_disabled = ifield.show e.on_disabled = ifield.show
e.redraw = ifield.show e.redraw = ifield.show
-- initial draw ---@class TextField:graphics_element
e.redraw() local TextField, id = e.complete(true)
local elem, id = e.complete() TextField.censor = ifield.censor
return elem, id, ifield.censor
return TextField, id
end end
return text_field

View File

@ -20,11 +20,11 @@ local flasher = require("graphics.flasher")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new alarm indicator light -- Create a new alarm indicator light element.
---@nodiscard ---@nodiscard
---@param args alarm_indicator_light ---@param args alarm_indicator_light
---@return graphics_element element, element_id id ---@return AlarmLight element, element_id id
local function alarm_indicator_light(args) return function (args)
element.assert(type(args.label) == "string", "label is a required field") element.assert(type(args.label) == "string", "label is a required field")
element.assert(type(args.c1) == "number", "c1 is a required field") element.assert(type(args.c1) == "number", "c1 is a required field")
element.assert(type(args.c2) == "number", "c2 is a required field") element.assert(type(args.c2) == "number", "c2 is a required field")
@ -49,7 +49,7 @@ local function alarm_indicator_light(args)
local c3 = colors.toBlit(args.c3) local c3 = colors.toBlit(args.c3)
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = 1 e.value = 1
@ -113,10 +113,8 @@ local function alarm_indicator_light(args)
e.w_write(args.label) e.w_write(args.label)
end end
-- initial draw ---@class AlarmLight:graphics_element
e.redraw() local AlarmLight, id = e.complete(true)
return e.complete() return AlarmLight, id
end end
return alarm_indicator_light

View File

@ -13,11 +13,11 @@ local element = require("graphics.element")
---@field x? integer 1 if omitted ---@field x? integer 1 if omitted
---@field y? integer auto incremented if omitted ---@field y? integer auto incremented if omitted
-- new core map box -- Create a new core map diagram indicator element.
---@nodiscard ---@nodiscard
---@param args core_map_args ---@param args core_map_args
---@return graphics_element element, element_id id ---@return CoreMap element, element_id id
local function core_map(args) return function (args)
element.assert(util.is_int(args.reactor_l), "reactor_l is a required field") element.assert(util.is_int(args.reactor_l), "reactor_l is a required field")
element.assert(util.is_int(args.reactor_w), "reactor_w is a required field") element.assert(util.is_int(args.reactor_w), "reactor_w is a required field")
@ -29,7 +29,7 @@ local function core_map(args)
args.fg_bg = core.cpair(args.parent.get_fg_bg().fgd, colors.gray) args.fg_bg = core.cpair(args.parent.get_fg_bg().fgd, colors.gray)
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = 0 e.value = 0
@ -165,10 +165,8 @@ local function core_map(args)
draw_core(e.value) draw_core(e.value)
end end
-- initial draw ---@class CoreMap:graphics_element
e.redraw() local CoreMap, id = e.complete(true)
return e.complete() return CoreMap, id
end end
return core_map

View File

@ -19,11 +19,11 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new data indicator -- Create new data indicator element.
---@nodiscard ---@nodiscard
---@param args data_indicator_args ---@param args data_indicator_args
---@return graphics_element element, element_id id ---@return DataIndicator element, element_id id
local function data(args) return function (args)
element.assert(type(args.label) == "string", "label is a required field") element.assert(type(args.label) == "string", "label is a required field")
element.assert(type(args.format) == "string", "format is a required field") element.assert(type(args.format) == "string", "format is a required field")
element.assert(args.value ~= nil, "value is a required field") element.assert(args.value ~= nil, "value is a required field")
@ -32,7 +32,7 @@ local function data(args)
args.height = 1 args.height = 1
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = args.value e.value = args.value
@ -94,10 +94,8 @@ local function data(args)
e.on_update(e.value) e.on_update(e.value)
end end
-- initial draw ---@class DataIndicator:graphics_element
e.redraw() local DataIndicator, id = e.complete(true)
return e.complete() return DataIndicator, id
end end
return data

View File

@ -17,13 +17,13 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new horizontal bar -- Create a new horizontal fill bar indicator element.
---@nodiscard ---@nodiscard
---@param args hbar_args ---@param args hbar_args
---@return graphics_element element, element_id id ---@return graphics_element element, element_id id
local function hbar(args) return function (args)
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = 0.0 e.value = 0.0
@ -119,10 +119,8 @@ local function hbar(args)
e.on_update(e.value) e.on_update(e.value)
end end
-- initial draw ---@class HorizontalBar:graphics_element
e.redraw() local HorizontalBar, id = e.complete(true)
return e.complete() return HorizontalBar, id
end end
return hbar

View File

@ -18,11 +18,11 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new icon indicator -- Create a new icon indicator element.
---@nodiscard ---@nodiscard
---@param args icon_indicator_args ---@param args icon_indicator_args
---@return graphics_element element, element_id id ---@return IconIndicator element, element_id id
local function icon(args) return function (args)
element.assert(type(args.label) == "string", "label is a required field") element.assert(type(args.label) == "string", "label is a required field")
element.assert(type(args.states) == "table", "states is a required field") element.assert(type(args.states) == "table", "states is a required field")
@ -30,7 +30,7 @@ local function icon(args)
args.width = math.max(args.min_label_width or 1, string.len(args.label)) + 4 args.width = math.max(args.min_label_width or 1, string.len(args.label)) + 4
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = args.value or 1 e.value = args.value or 1
if e.value == true then e.value = 2 end if e.value == true then e.value = 2 end
@ -71,10 +71,8 @@ local function icon(args)
e.on_update(e.value) e.on_update(e.value)
end end
-- initial draw ---@class IconIndicator:graphics_element
e.redraw() local IconIndicator, id = e.complete(true)
return e.complete() return IconIndicator, id
end end
return icon

View File

@ -18,11 +18,11 @@ local flasher = require("graphics.flasher")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new indicator light -- Create a new indicator light element.
---@nodiscard ---@nodiscard
---@param args indicator_light_args ---@param args indicator_light_args
---@return graphics_element element, element_id id ---@return IndicatorLight element, element_id id
local function indicator_light(args) return function (args)
element.assert(type(args.label) == "string", "label is a required field") element.assert(type(args.label) == "string", "label is a required field")
element.assert(type(args.colors) == "table", "colors is a required field") element.assert(type(args.colors) == "table", "colors is a required field")
@ -36,7 +36,7 @@ local function indicator_light(args)
local flash_on = true local flash_on = true
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = false e.value = false
@ -93,10 +93,8 @@ local function indicator_light(args)
e.w_write(args.label) e.w_write(args.label)
end end
-- initial draw ---@class IndicatorLight:graphics_element
e.redraw() local IndicatorLight, id = e.complete(true)
return e.complete() return IndicatorLight, id
end end
return indicator_light

View File

@ -18,11 +18,11 @@ local flasher = require("graphics.flasher")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new indicator LED -- Create a new indicator LED element.
---@nodiscard ---@nodiscard
---@param args indicator_led_args ---@param args indicator_led_args
---@return graphics_element element, element_id id ---@return LED element, element_id id
local function indicator_led(args) return function (args)
element.assert(type(args.label) == "string", "label is a required field") element.assert(type(args.label) == "string", "label is a required field")
element.assert(type(args.colors) == "table", "colors is a required field") element.assert(type(args.colors) == "table", "colors is a required field")
@ -36,7 +36,7 @@ local function indicator_led(args)
local flash_on = true local flash_on = true
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = false e.value = false
@ -95,10 +95,8 @@ local function indicator_led(args)
end end
end end
-- initial draw ---@class LED:graphics_element
e.redraw() local LED, id = e.complete(true)
return e.complete() return LED, id
end end
return indicator_led

View File

@ -20,11 +20,12 @@ local flasher = require("graphics.flasher")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new dual LED indicator light -- Create a new three-state LED indicator light. Two "active" states (colors c1 and c2) and an inactive state (off).<br>
-- Values: 1 = off, 2 = c1, 3 = c2
---@nodiscard ---@nodiscard
---@param args indicator_led_pair_args ---@param args indicator_led_pair_args
---@return graphics_element element, element_id id ---@return LEDPair element, element_id id
local function indicator_led_pair(args) return function (args)
element.assert(type(args.label) == "string", "label is a required field") element.assert(type(args.label) == "string", "label is a required field")
element.assert(type(args.off) == "number", "off is a required field") element.assert(type(args.off) == "number", "off is a required field")
element.assert(type(args.c1) == "number", "c1 is a required field") element.assert(type(args.c1) == "number", "c1 is a required field")
@ -44,7 +45,7 @@ local function indicator_led_pair(args)
local c2 = colors.toBlit(args.c2) local c2 = colors.toBlit(args.c2)
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = 1 e.value = 1
@ -104,10 +105,8 @@ local function indicator_led_pair(args)
end end
end end
-- initial draw ---@class LEDPair:graphics_element
e.redraw() local LEDPair, id = e.complete(true)
return e.complete() return LEDPair, id
end end
return indicator_led_pair

View File

@ -19,11 +19,11 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new power indicator -- Create a new power indicator. Variant of a data indicator with dynamic energy units.
---@nodiscard ---@nodiscard
---@param args power_indicator_args ---@param args power_indicator_args
---@return graphics_element element, element_id id ---@return PowerIndicator element, element_id id
local function power(args) return function (args)
element.assert(type(args.label) == "string", "label is a required field") element.assert(type(args.label) == "string", "label is a required field")
element.assert(type(args.unit) == "string", "unit is a required field") element.assert(type(args.unit) == "string", "unit is a required field")
element.assert(type(args.value) == "number", "value is a required field") element.assert(type(args.value) == "number", "value is a required field")
@ -32,7 +32,7 @@ local function power(args)
args.height = 1 args.height = 1
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = args.value e.value = args.value
@ -82,10 +82,8 @@ local function power(args)
e.on_update(e.value) e.on_update(e.value)
end end
-- initial draw ---@class PowerIndicator:graphics_element
e.redraw() local PowerIndicator, id = e.complete(true)
return e.complete() return PowerIndicator, id
end end
return power

View File

@ -13,11 +13,11 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new RGB LED indicator light -- Create a new RGB LED indicator light element.
---@nodiscard ---@nodiscard
---@param args indicator_led_rgb_args ---@param args indicator_led_rgb_args
---@return graphics_element element, element_id id ---@return RGBLED element, element_id id
local function indicator_led_rgb(args) return function (args)
element.assert(type(args.label) == "string", "label is a required field") element.assert(type(args.label) == "string", "label is a required field")
element.assert(type(args.colors) == "table", "colors is a required field") element.assert(type(args.colors) == "table", "colors is a required field")
@ -25,7 +25,7 @@ local function indicator_led_rgb(args)
args.width = math.max(args.min_label_width or 0, string.len(args.label)) + 2 args.width = math.max(args.min_label_width or 0, string.len(args.label)) + 2
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = 1 e.value = 1
@ -52,10 +52,8 @@ local function indicator_led_rgb(args)
end end
end end
-- initial draw ---@class RGBLED:graphics_element
e.redraw() local RGBLED, id = e.complete(true)
return e.complete() return RGBLED, id
end end
return indicator_led_rgb

View File

@ -19,11 +19,11 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new radiation indicator -- Create a new radiation indicator element. Variant of a data indicator using dynamic Sievert unit precision.
---@nodiscard ---@nodiscard
---@param args rad_indicator_args ---@param args rad_indicator_args
---@return graphics_element element, element_id id ---@return RadIndicator element, element_id id
local function rad(args) return function (args)
element.assert(type(args.label) == "string", "label is a required field") element.assert(type(args.label) == "string", "label is a required field")
element.assert(type(args.format) == "string", "format is a required field") element.assert(type(args.format) == "string", "format is a required field")
element.assert(util.is_int(args.width), "width is a required field") element.assert(util.is_int(args.width), "width is a required field")
@ -31,7 +31,7 @@ local function rad(args)
args.height = 1 args.height = 1
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = args.value or types.new_zero_radiation_reading() e.value = args.value or types.new_zero_radiation_reading()
@ -83,10 +83,8 @@ local function rad(args)
e.on_update(e.value) e.on_update(e.value)
end end
-- initial draw ---@class RadIndicator:graphics_element
e.redraw() local RadIndicator, id = e.complete(true)
return e.complete() return RadIndicator, id
end end
return rad

View File

@ -15,16 +15,16 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors (foreground is used for high signal quality) ---@field fg_bg? cpair foreground/background colors (foreground is used for high signal quality)
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new signal bar -- Create a new signal bar indicator element.
---@nodiscard ---@nodiscard
---@param args signal_bar_args ---@param args signal_bar_args
---@return graphics_element element, element_id id ---@return SignalBar element, element_id id
local function signal_bar(args) return function (args)
args.height = 1 args.height = 1
args.width = util.trinary(args.compact, 1, 2) args.width = util.trinary(args.compact, 1, 2)
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = 0 e.value = 0
@ -76,10 +76,8 @@ local function signal_bar(args)
end end
end end
-- initial draw ---@class SignalBar:graphics_element
e.redraw() local SignalBar, id = e.complete(true)
return e.complete() return SignalBar, id
end end
return signal_bar

View File

@ -20,11 +20,11 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new state indicator -- Create a new state indicator element.
---@nodiscard ---@nodiscard
---@param args state_indicator_args ---@param args state_indicator_args
---@return graphics_element element, element_id id ---@return StateIndicator element, element_id id
local function state_indicator(args) return function (args)
element.assert(type(args.states) == "table", "states is a required field") element.assert(type(args.states) == "table", "states is a required field")
if util.is_int(args.height) then if util.is_int(args.height) then
@ -52,7 +52,7 @@ local function state_indicator(args)
end end
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = args.value or 1 e.value = args.value or 1
@ -74,10 +74,8 @@ local function state_indicator(args)
---@param val integer indicator state ---@param val integer indicator state
function e.set_value(val) e.on_update(val) end function e.set_value(val) e.on_update(val) end
-- initial draw ---@class StateIndicator:graphics_element
e.redraw() local StateIndicator, id = e.complete(true)
return e.complete() return StateIndicator, id
end end
return state_indicator

View File

@ -20,11 +20,11 @@ local flasher = require("graphics.flasher")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new tri-state indicator light -- Create a new tri-state indicator light element.
---@nodiscard ---@nodiscard
---@param args tristate_indicator_light_args ---@param args tristate_indicator_light_args
---@return graphics_element element, element_id id ---@return TriIndicatorLight element, element_id id
local function tristate_indicator_light(args) return function (args)
element.assert(type(args.label) == "string", "label is a required field") element.assert(type(args.label) == "string", "label is a required field")
element.assert(type(args.c1) == "number", "c1 is a required field") element.assert(type(args.c1) == "number", "c1 is a required field")
element.assert(type(args.c2) == "number", "c2 is a required field") element.assert(type(args.c2) == "number", "c2 is a required field")
@ -38,7 +38,7 @@ local function tristate_indicator_light(args)
args.width = math.max(args.min_label_width or 1, string.len(args.label)) + 2 args.width = math.max(args.min_label_width or 1, string.len(args.label)) + 2
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = 1 e.value = 1
@ -102,10 +102,8 @@ local function tristate_indicator_light(args)
e.w_write(args.label) e.w_write(args.label)
end end
-- initial draw ---@class TriIndicatorLight:graphics_element
e.redraw() local TriIndicatorLight, id = e.complete(true)
return e.complete() return TriIndicatorLight, id
end end
return tristate_indicator_light

View File

@ -15,13 +15,13 @@ local element = require("graphics.element")
---@field fg_bg? cpair foreground/background colors ---@field fg_bg? cpair foreground/background colors
---@field hidden? boolean true to hide on initial draw ---@field hidden? boolean true to hide on initial draw
-- new vertical bar -- Create a new vertical fill bar indicator element.
---@nodiscard ---@nodiscard
---@param args vbar_args ---@param args vbar_args
---@return graphics_element element, element_id id ---@return VerticalBar element, element_id id
local function vbar(args) return function (args)
-- create new graphics element base object -- create new graphics element base object
local e = element.new(args) local e = element.new(args --[[@as graphics_args]])
e.value = 0.0 e.value = 0.0
@ -98,10 +98,8 @@ local function vbar(args)
e.redraw() e.redraw()
end end
-- initial draw ---@class VerticalBar:graphics_element
e.redraw() local VerticalBar, id = e.complete(true)
return e.complete() return VerticalBar, id
end end
return vbar

View File

@ -18,7 +18,7 @@ local PERIOD = {
flasher.PERIOD = PERIOD flasher.PERIOD = PERIOD
local active = false local active = false
local registry = { {}, {}, {} } -- one registry table per period local registry = { {}, {}, {} } ---@type [ function[], function[], function [] ] one registry table per period
local callback_counter = 0 local callback_counter = 0
-- blink registered indicators<br> -- blink registered indicators<br>

View File

@ -9,18 +9,18 @@ local util = require("scada-common.util")
local core = require("graphics.core") local core = require("graphics.core")
local themes = require("graphics.themes") local themes = require("graphics.themes")
local DisplayBox = require("graphics.elements.displaybox") local DisplayBox = require("graphics.elements.DisplayBox")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local ListBox = require("graphics.elements.listbox") local ListBox = require("graphics.elements.ListBox")
local MultiPane = require("graphics.elements.multipane") local MultiPane = require("graphics.elements.MultiPane")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local CheckBox = require("graphics.elements.controls.checkbox") local Checkbox = require("graphics.elements.controls.Checkbox")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local RadioButton = require("graphics.elements.controls.radio_button") local RadioButton = require("graphics.elements.controls.RadioButton")
local NumberField = require("graphics.elements.form.number_field") local NumberField = require("graphics.elements.form.NumberField")
local TextField = require("graphics.elements.form.text_field") local TextField = require("graphics.elements.form.TextField")
local println = util.println local println = util.println
local tri = util.trinary local tri = util.trinary
@ -58,8 +58,8 @@ local tool_ctl = {
viewing_config = false, viewing_config = false,
importing_legacy = false, importing_legacy = false,
view_cfg = nil, ---@type graphics_element view_cfg = nil, ---@type PushButton
settings_apply = nil, ---@type graphics_element settings_apply = nil, ---@type PushButton
set_networked = nil, ---@type function set_networked = nil, ---@type function
bundled_emcool = nil, ---@type function bundled_emcool = nil, ---@type function
@ -68,8 +68,8 @@ local tool_ctl = {
load_legacy = nil, ---@type function load_legacy = nil, ---@type function
show_auth_key = nil, ---@type function show_auth_key = nil, ---@type function
show_key_btn = nil, ---@type graphics_element show_key_btn = nil, ---@type PushButton
auth_key_textbox = nil, ---@type graphics_element auth_key_textbox = nil, ---@type TextBox
auth_key_value = "" auth_key_value = ""
} }
@ -122,7 +122,7 @@ local function load_settings(target, raw)
end end
-- create the config view -- create the config view
---@param display graphics_element ---@param display DisplayBox
local function config_view(display) local function config_view(display)
---@diagnostic disable-next-line: undefined-field ---@diagnostic disable-next-line: undefined-field
local function exit() os.queueEvent("terminate") end local function exit() os.queueEvent("terminate") end
@ -282,14 +282,14 @@ local function config_view(display)
TextBox{parent=net_c_4,x=1,y=6,height=6,text="This enables verifying that messages are authentic, so it is intended for security on multiplayer servers.",fg_bg=g_lg_fg_bg} TextBox{parent=net_c_4,x=1,y=6,height=6,text="This enables verifying that messages are authentic, so it is intended for security on multiplayer servers.",fg_bg=g_lg_fg_bg}
TextBox{parent=net_c_4,x=1,y=12,text="Facility Auth Key"} TextBox{parent=net_c_4,x=1,y=12,text="Facility Auth Key"}
local key, _, censor = TextField{parent=net_c_4,x=1,y=13,max_len=64,value=ini_cfg.AuthKey,width=24,height=1,fg_bg=bw_fg_bg} local key, _ = TextField{parent=net_c_4,x=1,y=13,max_len=64,value=ini_cfg.AuthKey,width=24,height=1,fg_bg=bw_fg_bg}
local function censor_key(enable) censor(util.trinary(enable, "*", nil)) end local function censor_key(enable) key.censor(util.trinary(enable, "*", nil)) end
-- declare back first so tabbing makes sense visually -- declare back first so tabbing makes sense visually
PushButton{parent=net_c_4,x=1,y=15,text="\x1b Back",callback=function()net_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg} PushButton{parent=net_c_4,x=1,y=15,text="\x1b Back",callback=function()net_pane.set_value(3)end,fg_bg=nav_fg_bg,active_fg_bg=btn_act_fg_bg}
local hide_key = CheckBox{parent=net_c_4,x=8,y=15,label="Hide Key",box_fg_bg=cpair(colors.lightBlue,colors.black),callback=censor_key} local hide_key = Checkbox{parent=net_c_4,x=8,y=15,label="Hide Key",box_fg_bg=cpair(colors.lightBlue,colors.black),callback=censor_key}
hide_key.set_value(true) hide_key.set_value(true)
censor_key(true) censor_key(true)
@ -323,7 +323,7 @@ local function config_view(display)
TextBox{parent=log_c_1,x=1,y=7,text="Log File Path"} TextBox{parent=log_c_1,x=1,y=7,text="Log File Path"}
local path = TextField{parent=log_c_1,x=1,y=8,width=24,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg} local path = TextField{parent=log_c_1,x=1,y=8,width=24,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
local en_dbg = CheckBox{parent=log_c_1,x=1,y=10,default=ini_cfg.LogDebug,label="Enable Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)} local en_dbg = Checkbox{parent=log_c_1,x=1,y=10,default=ini_cfg.LogDebug,label="Enable Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
TextBox{parent=log_c_1,x=3,y=11,height=4,text="This results in much larger log files. Use only as needed.",fg_bg=g_lg_fg_bg} TextBox{parent=log_c_1,x=3,y=11,height=4,text="This results in much larger log files. Use only as needed.",fg_bg=g_lg_fg_bg}
local path_err = TextBox{parent=log_c_1,x=1,y=14,width=24,text="Provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true} local path_err = TextBox{parent=log_c_1,x=1,y=14,width=24,text="Provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}

View File

@ -39,15 +39,6 @@ local io = {
ps = psil.create() ps = psil.create()
} }
-- luacheck: no unused args
-- placeholder acknowledge function for type hinting
---@param success boolean
---@diagnostic disable-next-line: unused-local
local function __generic_ack(success) end
-- luacheck: unused args
local config = nil ---@type pkt_config local config = nil ---@type pkt_config
local comms = nil ---@type pocket_comms local comms = nil ---@type pocket_comms
@ -92,10 +83,10 @@ function iocontrol.init_core(pkt_comms, nav, cfg)
get_tone_states = function () comms.diag__get_alarm_tones() end, get_tone_states = function () comms.diag__get_alarm_tones() end,
ready_warn = nil, ---@type graphics_element ready_warn = nil, ---@type TextBox
tone_buttons = {}, tone_buttons = {}, ---@type SwitchButton[]
alarm_buttons = {}, alarm_buttons = {}, ---@type Checkbox[]
tone_indicators = {} -- indicators to update from supervisor tone states tone_indicators = {} ---@type IndicatorLight[] indicators to update from supervisor tone states
} }
-- API access -- API access
@ -166,24 +157,21 @@ function iocontrol.init_fac(conf)
radiation = types.new_zero_radiation_reading(), radiation = types.new_zero_radiation_reading(),
start_ack = __generic_ack, start_ack = nil, ---@type fun(success: boolean)
stop_ack = __generic_ack, stop_ack = nil, ---@type fun(success: boolean)
scram_ack = __generic_ack, scram_ack = nil, ---@type fun(success: boolean)
ack_alarms_ack = __generic_ack, ack_alarms_ack = nil, ---@type fun(success: boolean)
ps = psil.create(), ps = psil.create(),
induction_ps_tbl = {}, induction_ps_tbl = {}, ---@type psil[]
induction_data_tbl = {}, induction_data_tbl = {}, ---@type imatrix_session_db[]
sps_ps_tbl = {}, sps_ps_tbl = {}, ---@type psil[]
sps_data_tbl = {}, sps_data_tbl = {}, ---@type sps_session_db[]
tank_ps_tbl = {}, tank_ps_tbl = {}, ---@type psil[]
tank_data_tbl = {}, tank_data_tbl = {} ---@type dynamicv_session_db[]
env_d_ps = psil.create(),
env_d_data = {}
} }
-- create induction and SPS tables (currently only 1 of each is supported) -- create induction and SPS tables (currently only 1 of each is supported)
@ -192,107 +180,14 @@ function iocontrol.init_fac(conf)
table.insert(io.facility.sps_ps_tbl, psil.create()) table.insert(io.facility.sps_ps_tbl, psil.create())
table.insert(io.facility.sps_data_tbl, {}) table.insert(io.facility.sps_data_tbl, {})
-- determine tank information
if io.facility.tank_mode == 0 then
io.facility.tank_defs = {}
-- on facility tank mode 0, setup tank defs to match unit tank option
for i = 1, conf.num_units do
io.facility.tank_defs[i] = util.trinary(conf.cooling.r_cool[i].TankConnection, 1, 0)
end
io.facility.tank_list = { table.unpack(io.facility.tank_defs) }
else
-- decode the layout of tanks from the connections definitions
local tank_mode = io.facility.tank_mode
local tank_defs = io.facility.tank_defs
local tank_list = { table.unpack(tank_defs) }
local function calc_fdef(start_idx, end_idx)
local first = 4
for i = start_idx, end_idx do
if io.facility.tank_defs[i] == 2 then
if i < first then first = i end
end
end
return first
end
if tank_mode == 1 then
-- (1) 1 total facility tank (A A A A)
local first_fdef = calc_fdef(1, #tank_defs)
for i = 1, #tank_defs do
if i > first_fdef and tank_defs[i] == 2 then
tank_list[i] = 0
end
end
elseif tank_mode == 2 then
-- (2) 2 total facility tanks (A A A B)
local first_fdef = calc_fdef(1, math.min(3, #tank_defs))
for i = 1, #tank_defs do
if (i ~= 4) and (i > first_fdef) and (tank_defs[i] == 2) then
tank_list[i] = 0
end
end
elseif tank_mode == 3 then
-- (3) 2 total facility tanks (A A B B)
for _, a in pairs({ 1, 3 }) do
local b = a + 1
if (tank_defs[a] == 2) and (tank_defs[b] == 2) then
tank_list[b] = 0
end
end
elseif tank_mode == 4 then
-- (4) 2 total facility tanks (A B B B)
local first_fdef = calc_fdef(2, #tank_defs)
for i = 1, #tank_defs do
if (i ~= 1) and (i > first_fdef) and (tank_defs[i] == 2) then
tank_list[i] = 0
end
end
elseif tank_mode == 5 then
-- (5) 3 total facility tanks (A A B C)
local first_fdef = calc_fdef(1, math.min(2, #tank_defs))
for i = 1, #tank_defs do
if (not (i == 3 or i == 4)) and (i > first_fdef) and (tank_defs[i] == 2) then
tank_list[i] = 0
end
end
elseif tank_mode == 6 then
-- (6) 3 total facility tanks (A B B C)
local first_fdef = calc_fdef(2, math.min(3, #tank_defs))
for i = 1, #tank_defs do
if (not (i == 1 or i == 4)) and (i > first_fdef) and (tank_defs[i] == 2) then
tank_list[i] = 0
end
end
elseif tank_mode == 7 then
-- (7) 3 total facility tanks (A B C C)
local first_fdef = calc_fdef(3, #tank_defs)
for i = 1, #tank_defs do
if (not (i == 1 or i == 2)) and (i > first_fdef) and (tank_defs[i] == 2) then
tank_list[i] = 0
end
end
end
io.facility.tank_list = tank_list
end
-- create facility tank tables
for i = 1, #io.facility.tank_list do
if io.facility.tank_list[i] == 2 then
table.insert(io.facility.tank_ps_tbl, psil.create())
table.insert(io.facility.tank_data_tbl, {})
end
end
-- create unit data structures -- create unit data structures
io.units = {} io.units = {} ---@type pioctl_unit[]
for i = 1, conf.num_units do for i = 1, conf.num_units do
---@class pioctl_unit ---@class pioctl_unit
local entry = { local entry = {
unit_id = i, unit_id = i,
connected = false, connected = false,
---@type { boilers: { connected: boolean, faulted: boolean }[], turbines: { connected: boolean, faulted: boolean }[] }
rtu_hw = {}, rtu_hw = {},
num_boilers = 0, num_boilers = 0,
@ -323,12 +218,12 @@ function iocontrol.init_fac(conf)
ack_alarms = function () process.ack_all_alarms(i) end, ack_alarms = function () process.ack_all_alarms(i) end,
set_burn = function (rate) process.set_rate(i, rate) end, ---@param rate number burn rate set_burn = function (rate) process.set_rate(i, rate) end, ---@param rate number burn rate
start_ack = __generic_ack, start_ack = nil, ---@type fun(success: boolean)
scram_ack = __generic_ack, scram_ack = nil, ---@type fun(success: boolean)
reset_rps_ack = __generic_ack, reset_rps_ack = nil, ---@type fun(success: boolean)
ack_alarms_ack = __generic_ack, ack_alarms_ack = nil, ---@type fun(success: boolean)
---@type alarms ---@type { [ALARM]: ALARM_STATE }
alarms = { ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE }, alarms = { ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE, ALARM_STATE.INACTIVE },
annunciator = {}, ---@type annunciator annunciator = {}, ---@type annunciator
@ -336,14 +231,14 @@ function iocontrol.init_fac(conf)
unit_ps = psil.create(), unit_ps = psil.create(),
reactor_data = {}, ---@type reactor_db reactor_data = {}, ---@type reactor_db
boiler_ps_tbl = {}, boiler_ps_tbl = {}, ---@type psil[]
boiler_data_tbl = {}, boiler_data_tbl = {}, ---@type boilerv_session_db[]
turbine_ps_tbl = {}, turbine_ps_tbl = {}, ---@type psil[]
turbine_data_tbl = {}, turbine_data_tbl = {}, ---@type turbinev_session_db[]
tank_ps_tbl = {}, tank_ps_tbl = {}, ---@type psil[]
tank_data_tbl = {} tank_data_tbl = {} ---@type dynamicv_session_db[]
} }
-- on other facility modes, overwrite unit TANK option with facility tank defs -- on other facility modes, overwrite unit TANK option with facility tank defs
@ -485,7 +380,7 @@ end
-- update unit status data from API_GET_UNIT -- update unit status data from API_GET_UNIT
---@param data table ---@param data table
function iocontrol.record_unit_data(data) function iocontrol.record_unit_data(data)
local unit = io.units[data[1]] ---@type pioctl_unit local unit = io.units[data[1]]
unit.connected = data[2] unit.connected = data[2]
unit.rtu_hw = data[3] unit.rtu_hw = data[3]
@ -650,8 +545,8 @@ function iocontrol.record_unit_data(data)
unit.boiler_data_tbl = data[8] unit.boiler_data_tbl = data[8]
for id = 1, #unit.boiler_data_tbl do for id = 1, #unit.boiler_data_tbl do
local boiler = unit.boiler_data_tbl[id] ---@type boilerv_session_db local boiler = unit.boiler_data_tbl[id]
local ps = unit.boiler_ps_tbl[id] ---@type psil local ps = unit.boiler_ps_tbl[id]
local boiler_status = 1 local boiler_status = 1
local computed_status = 1 local computed_status = 1
@ -683,8 +578,8 @@ function iocontrol.record_unit_data(data)
unit.turbine_data_tbl = data[9] unit.turbine_data_tbl = data[9]
for id = 1, #unit.turbine_data_tbl do for id = 1, #unit.turbine_data_tbl do
local turbine = unit.turbine_data_tbl[id] ---@type turbinev_session_db local turbine = unit.turbine_data_tbl[id]
local ps = unit.turbine_ps_tbl[id] ---@type psil local ps = unit.turbine_ps_tbl[id]
local turbine_status = 1 local turbine_status = 1
local computed_status = 1 local computed_status = 1

View File

@ -100,22 +100,22 @@ pocket.APP_ID = APP_ID
---@class nav_tree_page ---@class nav_tree_page
---@field _p nav_tree_page|nil page's parent ---@field _p nav_tree_page|nil page's parent
---@field _c table page's children ---@field _c nav_tree_page[] page's children
---@field nav_to function function to navigate to this page ---@field nav_to function function to navigate to this page
---@field switcher function|nil function to switch between children ---@field switcher function|nil function to switch between children
---@field tasks table tasks to run while viewing this page ---@field tasks function[] tasks to run while viewing this page
-- initialize the page navigation system -- initialize the page navigation system
---@param smem pkt_shared_memory ---@param smem pkt_shared_memory
function pocket.init_nav(smem) function pocket.init_nav(smem)
local self = { local self = {
pane = nil, ---@type graphics_element pane = nil, ---@type AppMultiPane|MultiPane|nil
sidebar = nil, ---@type graphics_element sidebar = nil, ---@type Sidebar|nil
apps = {}, apps = {}, ---@type pocket_app[]
containers = {}, containers = {}, ---@type Container[]
help_map = {}, help_map = {}, ---@type { [string]: function }
help_return = nil, help_return = nil, ---@type POCKET_APP_ID|nil
loader_return = nil, loader_return = nil, ---@type POCKET_APP_ID|nil
cur_app = APP_ID.ROOT cur_app = APP_ID.ROOT
} }
@ -125,17 +125,17 @@ function pocket.init_nav(smem)
local nav = {} local nav = {}
-- 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 MultiPane
function nav.set_pane(root_pane) self.pane = root_pane end function nav.set_pane(root_pane) self.pane = root_pane end
-- link sidebar element -- link sidebar element
---@param sidebar graphics_element ---@param sidebar Sidebar
function nav.set_sidebar(sidebar) self.sidebar = sidebar 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 Container 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? AppMultiPane|MultiPane multipane if this is a simple paned app, then nav_to must be a number
---@param require_sv? boolean true to specifiy if this app should be unloaded when the supervisor connection is lost ---@param require_sv? boolean true to specifiy if this app should be unloaded when the supervisor connection is lost
---@param require_api? boolean true to specifiy if this app should be unloaded when the api connection is lost ---@param require_api? boolean true 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) function nav.register_app(app_id, container, pane, require_sv, require_api)
@ -144,8 +144,8 @@ function pocket.init_nav(smem)
loaded = false, loaded = false,
cur_page = nil, ---@type nav_tree_page cur_page = nil, ---@type nav_tree_page
pane = pane, pane = pane,
paned_pages = {}, paned_pages = {}, ---@type nav_tree_page[]
sidebar_items = {} sidebar_items = {} ---@type sidebar_entry[]
} }
app.load = function () app.loaded = true end app.load = function () app.loaded = true end
@ -159,13 +159,13 @@ function pocket.init_nav(smem)
function app.requires_conn() return require_sv or require_api or false end function app.requires_conn() return require_sv or 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 AppMultiPane|MultiPane multipane
function app.set_root_pane(root_pane) function app.set_root_pane(root_pane)
app.pane = root_pane app.pane = root_pane
end end
-- configure the sidebar -- configure the sidebar
---@param items table ---@param items sidebar_entry[]
function app.set_sidebar(items) function app.set_sidebar(items)
app.sidebar_items = items app.sidebar_items = items
if self.sidebar then self.sidebar.update(items) end if self.sidebar then self.sidebar.update(items) end
@ -263,7 +263,7 @@ function pocket.init_nav(smem)
-- reset help return on navigating out of an app -- reset help return on navigating out of an app
if app_id == APP_ID.ROOT then self.help_return = nil end if app_id == APP_ID.ROOT then self.help_return = nil end
local app = self.apps[app_id] ---@type pocket_app local app = self.apps[app_id]
if app then if app then
if app.requires_conn() and not smem.pkt_sys.pocket_comms.is_linked() then if app.requires_conn() and not smem.pkt_sys.pocket_comms.is_linked() then
-- bring up the app loader -- bring up the app loader
@ -339,7 +339,7 @@ function pocket.init_nav(smem)
return return
end end
local app = self.apps[self.cur_app] ---@type pocket_app local app = self.apps[self.cur_app]
log.debug("attempting app nav up for app " .. self.cur_app) log.debug("attempting app nav up for app " .. self.cur_app)
if not app.nav_up() then if not app.nav_up() then
@ -359,6 +359,7 @@ function pocket.init_nav(smem)
end end
-- link the help map from the guide app -- link the help map from the guide app
---@param map { [string]: function }
function nav.link_help(map) self.help_map = map end function nav.link_help(map) self.help_map = map end
return nav return nav

View File

@ -8,7 +8,7 @@ local style = require("pocket.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local flasher = require("graphics.flasher") local flasher = require("graphics.flasher")
local DisplayBox = require("graphics.elements.displaybox") local DisplayBox = require("graphics.elements.DisplayBox")
---@class pocket_renderer ---@class pocket_renderer
local renderer = {} local renderer = {}

View File

@ -20,7 +20,7 @@ local pocket = require("pocket.pocket")
local renderer = require("pocket.renderer") local renderer = require("pocket.renderer")
local threads = require("pocket.threads") local threads = require("pocket.threads")
local POCKET_VERSION = "v0.12.1-alpha" local POCKET_VERSION = "v0.12.2-alpha"
local println = util.println local println = util.println
local println_ts = util.println_ts local println_ts = util.println_ts

View File

@ -13,19 +13,19 @@ local style = require("pocket.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local MultiPane = require("graphics.elements.multipane") local MultiPane = require("graphics.elements.MultiPane")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local WaitingAnim = require("graphics.elements.animations.waiting") local WaitingAnim = require("graphics.elements.animations.Waiting")
local HazardButton = require("graphics.elements.controls.hazard_button") local HazardButton = require("graphics.elements.controls.HazardButton")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local NumberField = require("graphics.elements.form.number_field") local NumberField = require("graphics.elements.form.NumberField")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local IconIndicator = require("graphics.elements.indicators.icon") local IconIndicator = require("graphics.elements.indicators.IconIndicator")
local AUTO_GROUP = types.AUTO_GROUP local AUTO_GROUP = types.AUTO_GROUP
@ -42,7 +42,7 @@ local hzd_fg_bg = cpair(colors.white, colors.gray)
local dis_colors = cpair(colors.white, colors.lightGray) local dis_colors = cpair(colors.white, colors.lightGray)
-- new unit control page view -- new unit control page view
---@param root graphics_element parent ---@param root Container parent
local function new_view(root) local function new_view(root)
local db = iocontrol.get_db() local db = iocontrol.get_db()
@ -63,7 +63,7 @@ local function new_view(root)
local btn_fg_bg = cpair(colors.green, colors.black) local btn_fg_bg = cpair(colors.green, colors.black)
local btn_active = cpair(colors.white, colors.black) local btn_active = cpair(colors.white, colors.black)
local page_div = nil ---@type nil|graphics_element local page_div = nil ---@type Div|nil
-- set sidebar to display unit-specific fields based on a specified unit -- set sidebar to display unit-specific fields based on a specified unit
local function set_sidebar() local function set_sidebar()
@ -83,7 +83,7 @@ local function new_view(root)
local function load() local function load()
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 = {} ---@type Div[]
local active_unit = 1 local active_unit = 1
@ -108,7 +108,7 @@ local function new_view(root)
for i = 1, db.facility.num_units do for i = 1, db.facility.num_units do
local u_pane = panes[i] local u_pane = panes[i]
local u_div = Div{parent=u_pane,x=2,width=main.get_width()-2} local u_div = Div{parent=u_pane,x=2,width=main.get_width()-2}
local unit = db.units[i] ---@type pioctl_unit local unit = db.units[i]
local u_ps = unit.unit_ps local u_ps = unit.unit_ps
-- refresh data callback, every 500ms it will re-send the query -- refresh data callback, every 500ms it will re-send the query

View File

@ -7,14 +7,14 @@ local pocket = require("pocket.pocket")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local IndicatorLight = require("graphics.elements.indicators.light") local IndicatorLight = require("graphics.elements.indicators.IndicatorLight")
local Checkbox = require("graphics.elements.controls.checkbox") local Checkbox = require("graphics.elements.controls.Checkbox")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local SwitchButton = require("graphics.elements.controls.switch_button") local SwitchButton = require("graphics.elements.controls.SwitchButton")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
local cpair = core.cpair local cpair = core.cpair
@ -22,7 +22,7 @@ local cpair = core.cpair
local APP_ID = pocket.APP_ID local APP_ID = pocket.APP_ID
-- create diagnostic app pages -- create diagnostic app pages
---@param root graphics_element parent ---@param root Container parent
local function create_pages(root) local function create_pages(root)
local db = iocontrol.get_db() local db = iocontrol.get_db()

View File

@ -7,13 +7,13 @@ local pocket = require("pocket.pocket")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local APP_ID = pocket.APP_ID local APP_ID = pocket.APP_ID
-- create placeholder app page -- create placeholder app page
---@param root graphics_element parent ---@param root Container parent
local function create_pages(root) local function create_pages(root)
local db = iocontrol.get_db() local db = iocontrol.get_db()

View File

@ -15,16 +15,16 @@ local guide_section = require("pocket.ui.pages.guide_section")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local ListBox = require("graphics.elements.listbox") local ListBox = require("graphics.elements.ListBox")
local MultiPane = require("graphics.elements.multipane") local MultiPane = require("graphics.elements.MultiPane")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local WaitingAnim = require("graphics.elements.animations.waiting") local WaitingAnim = require("graphics.elements.animations.Waiting")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local TextField = require("graphics.elements.form.text_field") local TextField = require("graphics.elements.form.TextField")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
local cpair = core.cpair local cpair = core.cpair
@ -36,7 +36,7 @@ local APP_ID = pocket.APP_ID
-- local text_fg = style.text_fg -- local text_fg = style.text_fg
-- new system guide view -- new system guide view
---@param root graphics_element parent ---@param root Container parent
local function new_view(root) local function new_view(root)
local db = iocontrol.get_db() local db = iocontrol.get_db()
@ -58,7 +58,7 @@ local function new_view(root)
app.set_sidebar({{ label = " # ", tall = true, color = core.cpair(colors.black, colors.green), callback = function () db.nav.open_app(APP_ID.ROOT) end }}) 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 local page_div = nil ---@type Div|nil
-- load the app (create the elements) -- load the app (create the elements)
local function load() local function load()
@ -88,12 +88,11 @@ local function new_view(root)
local fps = Div{parent=page_div,x=2,width=p_width} local fps = Div{parent=page_div,x=2,width=p_width}
local gls = Div{parent=page_div,x=2,width=p_width} local gls = Div{parent=page_div,x=2,width=p_width}
local lnk = Div{parent=page_div,x=2,width=p_width} local lnk = Div{parent=page_div,x=2,width=p_width}
local panes = { home, search, use, uis, fps, gls, lnk } local panes = { home, search, use, uis, fps, gls, lnk } ---@type Div[]
local doc_map = {} local doc_map = {} ---@type { [string]: function }
local search_db = {} local search_db = {} ---@type [ string, string, string, function ][]
---@class _guide_section_constructor_data
local sect_construct_data = { app, page_div, panes, doc_map, search_db, btn_fg_bg, btn_active } local sect_construct_data = { app, page_div, panes, doc_map, search_db, btn_fg_bg, btn_active }
TextBox{parent=home,y=1,text="cc-mek-scada Guide",alignment=ALIGN.CENTER} TextBox{parent=home,y=1,text="cc-mek-scada Guide",alignment=ALIGN.CENTER}
@ -117,7 +116,7 @@ local function new_view(root)
function func_ref.run_search() function func_ref.run_search()
local query = string.lower(query_field.get_value()) local query = string.lower(query_field.get_value())
local s_results = { {}, {}, {}, {} } local s_results = { {}, {}, {}, {} } ---@type [ string, string, string, function ][][]
search_results.remove_all() search_results.remove_all()

View File

@ -9,16 +9,16 @@ local conn_waiting = require("pocket.ui.components.conn_waiting")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local MultiPane = require("graphics.elements.multipane") local MultiPane = require("graphics.elements.MultiPane")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local APP_ID = pocket.APP_ID local APP_ID = pocket.APP_ID
local LINK_STATE = iocontrol.LINK_STATE local LINK_STATE = iocontrol.LINK_STATE
-- create the connecting to SV & API page -- create the connecting to SV & API page
---@param root graphics_element parent ---@param root Container parent
local function create_pages(root) local function create_pages(root)
local db = iocontrol.get_db() local db = iocontrol.get_db()

View File

@ -12,12 +12,12 @@ local pocket = require("pocket.pocket")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local ListBox = require("graphics.elements.listbox") local ListBox = require("graphics.elements.ListBox")
local MultiPane = require("graphics.elements.multipane") local MultiPane = require("graphics.elements.MultiPane")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
local cpair = core.cpair local cpair = core.cpair
@ -25,7 +25,7 @@ local cpair = core.cpair
local APP_ID = pocket.APP_ID local APP_ID = pocket.APP_ID
-- create system app pages -- create system app pages
---@param root graphics_element parent ---@param root Container parent
local function create_pages(root) local function create_pages(root)
local db = iocontrol.get_db() local db = iocontrol.get_db()

View File

@ -15,17 +15,17 @@ local turbine = require("pocket.ui.pages.unit_turbine")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local ListBox = require("graphics.elements.listbox") local ListBox = require("graphics.elements.ListBox")
local MultiPane = require("graphics.elements.multipane") local MultiPane = require("graphics.elements.MultiPane")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local WaitingAnim = require("graphics.elements.animations.waiting") local WaitingAnim = require("graphics.elements.animations.Waiting")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local IconIndicator = require("graphics.elements.indicators.icon") local IconIndicator = require("graphics.elements.indicators.IconIndicator")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
local cpair = core.cpair local cpair = core.cpair
@ -47,7 +47,7 @@ local emc_ind_s = {
} }
-- new unit page view -- new unit page view
---@param root graphics_element parent ---@param root Container parent
local function new_view(root) local function new_view(root)
local db = iocontrol.get_db() local db = iocontrol.get_db()
@ -69,11 +69,11 @@ local function new_view(root)
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 local page_div = nil ---@type Div|nil
-- set sidebar to display unit-specific fields based on a specified unit -- 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]
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 },
@ -99,7 +99,7 @@ local function new_view(root)
local function load() local function load()
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 = {} ---@type Div[]
local active_unit = 1 local active_unit = 1
@ -127,7 +127,7 @@ local function new_view(root)
for i = 1, db.facility.num_units do for i = 1, db.facility.num_units do
local u_pane = panes[i] local u_pane = panes[i]
local u_div = Div{parent=u_pane,x=2,width=main.get_width()-2} local u_div = Div{parent=u_pane,x=2,width=main.get_width()-2}
local unit = db.units[i] ---@type pioctl_unit local unit = db.units[i]
local u_ps = unit.unit_ps local u_ps = unit.unit_ps
-- refresh data callback, every 500ms it will re-send the query -- refresh data callback, every 500ms it will re-send the query

View File

@ -8,17 +8,17 @@ local style = require("pocket.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local WaitingAnim = require("graphics.elements.animations.waiting") local WaitingAnim = require("graphics.elements.animations.Waiting")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
local cpair = core.cpair local cpair = core.cpair
-- create a waiting view -- create a waiting view
---@param parent graphics_element parent ---@param parent Container parent
---@param y integer y offset ---@param y integer y offset
local function init(parent, y, is_api) local function init(parent, y, is_api)
-- root div -- root div

View File

@ -21,16 +21,16 @@ local style = require("pocket.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local MultiPane = require("graphics.elements.multipane") local MultiPane = require("graphics.elements.MultiPane")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local WaitingAnim = require("graphics.elements.animations.waiting") local WaitingAnim = require("graphics.elements.animations.Waiting")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local Sidebar = require("graphics.elements.controls.sidebar") local Sidebar = require("graphics.elements.controls.Sidebar")
local SignalBar = require("graphics.elements.indicators.signal") local SignalBar = require("graphics.elements.indicators.SignalBar")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
local cpair = core.cpair local cpair = core.cpair
@ -38,7 +38,7 @@ local cpair = core.cpair
local APP_ID = pocket.APP_ID local APP_ID = pocket.APP_ID
-- create new main view -- create new main view
---@param main graphics_element main displaybox ---@param main DisplayBox main displaybox
local function init(main) local function init(main)
local db = iocontrol.get_db() local db = iocontrol.get_db()

View File

@ -5,14 +5,14 @@ local docs = require("pocket.ui.docs")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local ListBox = require("graphics.elements.listbox") local ListBox = require("graphics.elements.ListBox")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local IndicatorLight = require("graphics.elements.indicators.light") local IndicatorLight = require("graphics.elements.indicators.IndicatorLight")
local LED = require("graphics.elements.indicators.led") local LED = require("graphics.elements.indicators.LED")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
local cpair = core.cpair local cpair = core.cpair
@ -21,14 +21,14 @@ local DOC_TYPE = docs.DOC_ITEM_TYPE
local LIST_TYPE = docs.DOC_LIST_TYPE local LIST_TYPE = docs.DOC_LIST_TYPE
-- new guide documentation section -- new guide documentation section
---@param data _guide_section_constructor_data ---@param data { [1]: pocket_app, [2]: Div, [3]: Div[], [4]: { [string]: function }, [5]: [ string, string, string, function ][], [6]: cpair, [7]: cpair }
---@param base_page nav_tree_page ---@param base_page nav_tree_page
---@param title string ---@param title string
---@param items table ---@param items table
---@param scroll_height integer ---@param scroll_height integer
---@return nav_tree_page ---@return nav_tree_page
return function (data, base_page, title, items, scroll_height) return function (data, base_page, title, items, scroll_height)
local app, page_div, panes, doc_map, search_db, btn_fg_bg, btn_active = table.unpack(data) local app, page_div, panes, doc_map, search_db, btn_fg_bg, btn_active = data[1], data[2], data[3], data[4], data[5], data[6], data[7]
local section_page = app.new_page(base_page, #panes + 1) local section_page = app.new_page(base_page, #panes + 1)
local section_div = Div{parent=page_div,x=2} local section_div = Div{parent=page_div,x=2}

View File

@ -7,11 +7,11 @@ local pocket = require("pocket.pocket")
local core = require("graphics.core") local core = require("graphics.core")
local AppMultiPane = require("graphics.elements.appmultipane") local AppMultiPane = require("graphics.elements.AppMultiPane")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local App = require("graphics.elements.controls.app") local App = require("graphics.elements.controls.App")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
local cpair = core.cpair local cpair = core.cpair
@ -19,7 +19,7 @@ local cpair = core.cpair
local APP_ID = pocket.APP_ID local APP_ID = pocket.APP_ID
-- new home page view -- new home page view
---@param root graphics_element parent ---@param root Container parent
local function new_view(root) local function new_view(root)
local db = iocontrol.get_db() local db = iocontrol.get_db()

View File

@ -7,15 +7,15 @@ local style = require("pocket.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local StateIndicator = require("graphics.elements.indicators.state") local StateIndicator = require("graphics.elements.indicators.StateIndicator")
local IconIndicator = require("graphics.elements.indicators.icon") local IconIndicator = require("graphics.elements.indicators.IconIndicator")
local VerticalBar = require("graphics.elements.indicators.vbar") local VerticalBar = require("graphics.elements.indicators.VerticalBar")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
local cpair = core.cpair local cpair = core.cpair
@ -29,8 +29,8 @@ local yel_ind_s = style.icon_states.yel_ind_s
-- create a boiler view in the unit app -- create a boiler view in the unit app
---@param app pocket_app ---@param app pocket_app
---@param u_page nav_tree_page ---@param u_page nav_tree_page
---@param panes table ---@param panes Div[]
---@param blr_pane graphics_element ---@param blr_pane Div
---@param b_id integer boiler ID ---@param b_id integer boiler ID
---@param ps psil ---@param ps psil
---@param update function ---@param update function

View File

@ -7,15 +7,15 @@ local style = require("pocket.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local StateIndicator = require("graphics.elements.indicators.state") local StateIndicator = require("graphics.elements.indicators.StateIndicator")
local IconIndicator = require("graphics.elements.indicators.icon") local IconIndicator = require("graphics.elements.indicators.IconIndicator")
local VerticalBar = require("graphics.elements.indicators.vbar") local VerticalBar = require("graphics.elements.indicators.VerticalBar")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
local cpair = core.cpair local cpair = core.cpair
@ -29,8 +29,8 @@ local yel_ind_s = style.icon_states.yel_ind_s
-- create a reactor view in the unit app -- create a reactor view in the unit app
---@param app pocket_app ---@param app pocket_app
---@param u_page nav_tree_page ---@param u_page nav_tree_page
---@param panes table ---@param panes Div[]
---@param page_div graphics_element ---@param page_div Div
---@param u_ps psil ---@param u_ps psil
---@param update function ---@param update function
return function (app, u_page, panes, page_div, u_ps, update) return function (app, u_page, panes, page_div, u_ps, update)

View File

@ -6,16 +6,16 @@ local style = require("pocket.ui.style")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local IconIndicator = require("graphics.elements.indicators.icon") local IconIndicator = require("graphics.elements.indicators.IconIndicator")
local PowerIndicator = require("graphics.elements.indicators.power") local PowerIndicator = require("graphics.elements.indicators.PowerIndicator")
local StateIndicator = require("graphics.elements.indicators.state") local StateIndicator = require("graphics.elements.indicators.StateIndicator")
local VerticalBar = require("graphics.elements.indicators.vbar") local VerticalBar = require("graphics.elements.indicators.VerticalBar")
local ALIGN = core.ALIGN local ALIGN = core.ALIGN
local cpair = core.cpair local cpair = core.cpair
@ -30,8 +30,8 @@ local yel_ind_s = style.icon_states.yel_ind_s
-- create a turbine view in the unit app -- create a turbine view in the unit app
---@param app pocket_app ---@param app pocket_app
---@param u_page nav_tree_page ---@param u_page nav_tree_page
---@param panes table ---@param panes Div[]
---@param tbn_pane graphics_element ---@param tbn_pane Div
---@param u_id integer unit ID ---@param u_id integer unit ID
---@param t_id integer turbine ID ---@param t_id integer turbine ID
---@param ps psil ---@param ps psil

View File

@ -8,11 +8,11 @@ local plc = require("reactor-plc.plc")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local ListBox = require("graphics.elements.listbox") local ListBox = require("graphics.elements.ListBox")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local tri = util.trinary local tri = util.trinary
@ -33,8 +33,8 @@ local self = {
settings = nil, ---@type plc_config settings = nil, ---@type plc_config
run_test_btn = nil, ---@type graphics_element run_test_btn = nil, ---@type PushButton
sc_log = nil, ---@type graphics_element sc_log = nil, ---@type ListBox
self_check_msg = nil ---@type function self_check_msg = nil ---@type function
} }
@ -160,7 +160,7 @@ local function self_check()
end end
-- exit self check back home -- exit self check back home
---@param main_pane graphics_element ---@param main_pane MultiPane
local function exit_self_check(main_pane) local function exit_self_check(main_pane)
tcd.abort(handle_timeout) tcd.abort(handle_timeout)
self.net_listen = false self.net_listen = false
@ -172,10 +172,10 @@ end
local check = {} local check = {}
-- create the self-check view -- create the self-check view
---@param main_pane graphics_element ---@param main_pane MultiPane
---@param settings_cfg plc_config ---@param settings_cfg plc_config
---@param check_sys graphics_element ---@param check_sys Div
---@param style table ---@param style { [string]: cpair }
function check.create(main_pane, settings_cfg, check_sys, style) function check.create(main_pane, settings_cfg, check_sys, style)
local bw_fg_bg = style.bw_fg_bg local bw_fg_bg = style.bw_fg_bg
local g_lg_fg_bg = style.g_lg_fg_bg local g_lg_fg_bg = style.g_lg_fg_bg

View File

@ -5,20 +5,20 @@ local util = require("scada-common.util")
local core = require("graphics.core") local core = require("graphics.core")
local themes = require("graphics.themes") local themes = require("graphics.themes")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local ListBox = require("graphics.elements.listbox") local ListBox = require("graphics.elements.ListBox")
local MultiPane = require("graphics.elements.multipane") local MultiPane = require("graphics.elements.MultiPane")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local CheckBox = require("graphics.elements.controls.checkbox") local Checkbox = require("graphics.elements.controls.Checkbox")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local Radio2D = require("graphics.elements.controls.radio_2d") local Radio2D = require("graphics.elements.controls.Radio2D")
local RadioButton = require("graphics.elements.controls.radio_button") local RadioButton = require("graphics.elements.controls.RadioButton")
local NumberField = require("graphics.elements.form.number_field") local NumberField = require("graphics.elements.form.NumberField")
local TextField = require("graphics.elements.form.text_field") local TextField = require("graphics.elements.form.TextField")
local IndLight = require("graphics.elements.indicators.light") local IndLight = require("graphics.elements.indicators.IndicatorLight")
local cpair = core.cpair local cpair = core.cpair
@ -31,8 +31,8 @@ local self = {
bundled_emcool = nil, ---@type function bundled_emcool = nil, ---@type function
show_auth_key = nil, ---@type function show_auth_key = nil, ---@type function
show_key_btn = nil, ---@type graphics_element show_key_btn = nil, ---@type PushButton
auth_key_textbox = nil, ---@type graphics_element auth_key_textbox = nil, ---@type TextBox
auth_key_value = "" auth_key_value = ""
} }
@ -61,17 +61,14 @@ local system = {}
-- create the system configuration view -- create the system configuration view
---@param tool_ctl _plc_cfg_tool_ctl ---@param tool_ctl _plc_cfg_tool_ctl
---@param main_pane graphics_element ---@param main_pane MultiPane
---@param cfg_sys table ---@param cfg_sys [ plc_config, plc_config, plc_config, table, function ]
---@param divs table ---@param divs Div[]
---@param style table ---@param style { [string]: cpair }
---@param exit function ---@param exit function
function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit) function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
---@type plc_config, plc_config, plc_config, table, function local settings_cfg, ini_cfg, tmp_cfg, fields, load_settings = cfg_sys[1], cfg_sys[2], cfg_sys[3], cfg_sys[4], cfg_sys[5]
local settings_cfg, ini_cfg, tmp_cfg, fields, load_settings = table.unpack(cfg_sys) local plc_cfg, net_cfg, log_cfg, clr_cfg, summary = divs[1], divs[2], divs[3], divs[4], divs[5]
---@type graphics_element, graphics_element, graphics_element, graphics_element, graphics_element
local plc_cfg, net_cfg, log_cfg, clr_cfg, summary = table.unpack(divs)
local bw_fg_bg = style.bw_fg_bg local bw_fg_bg = style.bw_fg_bg
local g_lg_fg_bg = style.g_lg_fg_bg local g_lg_fg_bg = style.g_lg_fg_bg
@ -93,7 +90,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
TextBox{parent=plc_c_1,x=1,y=1,text="Would you like to set this PLC as networked?"} TextBox{parent=plc_c_1,x=1,y=1,text="Would you like to set this PLC as networked?"}
TextBox{parent=plc_c_1,x=1,y=3,height=4,text="If you have a supervisor, select the box. You will later be prompted to select the network configuration. If you instead want to use this as a standalone safety system, don't select the box.",fg_bg=g_lg_fg_bg} TextBox{parent=plc_c_1,x=1,y=3,height=4,text="If you have a supervisor, select the box. You will later be prompted to select the network configuration. If you instead want to use this as a standalone safety system, don't select the box.",fg_bg=g_lg_fg_bg}
local networked = CheckBox{parent=plc_c_1,x=1,y=8,label="Networked",default=ini_cfg.Networked,box_fg_bg=cpair(colors.orange,colors.black)} local networked = Checkbox{parent=plc_c_1,x=1,y=8,label="Networked",default=ini_cfg.Networked,box_fg_bg=cpair(colors.orange,colors.black)}
local function submit_networked() local function submit_networked()
self.set_networked(networked.get_value()) self.set_networked(networked.get_value())
@ -131,7 +128,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
TextBox{parent=plc_c_3,x=1,y=1,height=4,text="When networked, the supervisor takes care of emergency coolant via RTUs. However, you can configure independent emergency coolant via the PLC."} TextBox{parent=plc_c_3,x=1,y=1,height=4,text="When networked, the supervisor takes care of emergency coolant via RTUs. However, you can configure independent emergency coolant via the PLC."}
TextBox{parent=plc_c_3,x=1,y=6,height=5,text="This independent control can be used with or without a supervisor. To configure, you would next select the interface of the redstone output connected to one or more mekanism pipes.",fg_bg=g_lg_fg_bg} TextBox{parent=plc_c_3,x=1,y=6,height=5,text="This independent control can be used with or without a supervisor. To configure, you would next select the interface of the redstone output connected to one or more mekanism pipes.",fg_bg=g_lg_fg_bg}
local en_em_cool = CheckBox{parent=plc_c_3,x=1,y=11,label="Enable PLC Emergency Coolant Control",default=ini_cfg.EmerCoolEnable,box_fg_bg=cpair(colors.orange,colors.black)} local en_em_cool = Checkbox{parent=plc_c_3,x=1,y=11,label="Enable PLC Emergency Coolant Control",default=ini_cfg.EmerCoolEnable,box_fg_bg=cpair(colors.orange,colors.black)}
local function next_from_plc() local function next_from_plc()
if tmp_cfg.Networked then main_pane.set_value(3) else main_pane.set_value(4) end if tmp_cfg.Networked then main_pane.set_value(3) else main_pane.set_value(4) end
@ -149,7 +146,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
local side = Radio2D{parent=plc_c_4,x=1,y=2,rows=2,columns=3,default=side_to_idx(ini_cfg.EmerCoolSide),options=side_options,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.orange} local side = Radio2D{parent=plc_c_4,x=1,y=2,rows=2,columns=3,default=side_to_idx(ini_cfg.EmerCoolSide),options=side_options,radio_colors=cpair(colors.lightGray,colors.black),select_color=colors.orange}
TextBox{parent=plc_c_4,x=1,y=5,text="Bundled Redstone Configuration"} TextBox{parent=plc_c_4,x=1,y=5,text="Bundled Redstone Configuration"}
local bundled = CheckBox{parent=plc_c_4,x=1,y=6,label="Is Bundled?",default=ini_cfg.EmerCoolColor~=nil,box_fg_bg=cpair(colors.orange,colors.black),callback=function(v)self.bundled_emcool(v)end} local bundled = Checkbox{parent=plc_c_4,x=1,y=6,label="Is Bundled?",default=ini_cfg.EmerCoolColor~=nil,box_fg_bg=cpair(colors.orange,colors.black),callback=function(v)self.bundled_emcool(v)end}
local color = Radio2D{parent=plc_c_4,x=1,y=8,rows=4,columns=4,default=color_to_idx(ini_cfg.EmerCoolColor),options=color_options,radio_colors=cpair(colors.lightGray,colors.black),color_map=color_options_map,disable_color=colors.gray,disable_fg_bg=g_lg_fg_bg} local color = Radio2D{parent=plc_c_4,x=1,y=8,rows=4,columns=4,default=color_to_idx(ini_cfg.EmerCoolColor),options=color_options,radio_colors=cpair(colors.lightGray,colors.black),color_map=color_options_map,disable_color=colors.gray,disable_fg_bg=g_lg_fg_bg}
if ini_cfg.EmerCoolColor == nil then color.disable() end if ini_cfg.EmerCoolColor == nil then color.disable() end
@ -243,11 +240,11 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
TextBox{parent=net_c_3,x=1,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for security on multiplayer servers. All devices on the same network MUST use the same key if any device has a key. This does result in some extra compution (can slow things down).",fg_bg=g_lg_fg_bg} TextBox{parent=net_c_3,x=1,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for security on multiplayer servers. All devices on the same network MUST use the same key if any device has a key. This does result in some extra compution (can slow things down).",fg_bg=g_lg_fg_bg}
TextBox{parent=net_c_3,x=1,y=11,text="Facility Auth Key"} TextBox{parent=net_c_3,x=1,y=11,text="Facility Auth Key"}
local key, _, censor = TextField{parent=net_c_3,x=1,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg} local key, _ = TextField{parent=net_c_3,x=1,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg}
local function censor_key(enable) censor(util.trinary(enable, "*", nil)) end local function censor_key(enable) key.censor(util.trinary(enable, "*", nil)) end
local hide_key = CheckBox{parent=net_c_3,x=34,y=12,label="Hide",box_fg_bg=cpair(colors.lightBlue,colors.black),callback=censor_key} local hide_key = Checkbox{parent=net_c_3,x=34,y=12,label="Hide",box_fg_bg=cpair(colors.lightBlue,colors.black),callback=censor_key}
hide_key.set_value(true) hide_key.set_value(true)
censor_key(true) censor_key(true)
@ -282,7 +279,7 @@ function system.create(tool_ctl, main_pane, cfg_sys, divs, style, exit)
TextBox{parent=log_c_1,x=1,y=7,text="Log File Path"} TextBox{parent=log_c_1,x=1,y=7,text="Log File Path"}
local path = TextField{parent=log_c_1,x=1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg} local path = TextField{parent=log_c_1,x=1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
local en_dbg = CheckBox{parent=log_c_1,x=1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)} local en_dbg = Checkbox{parent=log_c_1,x=1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
TextBox{parent=log_c_1,x=3,y=11,height=2,text="This results in much larger log files. It is best to only use this when there is a problem.",fg_bg=g_lg_fg_bg} TextBox{parent=log_c_1,x=3,y=11,height=2,text="This results in much larger log files. It is best to only use this when there is a problem.",fg_bg=g_lg_fg_bg}
local path_err = TextBox{parent=log_c_1,x=8,y=14,width=35,text="Please provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true} local path_err = TextBox{parent=log_c_1,x=8,y=14,width=35,text="Please provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}

View File

@ -12,13 +12,13 @@ local system = require("reactor-plc.config.system")
local core = require("graphics.core") local core = require("graphics.core")
local themes = require("graphics.themes") local themes = require("graphics.themes")
local DisplayBox = require("graphics.elements.displaybox") local DisplayBox = require("graphics.elements.DisplayBox")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local ListBox = require("graphics.elements.listbox") local ListBox = require("graphics.elements.ListBox")
local MultiPane = require("graphics.elements.multipane") local MultiPane = require("graphics.elements.MultiPane")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local println = util.println local println = util.println
local tri = util.trinary local tri = util.trinary
@ -58,11 +58,11 @@ local tool_ctl = {
viewing_config = false, viewing_config = false,
jumped_to_color = false, jumped_to_color = false,
view_cfg = nil, ---@type graphics_element view_cfg = nil, ---@type PushButton
color_cfg = nil, ---@type graphics_element color_cfg = nil, ---@type PushButton
color_next = nil, ---@type graphics_element color_next = nil, ---@type PushButton
color_apply = nil, ---@type graphics_element color_apply = nil, ---@type PushButton
settings_apply = nil, ---@type graphics_element settings_apply = nil, ---@type PushButton
gen_summary = nil, ---@type function gen_summary = nil, ---@type function
load_legacy = nil, ---@type function load_legacy = nil, ---@type function
@ -125,7 +125,7 @@ local function load_settings(target, raw)
end end
-- create the config view -- create the config view
---@param display graphics_element ---@param display DisplayBox
local function config_view(display) local function config_view(display)
local bw_fg_bg = style.bw_fg_bg local bw_fg_bg = style.bw_fg_bg
local g_lg_fg_bg = style.g_lg_fg_bg local g_lg_fg_bg = style.g_lg_fg_bg

View File

@ -77,7 +77,7 @@ end
-- transmit RPS data across the bus -- transmit RPS data across the bus
---@param tripped boolean RPS tripped ---@param tripped boolean RPS tripped
---@param status table RPS status ---@param status boolean[] RPS status
---@param emer_cool_active boolean RPS activated the emergency coolant ---@param emer_cool_active boolean RPS activated the emergency coolant
function databus.tx_rps(tripped, status, emer_cool_active) function databus.tx_rps(tripped, status, emer_cool_active)
databus.ps.publish("rps_scram", tripped) databus.ps.publish("rps_scram", tripped)

View File

@ -13,15 +13,15 @@ local style = require("reactor-plc.panel.style")
local core = require("graphics.core") local core = require("graphics.core")
local flasher = require("graphics.flasher") local flasher = require("graphics.flasher")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local Rectangle = require("graphics.elements.rectangle") local Rectangle = require("graphics.elements.Rectangle")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local LED = require("graphics.elements.indicators.led") local LED = require("graphics.elements.indicators.LED")
local LEDPair = require("graphics.elements.indicators.ledpair") local LEDPair = require("graphics.elements.indicators.LEDPair")
local RGBLED = require("graphics.elements.indicators.ledrgb") local RGBLED = require("graphics.elements.indicators.RGBLED")
local LINK_STATE = types.PANEL_LINK_STATE local LINK_STATE = types.PANEL_LINK_STATE
@ -34,7 +34,7 @@ local ind_grn = style.ind_grn
local ind_red = style.ind_red local ind_red = style.ind_red
-- create new front panel view -- create new front panel view
---@param panel graphics_element main displaybox ---@param panel DisplayBox main displaybox
local function init(panel) local function init(panel)
local s_hi_box = style.theme.highlight_box local s_hi_box = style.theme.highlight_box

View File

@ -110,22 +110,8 @@ end
---@param reactor table ---@param reactor table
---@param is_formed boolean ---@param is_formed boolean
function plc.rps_init(reactor, is_formed) function plc.rps_init(reactor, is_formed)
local state_keys = {
high_dmg = 1,
high_temp = 2,
low_coolant = 3,
ex_waste = 4,
ex_hcoolant = 5,
no_fuel = 6,
fault = 7,
timeout = 8,
manual = 9,
automatic = 10,
sys_fail = 11,
force_disabled = 12
}
local self = { local self = {
---@type boolean[] check states
state = { false, false, false, false, false, false, false, false, false, false, false, false }, state = { false, false, false, false, false, false, false, false, false, false, false, false },
reactor_enabled = false, reactor_enabled = false,
enabled_at = 0, enabled_at = 0,
@ -136,12 +122,27 @@ function plc.rps_init(reactor, is_formed)
trip_cause = "ok" ---@type rps_trip_cause trip_cause = "ok" ---@type rps_trip_cause
} }
local CHK = {
HIGH_DMG = 1,
HIGH_TEMP = 2,
LOW_COOLANT = 3,
EX_WASTE = 4,
EX_HCOOLANT = 5,
NO_FUEL = 6,
FAULT = 7,
TIMEOUT = 8,
MANUAL = 9,
AUTOMATIC = 10,
SYS_FAIL = 11,
FORCE_DISABLED = 12
}
-- PRIVATE FUNCTIONS -- -- PRIVATE FUNCTIONS --
-- set reactor access fault flag -- set reactor access fault flag
local function _set_fault() local function _set_fault()
if reactor.__p_last_fault() ~= "Terminated" then if reactor.__p_last_fault() ~= "Terminated" then
self.state[state_keys.fault] = true self.state[CHK.FAULT] = true
end end
end end
@ -203,8 +204,8 @@ function plc.rps_init(reactor, is_formed)
end end
-- always update, since some ppm failures constitute not being formed -- always update, since some ppm failures constitute not being formed
if not self.state[state_keys.sys_fail] then if not self.state[CHK.SYS_FAIL] then
self.state[state_keys.sys_fail] = not self.formed self.state[CHK.SYS_FAIL] = not self.formed
end end
end end
@ -214,8 +215,8 @@ function plc.rps_init(reactor, is_formed)
if _check_and_handle_ppm_call(disabled) then if _check_and_handle_ppm_call(disabled) then
self.force_disabled = disabled self.force_disabled = disabled
if not self.state[state_keys.force_disabled] then if not self.state[CHK.FORCE_DISABLED] then
self.state[state_keys.force_disabled] = disabled self.state[CHK.FORCE_DISABLED] = disabled
end end
end end
end end
@ -223,8 +224,8 @@ function plc.rps_init(reactor, is_formed)
-- check for high damage -- check for high damage
local function _high_damage() local function _high_damage()
local damage_percent = reactor.getDamagePercent() local damage_percent = reactor.getDamagePercent()
if _check_and_handle_ppm_call(damage_percent) and not self.state[state_keys.high_dmg] then if _check_and_handle_ppm_call(damage_percent) and not self.state[CHK.HIGH_DMG] then
self.state[state_keys.high_dmg] = damage_percent >= RPS_LIMITS.MAX_DAMAGE_PERCENT self.state[CHK.HIGH_DMG] = damage_percent >= RPS_LIMITS.MAX_DAMAGE_PERCENT
end end
end end
@ -232,40 +233,40 @@ function plc.rps_init(reactor, is_formed)
local function _high_temp() local function _high_temp()
-- mekanism: MAX_DAMAGE_TEMPERATURE = 1200K -- mekanism: MAX_DAMAGE_TEMPERATURE = 1200K
local temp = reactor.getTemperature() local temp = reactor.getTemperature()
if _check_and_handle_ppm_call(temp) and not self.state[state_keys.high_temp] then if _check_and_handle_ppm_call(temp) and not self.state[CHK.HIGH_TEMP] then
self.state[state_keys.high_temp] = temp >= RPS_LIMITS.MAX_DAMAGE_TEMPERATURE self.state[CHK.HIGH_TEMP] = temp >= RPS_LIMITS.MAX_DAMAGE_TEMPERATURE
end end
end end
-- check if there is very low coolant -- check if there is very low coolant
local function _low_coolant() local function _low_coolant()
local coolant_filled = reactor.getCoolantFilledPercentage() local coolant_filled = reactor.getCoolantFilledPercentage()
if _check_and_handle_ppm_call(coolant_filled) and not self.state[state_keys.low_coolant] then if _check_and_handle_ppm_call(coolant_filled) and not self.state[CHK.LOW_COOLANT] then
self.state[state_keys.low_coolant] = coolant_filled < RPS_LIMITS.MIN_COOLANT_FILL self.state[CHK.LOW_COOLANT] = coolant_filled < RPS_LIMITS.MIN_COOLANT_FILL
end end
end end
-- check for excess waste (>80% filled) -- check for excess waste (>80% filled)
local function _excess_waste() local function _excess_waste()
local w_filled = reactor.getWasteFilledPercentage() local w_filled = reactor.getWasteFilledPercentage()
if _check_and_handle_ppm_call(w_filled) and not self.state[state_keys.ex_waste] then if _check_and_handle_ppm_call(w_filled) and not self.state[CHK.EX_WASTE] then
self.state[state_keys.ex_waste] = w_filled > RPS_LIMITS.MAX_WASTE_FILL self.state[CHK.EX_WASTE] = w_filled > RPS_LIMITS.MAX_WASTE_FILL
end end
end end
-- check for heated coolant backup (>95% filled) -- check for heated coolant backup (>95% filled)
local function _excess_heated_coolant() local function _excess_heated_coolant()
local hc_filled = reactor.getHeatedCoolantFilledPercentage() local hc_filled = reactor.getHeatedCoolantFilledPercentage()
if _check_and_handle_ppm_call(hc_filled) and not self.state[state_keys.ex_hcoolant] then if _check_and_handle_ppm_call(hc_filled) and not self.state[CHK.EX_HCOOLANT] then
self.state[state_keys.ex_hcoolant] = hc_filled > RPS_LIMITS.MAX_HEATED_COLLANT_FILL self.state[CHK.EX_HCOOLANT] = hc_filled > RPS_LIMITS.MAX_HEATED_COLLANT_FILL
end end
end end
-- check if there is no fuel -- check if there is no fuel
local function _insufficient_fuel() local function _insufficient_fuel()
local fuel = reactor.getFuelFilledPercentage() local fuel = reactor.getFuelFilledPercentage()
if _check_and_handle_ppm_call(fuel) and not self.state[state_keys.no_fuel] then if _check_and_handle_ppm_call(fuel) and not self.state[CHK.NO_FUEL] then
self.state[state_keys.no_fuel] = fuel <= RPS_LIMITS.NO_FUEL_FILL self.state[CHK.NO_FUEL] = fuel <= RPS_LIMITS.NO_FUEL_FILL
end end
end end
@ -287,23 +288,23 @@ function plc.rps_init(reactor, is_formed)
-- trip for a PLC comms timeout -- trip for a PLC comms timeout
function public.trip_timeout() function public.trip_timeout()
self.state[state_keys.timeout] = true self.state[CHK.TIMEOUT] = true
end end
-- manually SCRAM the reactor -- manually SCRAM the reactor
function public.trip_manual() function public.trip_manual()
self.state[state_keys.manual] = true self.state[CHK.MANUAL] = true
end end
-- automatic SCRAM commanded by supervisor -- automatic SCRAM commanded by supervisor
function public.trip_auto() function public.trip_auto()
self.state[state_keys.automatic] = true self.state[CHK.AUTOMATIC] = true
end end
-- trip for unformed reactor -- trip for unformed reactor
function public.trip_sys_fail() function public.trip_sys_fail()
self.state[state_keys.fault] = true self.state[CHK.FAULT] = true
self.state[state_keys.sys_fail] = true self.state[CHK.SYS_FAIL] = true
end end
-- SCRAM the reactor now<br> -- SCRAM the reactor now<br>
@ -350,7 +351,7 @@ function plc.rps_init(reactor, is_formed)
function public.auto_activate() function public.auto_activate()
-- clear automatic SCRAM if it was the cause -- clear automatic SCRAM if it was the cause
if self.tripped and self.trip_cause == "automatic" then if self.tripped and self.trip_cause == "automatic" then
self.state[state_keys.automatic] = true self.state[CHK.AUTOMATIC] = true
self.trip_cause = RPS_TRIP_CAUSE.OK self.trip_cause = RPS_TRIP_CAUSE.OK
self.tripped = false self.tripped = false
@ -388,40 +389,40 @@ function plc.rps_init(reactor, is_formed)
-- check system states in order of severity -- check system states in order of severity
if self.tripped then if self.tripped then
status = self.trip_cause status = self.trip_cause
elseif self.state[state_keys.sys_fail] then elseif self.state[CHK.SYS_FAIL] then
log.warning("RPS: system failure, reactor not formed") log.warning("RPS: system failure, reactor not formed")
status = RPS_TRIP_CAUSE.SYS_FAIL status = RPS_TRIP_CAUSE.SYS_FAIL
elseif self.state[state_keys.force_disabled] then elseif self.state[CHK.FORCE_DISABLED] then
log.warning("RPS: reactor was force disabled") log.warning("RPS: reactor was force disabled")
status = RPS_TRIP_CAUSE.FORCE_DISABLED status = RPS_TRIP_CAUSE.FORCE_DISABLED
elseif self.state[state_keys.high_dmg] then elseif self.state[CHK.HIGH_DMG] then
log.warning("RPS: high damage") log.warning("RPS: high damage")
status = RPS_TRIP_CAUSE.HIGH_DMG status = RPS_TRIP_CAUSE.HIGH_DMG
elseif self.state[state_keys.high_temp] then elseif self.state[CHK.HIGH_TEMP] then
log.warning("RPS: high temperature") log.warning("RPS: high temperature")
status = RPS_TRIP_CAUSE.HIGH_TEMP status = RPS_TRIP_CAUSE.HIGH_TEMP
elseif self.state[state_keys.low_coolant] then elseif self.state[CHK.LOW_COOLANT] then
log.warning("RPS: low coolant") log.warning("RPS: low coolant")
status = RPS_TRIP_CAUSE.LOW_COOLANT status = RPS_TRIP_CAUSE.LOW_COOLANT
elseif self.state[state_keys.ex_waste] then elseif self.state[CHK.EX_WASTE] then
log.warning("RPS: full waste") log.warning("RPS: full waste")
status = RPS_TRIP_CAUSE.EX_WASTE status = RPS_TRIP_CAUSE.EX_WASTE
elseif self.state[state_keys.ex_hcoolant] then elseif self.state[CHK.EX_HCOOLANT] then
log.warning("RPS: heated coolant backup") log.warning("RPS: heated coolant backup")
status = RPS_TRIP_CAUSE.EX_HCOOLANT status = RPS_TRIP_CAUSE.EX_HCOOLANT
elseif self.state[state_keys.no_fuel] then elseif self.state[CHK.NO_FUEL] then
log.warning("RPS: no fuel") log.warning("RPS: no fuel")
status = RPS_TRIP_CAUSE.NO_FUEL status = RPS_TRIP_CAUSE.NO_FUEL
elseif self.state[state_keys.fault] then elseif self.state[CHK.FAULT] then
log.warning("RPS: reactor access fault") log.warning("RPS: reactor access fault")
status = RPS_TRIP_CAUSE.FAULT status = RPS_TRIP_CAUSE.FAULT
elseif self.state[state_keys.timeout] then elseif self.state[CHK.TIMEOUT] then
log.warning("RPS: supervisor connection timeout") log.warning("RPS: supervisor connection timeout")
status = RPS_TRIP_CAUSE.TIMEOUT status = RPS_TRIP_CAUSE.TIMEOUT
elseif self.state[state_keys.manual] then elseif self.state[CHK.MANUAL] then
log.warning("RPS: manual SCRAM requested") log.warning("RPS: manual SCRAM requested")
status = RPS_TRIP_CAUSE.MANUAL status = RPS_TRIP_CAUSE.MANUAL
elseif self.state[state_keys.automatic] then elseif self.state[CHK.AUTOMATIC] then
log.warning("RPS: automatic SCRAM requested") log.warning("RPS: automatic SCRAM requested")
status = RPS_TRIP_CAUSE.AUTOMATIC status = RPS_TRIP_CAUSE.AUTOMATIC
else else
@ -449,7 +450,7 @@ function plc.rps_init(reactor, is_formed)
end end
-- update emergency coolant control if configured -- update emergency coolant control if configured
_set_emer_cool(self.state[state_keys.low_coolant]) _set_emer_cool(self.state[CHK.LOW_COOLANT])
-- report RPS status -- report RPS status
databus.tx_rps(self.tripped, self.state, self.emer_cool_active) databus.tx_rps(self.tripped, self.state, self.emer_cool_active)
@ -465,7 +466,7 @@ function plc.rps_init(reactor, is_formed)
---@nodiscard ---@nodiscard
function public.get_trip_cause() return self.trip_cause end function public.get_trip_cause() return self.trip_cause end
---@nodiscard ---@nodiscard
function public.is_low_coolant() return self.states[state_keys.low_coolant] end function public.is_low_coolant() return self.states[CHK.LOW_COOLANT] end
---@nodiscard ---@nodiscard
function public.is_active() return self.reactor_enabled end function public.is_active() return self.reactor_enabled end
@ -495,16 +496,16 @@ function plc.rps_init(reactor, is_formed)
self.tripped = false self.tripped = false
self.trip_cause = RPS_TRIP_CAUSE.OK self.trip_cause = RPS_TRIP_CAUSE.OK
self.state[state_keys.fault] = false self.state[CHK.FAULT] = false
self.state[state_keys.sys_fail] = false self.state[CHK.SYS_FAIL] = false
log.info("RPS: partial reset on formed") log.info("RPS: partial reset on formed")
end end
-- reset the automatic and timeout trip flags, then clear trip if that was the trip cause -- reset the automatic and timeout trip flags, then clear trip if that was the trip cause
function public.auto_reset() function public.auto_reset()
self.state[state_keys.automatic] = false self.state[CHK.AUTOMATIC] = false
self.state[state_keys.timeout] = false self.state[CHK.TIMEOUT] = false
if self.trip_cause == RPS_TRIP_CAUSE.AUTOMATIC or self.trip_cause == RPS_TRIP_CAUSE.TIMEOUT then if self.trip_cause == RPS_TRIP_CAUSE.AUTOMATIC or self.trip_cause == RPS_TRIP_CAUSE.TIMEOUT then
self.trip_cause = RPS_TRIP_CAUSE.OK self.trip_cause = RPS_TRIP_CAUSE.OK

View File

@ -8,7 +8,7 @@ local style = require("reactor-plc.panel.style")
local core = require("graphics.core") local core = require("graphics.core")
local flasher = require("graphics.flasher") local flasher = require("graphics.flasher")
local DisplayBox = require("graphics.elements.displaybox") local DisplayBox = require("graphics.elements.DisplayBox")
---@class reactor_plc_renderer ---@class reactor_plc_renderer
local renderer = {} local renderer = {}

View File

@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc")
local renderer = require("reactor-plc.renderer") local renderer = require("reactor-plc.renderer")
local threads = require("reactor-plc.threads") local threads = require("reactor-plc.threads")
local R_PLC_VERSION = "v1.8.8" local R_PLC_VERSION = "v1.8.9"
local println = util.println local println = util.println
local println_ts = util.println_ts local println_ts = util.println_ts

View File

@ -144,6 +144,7 @@ function threads.thread__main(smem, init)
plc_state.no_reactor = true plc_state.no_reactor = true
plc_state.degraded = true plc_state.degraded = true
elseif networked and type == "modem" then elseif networked and type == "modem" then
---@cast device Modem
-- we only care if this is our wireless modem -- we only care if this is our wireless modem
-- note, check init_ok first since nic will be nil if it is false -- note, check init_ok first since nic will be nil if it is false
if plc_state.init_ok and nic.is_modem(device) then if plc_state.init_ok and nic.is_modem(device) then
@ -208,6 +209,7 @@ function threads.thread__main(smem, init)
rps.reset_formed() rps.reset_formed()
end end
elseif networked and type == "modem" then elseif networked and type == "modem" then
---@cast device Modem
-- note, check init_ok first since nic will be nil if it is false -- note, check init_ok first since nic will be nil if it is false
if device.isWireless() and not (plc_state.init_ok and nic.is_connected()) then if device.isWireless() and not (plc_state.init_ok and nic.is_connected()) then
-- reconnected modem -- reconnected modem
@ -628,9 +630,10 @@ function threads.thread__setpoint_control(smem)
local reactor = plc_dev.reactor local reactor = plc_dev.reactor
if plc_state.init_ok and (not plc_state.no_reactor) then if plc_state.init_ok and (not plc_state.no_reactor) then
---@cast reactor table won't be nil
-- check if we should start ramping -- check if we should start ramping
if setpoints.burn_rate_en and (setpoints.burn_rate ~= last_burn_sp) then if setpoints.burn_rate_en and (setpoints.burn_rate ~= last_burn_sp) then
---@diagnostic disable-next-line: need-check-nil
local cur_burn_rate = reactor.getBurnRate() local cur_burn_rate = reactor.getBurnRate()
if (type(cur_burn_rate) == "number") and (setpoints.burn_rate ~= cur_burn_rate) and rps.is_active() then if (type(cur_burn_rate) == "number") and (setpoints.burn_rate ~= cur_burn_rate) and rps.is_active() then
@ -644,7 +647,6 @@ function threads.thread__setpoint_control(smem)
log.debug(util.c("SPCTL: starting burn rate ramp from ", cur_burn_rate, " mB/t to ", setpoints.burn_rate, " mB/t")) log.debug(util.c("SPCTL: starting burn rate ramp from ", cur_burn_rate, " mB/t to ", setpoints.burn_rate, " mB/t"))
else else
log.debug(util.c("SPCTL: setting burn rate directly to ", setpoints.burn_rate, " mB/t")) log.debug(util.c("SPCTL: setting burn rate directly to ", setpoints.burn_rate, " mB/t"))
---@diagnostic disable-next-line: need-check-nil
reactor.setBurnRate(setpoints.burn_rate) reactor.setBurnRate(setpoints.burn_rate)
end end
end end
@ -658,7 +660,6 @@ function threads.thread__setpoint_control(smem)
-- adjust burn rate (setpoints.burn_rate) -- adjust burn rate (setpoints.burn_rate)
if setpoints.burn_rate_en then if setpoints.burn_rate_en then
if rps.is_active() then if rps.is_active() then
---@diagnostic disable-next-line: need-check-nil
local current_burn_rate = reactor.getBurnRate() local current_burn_rate = reactor.getBurnRate()
-- we yielded, check enable again -- we yielded, check enable again
@ -679,7 +680,6 @@ function threads.thread__setpoint_control(smem)
running = running or (new_burn_rate ~= setpoints.burn_rate) running = running or (new_burn_rate ~= setpoints.burn_rate)
-- set the burn rate -- set the burn rate
---@diagnostic disable-next-line: need-check-nil
reactor.setBurnRate(new_burn_rate) reactor.setBurnRate(new_burn_rate)
end end
else else

View File

@ -12,21 +12,21 @@ local util = require("scada-common.util")
local core = require("graphics.core") local core = require("graphics.core")
local themes = require("graphics.themes") local themes = require("graphics.themes")
local DisplayBox = require("graphics.elements.displaybox") local DisplayBox = require("graphics.elements.DisplayBox")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local ListBox = require("graphics.elements.listbox") local ListBox = require("graphics.elements.ListBox")
local MultiPane = require("graphics.elements.multipane") local MultiPane = require("graphics.elements.MultiPane")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local CheckBox = require("graphics.elements.controls.checkbox") local Checkbox = require("graphics.elements.controls.Checkbox")
local PushButton = require("graphics.elements.controls.push_button") local PushButton = require("graphics.elements.controls.PushButton")
local Radio2D = require("graphics.elements.controls.radio_2d") local Radio2D = require("graphics.elements.controls.Radio2D")
local RadioButton = require("graphics.elements.controls.radio_button") local RadioButton = require("graphics.elements.controls.RadioButton")
local NumberField = require("graphics.elements.form.number_field") local NumberField = require("graphics.elements.form.NumberField")
local TextField = require("graphics.elements.form.text_field") local TextField = require("graphics.elements.form.TextField")
local IndLight = require("graphics.elements.indicators.light") local IndLight = require("graphics.elements.indicators.IndicatorLight")
local println = util.println local println = util.println
local tri = util.trinary local tri = util.trinary
@ -88,17 +88,17 @@ local changes = {
{ "v1.10.2", { "Re-organized peripheral configuration UI, resulting in some input fields being re-ordered" } } { "v1.10.2", { "Re-organized peripheral configuration UI, resulting in some input fields being re-ordered" } }
} }
---@class rtu_peri_definition
---@field unit integer|nil
---@field index integer|nil
---@field name string
---@class rtu_rs_definition ---@class rtu_rs_definition
---@field unit integer|nil ---@field unit integer|nil
---@field port IO_PORT ---@field port IO_PORT
---@field side side ---@field side side
---@field color color|nil ---@field color color|nil
---@class rtu_peri_definition
---@field unit integer|nil
---@field index integer|nil
---@field name string
local RTU_DEV_TYPES = { "boilerValve", "turbineValve", "dynamicValve", "inductionPort", "spsPort", "solarNeutronActivator", "environmentDetector" } local RTU_DEV_TYPES = { "boilerValve", "turbineValve", "dynamicValve", "inductionPort", "spsPort", "solarNeutronActivator", "environmentDetector" }
local NEEDS_UNIT = { "boilerValve", "turbineValve", "dynamicValve", "solarNeutronActivator", "environmentDetector" } local NEEDS_UNIT = { "boilerValve", "turbineValve", "dynamicValve", "solarNeutronActivator", "environmentDetector" }
@ -130,14 +130,14 @@ local tool_ctl = {
rs_cfg_port = IO.F_SCRAM, ---@type IO_PORT rs_cfg_port = IO.F_SCRAM, ---@type IO_PORT
rs_cfg_editing = false, ---@type integer|false rs_cfg_editing = false, ---@type integer|false
view_gw_cfg = nil, ---@type graphics_element view_gw_cfg = nil, ---@type PushButton
dev_cfg = nil, ---@type graphics_element dev_cfg = nil, ---@type PushButton
rs_cfg = nil, ---@type graphics_element rs_cfg = nil, ---@type PushButton
color_cfg = nil, ---@type graphics_element color_cfg = nil, ---@type PushButton
color_next = nil, ---@type graphics_element color_next = nil, ---@type PushButton
color_apply = nil, ---@type graphics_element color_apply = nil, ---@type PushButton
settings_apply = nil, ---@type graphics_element settings_apply = nil, ---@type PushButton
settings_confirm = nil, ---@type graphics_element settings_confirm = nil, ---@type PushButton
go_home = nil, ---@type function go_home = nil, ---@type function
gen_summary = nil, ---@type function gen_summary = nil, ---@type function
@ -149,33 +149,33 @@ local tool_ctl = {
gen_rs_summary = nil, ---@type function gen_rs_summary = nil, ---@type function
show_auth_key = nil, ---@type function show_auth_key = nil, ---@type function
show_key_btn = nil, ---@type graphics_element show_key_btn = nil, ---@type PushButton
auth_key_textbox = nil, ---@type graphics_element auth_key_textbox = nil, ---@type TextBox
auth_key_value = "", auth_key_value = "",
ppm_devs = nil, ---@type graphics_element ppm_devs = nil, ---@type ListBox
p_name_msg = nil, ---@type graphics_element p_name_msg = nil, ---@type TextBox
p_prompt = nil, ---@type graphics_element p_prompt = nil, ---@type TextBox
p_idx = nil, ---@type graphics_element p_idx = nil, ---@type NumberField
p_unit = nil, ---@type graphics_element p_unit = nil, ---@type NumberField
p_assign_btn = nil, ---@type graphics_element p_assign_btn = nil, ---@type RadioButton
p_desc = nil, ---@type graphics_element p_desc = nil, ---@type TextBox
p_desc_ext = nil, ---@type graphics_element p_desc_ext = nil, ---@type TextBox
p_err = nil, ---@type graphics_element p_err = nil, ---@type TextBox
rs_cfg_selection = nil, ---@type graphics_element rs_cfg_selection = nil, ---@type TextBox
rs_cfg_unit_l = nil, ---@type graphics_element rs_cfg_unit_l = nil, ---@type TextBox
rs_cfg_unit = nil, ---@type graphics_element rs_cfg_unit = nil, ---@type NumberField
rs_cfg_side_l = nil, ---@type graphics_element rs_cfg_side_l = nil, ---@type TextBox
rs_cfg_color = nil, ---@type graphics_element rs_cfg_color = nil, ---@type Radio2D
rs_cfg_shortcut = nil ---@type graphics_element rs_cfg_shortcut = nil ---@type TextBox
} }
---@class rtu_config ---@class rtu_config
local tmp_cfg = { local tmp_cfg = {
SpeakerVolume = 1.0, SpeakerVolume = 1.0,
Peripherals = {}, Peripherals = {}, ---@type rtu_peri_definition[]
Redstone = {}, Redstone = {}, ---@type rtu_rs_definition[]
SVR_Channel = nil, ---@type integer SVR_Channel = nil, ---@type integer
RTU_Channel = nil, ---@type integer RTU_Channel = nil, ---@type integer
ConnTimeout = nil, ---@type number ConnTimeout = nil, ---@type number
@ -259,7 +259,7 @@ local function load_settings(target, raw)
end end
-- create the config view -- create the config view
---@param display graphics_element ---@param display DisplayBox
local function config_view(display) local function config_view(display)
---@diagnostic disable-next-line: undefined-field ---@diagnostic disable-next-line: undefined-field
local function exit() os.queueEvent("terminate") end local function exit() os.queueEvent("terminate") end
@ -446,11 +446,11 @@ local function config_view(display)
TextBox{parent=net_c_3,x=1,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for security on multiplayer servers. All devices on the same network MUST use the same key if any device has a key. This does result in some extra compution (can slow things down).",fg_bg=g_lg_fg_bg} TextBox{parent=net_c_3,x=1,y=4,height=6,text="This enables verifying that messages are authentic, so it is intended for security on multiplayer servers. All devices on the same network MUST use the same key if any device has a key. This does result in some extra compution (can slow things down).",fg_bg=g_lg_fg_bg}
TextBox{parent=net_c_3,x=1,y=11,text="Facility Auth Key"} TextBox{parent=net_c_3,x=1,y=11,text="Facility Auth Key"}
local key, _, censor = TextField{parent=net_c_3,x=1,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg} local key, _ = TextField{parent=net_c_3,x=1,y=12,max_len=64,value=ini_cfg.AuthKey,width=32,height=1,fg_bg=bw_fg_bg}
local function censor_key(enable) censor(tri(enable, "*", nil)) end local function censor_key(enable) key.censor(tri(enable, "*", nil)) end
local hide_key = CheckBox{parent=net_c_3,x=34,y=12,label="Hide",box_fg_bg=cpair(colors.lightBlue,colors.black),callback=censor_key} local hide_key = Checkbox{parent=net_c_3,x=34,y=12,label="Hide",box_fg_bg=cpair(colors.lightBlue,colors.black),callback=censor_key}
hide_key.set_value(true) hide_key.set_value(true)
censor_key(true) censor_key(true)
@ -485,7 +485,7 @@ local function config_view(display)
TextBox{parent=log_c_1,x=1,y=7,text="Log File Path"} TextBox{parent=log_c_1,x=1,y=7,text="Log File Path"}
local path = TextField{parent=log_c_1,x=1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg} local path = TextField{parent=log_c_1,x=1,y=8,width=49,height=1,value=ini_cfg.LogPath,max_len=128,fg_bg=bw_fg_bg}
local en_dbg = CheckBox{parent=log_c_1,x=1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)} local en_dbg = Checkbox{parent=log_c_1,x=1,y=10,default=ini_cfg.LogDebug,label="Enable Logging Debug Messages",box_fg_bg=cpair(colors.pink,colors.black)}
TextBox{parent=log_c_1,x=3,y=11,height=2,text="This results in much larger log files. It is best to only use this when there is a problem.",fg_bg=g_lg_fg_bg} TextBox{parent=log_c_1,x=3,y=11,height=2,text="This results in much larger log files. It is best to only use this when there is a problem.",fg_bg=g_lg_fg_bg}
local path_err = TextBox{parent=log_c_1,x=8,y=14,width=35,text="Please provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true} local path_err = TextBox{parent=log_c_1,x=8,y=14,width=35,text="Please provide a log file path.",fg_bg=cpair(colors.red,colors.lightGray),hidden=true}
@ -1198,7 +1198,7 @@ local function config_view(display)
tool_ctl.rs_cfg_shortcut = TextBox{parent=rs_c_3,x=1,y=9,height=4,text="This shortcut will add entries for each of the 4 waste outputs. If you select bundled, 4 colors will be assigned to the selected side. Otherwise, 4 default sides will be used."} tool_ctl.rs_cfg_shortcut = TextBox{parent=rs_c_3,x=1,y=9,height=4,text="This shortcut will add entries for each of the 4 waste outputs. If you select bundled, 4 colors will be assigned to the selected side. Otherwise, 4 default sides will be used."}
tool_ctl.rs_cfg_shortcut.hide(true) tool_ctl.rs_cfg_shortcut.hide(true)
local bundled = CheckBox{parent=rs_c_3,x=1,y=7,label="Is Bundled?",default=false,box_fg_bg=cpair(colors.red,colors.black),callback=set_bundled} local bundled = Checkbox{parent=rs_c_3,x=1,y=7,label="Is Bundled?",default=false,box_fg_bg=cpair(colors.red,colors.black),callback=set_bundled}
tool_ctl.rs_cfg_color = Radio2D{parent=rs_c_3,x=1,y=9,rows=4,columns=4,default=1,options=color_options,radio_colors=cpair(colors.lightGray,colors.black),color_map=color_options_map,disable_color=colors.gray,disable_fg_bg=g_lg_fg_bg} tool_ctl.rs_cfg_color = Radio2D{parent=rs_c_3,x=1,y=9,rows=4,columns=4,default=1,options=color_options,radio_colors=cpair(colors.lightGray,colors.black),color_map=color_options_map,disable_color=colors.gray,disable_fg_bg=g_lg_fg_bg}
tool_ctl.rs_cfg_color.disable() tool_ctl.rs_cfg_color.disable()
@ -1296,7 +1296,7 @@ local function config_view(display)
local ini_unit = tri(for_facility, nil, entry.for_reactor) local ini_unit = tri(for_facility, nil, entry.for_reactor)
local def = { name = entry.name, unit = ini_unit, index = entry.index } local def = { name = entry.name, unit = ini_unit, index = entry.index }
local mount = mounts[def.name] ---@type ppm_entry|nil local mount = mounts[def.name]
local status = " \x13 not connected, please re-config later" local status = " \x13 not connected, please re-config later"
local color = colors.orange local color = colors.orange
@ -1497,7 +1497,7 @@ local function config_view(display)
peri_list.remove_all() peri_list.remove_all()
for i = 1, #cfg.Peripherals do for i = 1, #cfg.Peripherals do
local def = cfg.Peripherals[i] ---@type rtu_peri_definition local def = cfg.Peripherals[i]
local t = ppm.get_type(def.name) local t = ppm.get_type(def.name)
local t_str = "<disconnected> (connect to edit)" local t_str = "<disconnected> (connect to edit)"
@ -1529,7 +1529,7 @@ local function config_view(display)
end end
local function edit_rs_entry(idx) local function edit_rs_entry(idx)
local def = tmp_cfg.Redstone[idx] ---@type rtu_rs_definition local def = tmp_cfg.Redstone[idx]
tool_ctl.rs_cfg_shortcut.hide(true) tool_ctl.rs_cfg_shortcut.hide(true)
tool_ctl.rs_cfg_color.show() tool_ctl.rs_cfg_color.show()

View File

@ -10,15 +10,15 @@ local databus = {}
-- databus PSIL -- databus PSIL
databus.ps = psil.create() databus.ps = psil.create()
---@enum RTU_UNIT_HW_STATE ---@enum RTU_HW_STATE
local RTU_UNIT_HW_STATE = { local RTU_HW_STATE = {
OFFLINE = 1, OFFLINE = 1,
FAULTED = 2, FAULTED = 2,
UNFORMED = 3, UNFORMED = 3,
OK = 4 OK = 4
} }
databus.RTU_UNIT_HW_STATE = RTU_UNIT_HW_STATE databus.RTU_HW_STATE = RTU_HW_STATE
-- call to toggle heartbeat signal -- call to toggle heartbeat signal
function databus.heartbeat() databus.ps.toggle("heartbeat") end function databus.heartbeat() databus.ps.toggle("heartbeat") end
@ -52,7 +52,7 @@ end
-- transmit unit hardware status across the bus -- transmit unit hardware status across the bus
---@param uid integer unit ID ---@param uid integer unit ID
---@param status RTU_UNIT_HW_STATE ---@param status RTU_HW_STATE
function databus.tx_unit_hw_status(uid, status) function databus.tx_unit_hw_status(uid, status)
databus.ps.publish("unit_hw_" .. uid, status) databus.ps.publish("unit_hw_" .. uid, status)
end end

View File

@ -11,13 +11,13 @@ local style = require("rtu.panel.style")
local core = require("graphics.core") local core = require("graphics.core")
local Div = require("graphics.elements.div") local Div = require("graphics.elements.Div")
local TextBox = require("graphics.elements.textbox") local TextBox = require("graphics.elements.TextBox")
local DataIndicator = require("graphics.elements.indicators.data") local DataIndicator = require("graphics.elements.indicators.DataIndicator")
local LED = require("graphics.elements.indicators.led") local LED = require("graphics.elements.indicators.LED")
local LEDPair = require("graphics.elements.indicators.ledpair") local LEDPair = require("graphics.elements.indicators.LEDPair")
local RGBLED = require("graphics.elements.indicators.ledrgb") local RGBLED = require("graphics.elements.indicators.RGBLED")
local LINK_STATE = types.PANEL_LINK_STATE local LINK_STATE = types.PANEL_LINK_STATE
@ -30,8 +30,8 @@ local ind_grn = style.ind_grn
local UNIT_TYPE_LABELS = { "UNKNOWN", "REDSTONE", "BOILER", "TURBINE", "DYNAMIC TANK", "IND MATRIX", "SPS", "SNA", "ENV DETECTOR" } local UNIT_TYPE_LABELS = { "UNKNOWN", "REDSTONE", "BOILER", "TURBINE", "DYNAMIC TANK", "IND MATRIX", "SPS", "SNA", "ENV DETECTOR" }
-- create new front panel view -- create new front panel view
---@param panel graphics_element main displaybox ---@param panel DisplayBox main displaybox
---@param units table unit list ---@param units rtu_registry_entry[] unit list
local function init(panel, units) local function init(panel, units)
local disabled_fg = style.fp.disabled_fg local disabled_fg = style.fp.disabled_fg
@ -135,7 +135,7 @@ local function init(panel, units)
-- show hardware statuses -- show hardware statuses
for i = 1, list_length do for i = 1, list_length do
local unit = units[i] ---@type rtu_unit_registry_entry local unit = units[i]
-- hardware status -- hardware status
local unit_hw = RGBLED{parent=unit_hw_statuses,y=i,label="",colors={colors.red,colors.orange,colors.yellow,colors.green}} local unit_hw = RGBLED{parent=unit_hw_statuses,y=i,label="",colors={colors.red,colors.orange,colors.yellow,colors.green}}

View File

@ -8,7 +8,7 @@ local style = require("rtu.panel.style")
local core = require("graphics.core") local core = require("graphics.core")
local flasher = require("graphics.flasher") local flasher = require("graphics.flasher")
local DisplayBox = require("graphics.elements.displaybox") local DisplayBox = require("graphics.elements.DisplayBox")
---@class rtu_renderer ---@class rtu_renderer
local renderer = {} local renderer = {}
@ -18,7 +18,7 @@ local ui = {
} }
-- try to start the UI -- try to start the UI
---@param units table RTU units ---@param units rtu_registry_entry[] RTU entries
---@param theme FP_THEME front panel theme ---@param theme FP_THEME front panel theme
---@param color_mode COLOR_MODE color mode ---@param color_mode COLOR_MODE color mode
---@return boolean success, any error_msg ---@return boolean success, any error_msg

View File

@ -235,7 +235,7 @@ function rtu.init_unit(device)
end end
-- create an alarm speaker sounder -- create an alarm speaker sounder
---@param speaker table device peripheral ---@param speaker Speaker device peripheral
function rtu.init_sounder(speaker) function rtu.init_sounder(speaker)
---@class rtu_speaker_sounder ---@class rtu_speaker_sounder
local spkr_ctl = { local spkr_ctl = {
@ -322,13 +322,13 @@ function rtu.comms(version, nic, conn_watchdog)
-- generate device advertisement table -- generate device advertisement table
---@nodiscard ---@nodiscard
---@param units table ---@param units rtu_registry_entry[]
---@return table advertisement ---@return table advertisement
local function _generate_advertisement(units) local function _generate_advertisement(units)
local advertisement = {} local advertisement = {}
for i = 1, #units do for i = 1, #units do
local unit = units[i] ---@type rtu_unit_registry_entry local unit = units[i]
if unit.type ~= nil then if unit.type ~= nil then
local advert = { unit.type, unit.index, unit.reactor } local advert = { unit.type, unit.index, unit.reactor }
@ -429,9 +429,9 @@ function rtu.comms(version, nic, conn_watchdog)
-- handle a MODBUS/SCADA packet -- handle a MODBUS/SCADA packet
---@param packet modbus_frame|mgmt_frame ---@param packet modbus_frame|mgmt_frame
---@param units table RTU units ---@param units rtu_registry_entry[] RTU entries
---@param rtu_state rtu_state ---@param rtu_state rtu_state
---@param sounders table speaker alarm sounders ---@param sounders rtu_speaker_sounder[] speaker alarm sounders
function public.handle_packet(packet, units, rtu_state, sounders) function public.handle_packet(packet, units, rtu_state, sounders)
-- print a log message to the terminal as long as the UI isn't running -- print a log message to the terminal as long as the UI isn't running
local function println_ts(message) if not rtu_state.fp_ok then util.println_ts(message) end end local function println_ts(message) if not rtu_state.fp_ok then util.println_ts(message) end end
@ -467,7 +467,7 @@ function rtu.comms(version, nic, conn_watchdog)
-- handle MODBUS instruction -- handle MODBUS instruction
if packet.unit_id <= #units then if packet.unit_id <= #units then
local unit = units[packet.unit_id] ---@type rtu_unit_registry_entry local unit = units[packet.unit_id]
local unit_dbg_tag = " (unit " .. packet.unit_id .. ")" local unit_dbg_tag = " (unit " .. packet.unit_id .. ")"
if unit.name == "redstone_io" then if unit.name == "redstone_io" then
@ -538,11 +538,9 @@ function rtu.comms(version, nic, conn_watchdog)
if (packet.length == 1) and type(packet.data[1] == "table") and (#packet.data[1] == 8) then if (packet.length == 1) and type(packet.data[1] == "table") and (#packet.data[1] == 8) then
local states = packet.data[1] local states = packet.data[1]
for i = 1, #sounders do
local s = sounders[i] ---@type rtu_speaker_sounder
-- set tone states -- set tone states
for id = 1, #states do s.stream.set_active(id, states[id] == true) end for i = 1, #sounders do
for id = 1, #states do sounders[i].stream.set_active(id, states[id] == true) end
end end
end end
else else

View File

@ -31,10 +31,10 @@ local sna_rtu = require("rtu.dev.sna_rtu")
local sps_rtu = require("rtu.dev.sps_rtu") local sps_rtu = require("rtu.dev.sps_rtu")
local turbinev_rtu = require("rtu.dev.turbinev_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu")
local RTU_VERSION = "v1.10.8" local RTU_VERSION = "v1.10.9"
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE local RTU_HW_STATE = databus.RTU_HW_STATE
local println = util.println local println = util.println
local println_ts = util.println_ts local println_ts = util.println_ts
@ -109,7 +109,7 @@ local function main()
-- RTU gateway devices (not RTU units) -- RTU gateway devices (not RTU units)
rtu_dev = { rtu_dev = {
modem = ppm.get_wireless_modem(), modem = ppm.get_wireless_modem(),
sounders = {} sounders = {} ---@type rtu_speaker_sounder[]
}, },
-- system objects -- system objects
@ -117,7 +117,7 @@ local function main()
nic = nil, ---@type nic nic = nil, ---@type nic
rtu_comms = nil, ---@type rtu_comms rtu_comms = nil, ---@type rtu_comms
conn_watchdog = nil, ---@type watchdog conn_watchdog = nil, ---@type watchdog
units = {} units = {} ---@type rtu_registry_entry[]
}, },
-- message queues -- message queues
@ -143,11 +143,11 @@ local function main()
-- configure RTU gateway based on settings file definitions -- configure RTU gateway based on settings file definitions
local function sys_config() local function sys_config()
-- redstone interfaces -- redstone interfaces
local rs_rtus = {} local rs_rtus = {} ---@type { rtu: rtu_rs_device, capabilities: IO_PORT[] }[]
-- go through redstone definitions list -- go through redstone definitions list
for entry_idx = 1, #rtu_redstone do for entry_idx = 1, #rtu_redstone do
local entry = rtu_redstone[entry_idx] ---@type rtu_rs_definition local entry = rtu_redstone[entry_idx]
local assignment local assignment
local for_reactor = entry.unit local for_reactor = entry.unit
local iface_name = util.trinary(entry.color ~= nil, util.c(entry.side, "/", rsio.color_name(entry.color)), entry.side) local iface_name = util.trinary(entry.color ~= nil, util.c(entry.side, "/", rsio.color_name(entry.color)), entry.side)
@ -227,17 +227,17 @@ local function main()
-- create unit entries for redstone RTUs -- create unit entries for redstone RTUs
for for_reactor, def in pairs(rs_rtus) do for for_reactor, def in pairs(rs_rtus) do
---@class rtu_unit_registry_entry ---@class rtu_registry_entry
local unit = { local unit = {
uid = 0, ---@type integer uid = 0, ---@type integer
name = "redstone_io", ---@type string name = "redstone_io", ---@type string
type = RTU_UNIT_TYPE.REDSTONE, ---@type RTU_UNIT_TYPE type = RTU_UNIT_TYPE.REDSTONE, ---@type RTU_UNIT_TYPE
index = false, ---@type integer|false index = false, ---@type integer|false
reactor = for_reactor, ---@type integer reactor = for_reactor, ---@type integer
device = def.capabilities, ---@type table use device field for redstone ports device = def.capabilities, ---@type IO_PORT[] use device field for redstone ports
is_multiblock = false, ---@type boolean is_multiblock = false, ---@type boolean
formed = nil, ---@type boolean|nil formed = nil, ---@type boolean|nil
hw_state = RTU_UNIT_HW_STATE.OK, ---@type RTU_UNIT_HW_STATE hw_state = RTU_HW_STATE.OK, ---@type RTU_HW_STATE
rtu = def.rtu, ---@type rtu_device|rtu_rs_device rtu = def.rtu, ---@type rtu_device|rtu_rs_device
modbus_io = modbus.new(def.rtu, false), modbus_io = modbus.new(def.rtu, false),
pkt_queue = nil, ---@type mqueue|nil pkt_queue = nil, ---@type mqueue|nil
@ -440,17 +440,17 @@ local function main()
end end
end end
---@class rtu_unit_registry_entry ---@class rtu_registry_entry
local rtu_unit = { local rtu_unit = {
uid = 0, ---@type integer uid = 0, ---@type integer
name = name, ---@type string name = name, ---@type string
type = rtu_type, ---@type RTU_UNIT_TYPE type = rtu_type, ---@type RTU_UNIT_TYPE
index = index or false, ---@type integer|false index = index or false, ---@type integer|false
reactor = for_reactor, ---@type integer reactor = for_reactor, ---@type integer
device = device, ---@type table device = device, ---@type table peripheral reference
is_multiblock = is_multiblock, ---@type boolean is_multiblock = is_multiblock, ---@type boolean
formed = formed, ---@type boolean|nil formed = formed, ---@type boolean|nil
hw_state = RTU_UNIT_HW_STATE.OFFLINE, ---@type RTU_UNIT_HW_STATE hw_state = RTU_HW_STATE.OFFLINE, ---@type RTU_HW_STATE
rtu = rtu_iface, ---@type rtu_device|rtu_rs_device rtu = rtu_iface, ---@type rtu_device|rtu_rs_device
modbus_io = modbus.new(rtu_iface, true), modbus_io = modbus.new(rtu_iface, true),
pkt_queue = mqueue.new(), ---@type mqueue|nil pkt_queue = mqueue.new(), ---@type mqueue|nil
@ -473,14 +473,14 @@ local function main()
-- determine hardware status -- determine hardware status
if rtu_unit.type == RTU_UNIT_TYPE.VIRTUAL then if rtu_unit.type == RTU_UNIT_TYPE.VIRTUAL then
rtu_unit.hw_state = RTU_UNIT_HW_STATE.OFFLINE rtu_unit.hw_state = RTU_HW_STATE.OFFLINE
else else
if rtu_unit.is_multiblock then if rtu_unit.is_multiblock then
rtu_unit.hw_state = util.trinary(rtu_unit.formed == true, RTU_UNIT_HW_STATE.OK, RTU_UNIT_HW_STATE.UNFORMED) rtu_unit.hw_state = util.trinary(rtu_unit.formed == true, RTU_HW_STATE.OK, RTU_HW_STATE.UNFORMED)
elseif faulted then elseif faulted then
rtu_unit.hw_state = RTU_UNIT_HW_STATE.FAULTED rtu_unit.hw_state = RTU_HW_STATE.FAULTED
else else
rtu_unit.hw_state = RTU_UNIT_HW_STATE.OK rtu_unit.hw_state = RTU_HW_STATE.OK
end end
end end

Some files were not shown because too many files have changed in this diff Show More