diff --git a/scada-common/util.lua b/scada-common/util.lua index 8dffd40..38cfc1f 100644 --- a/scada-common/util.lua +++ b/scada-common/util.lua @@ -80,6 +80,33 @@ util.adaptive_delay = function (target_timing, last_update) return util.time() end +-- TABLE UTILITIES -- + +-- delete elements from a table if the passed function returns false when passed a table element +-- +-- put briefly: deletes elements that return false, keeps elements that return true +---@param t table table to remove elements from +---@param f function should return false to delete an element when passed the element: f(elem) = true|false +---@param on_delete? function optional function to execute on deletion, passed the table element to be deleted as the parameter +util.filter_table = function (t, f, on_delete) + local move_to = 1 + for i = 1, #t do + local element = t[i] + if element ~= nil then + if f(element) then + if t[move_to] == nil then + t[move_to] = element + t[i] = nil + end + move_to = move_to + 1 + else + if on_delete then on_delete(element) end + t[i] = nil + end + end + end +end + -- MEKANISM POWER -- -- function kFE(fe) return fe / 1000 end diff --git a/supervisor/session/rtu/txnctrl.lua b/supervisor/session/rtu/txnctrl.lua index 3d74484..2d6be2e 100644 --- a/supervisor/session/rtu/txnctrl.lua +++ b/supervisor/session/rtu/txnctrl.lua @@ -66,22 +66,7 @@ txnctrl.new = function () -- close timed-out transactions public.cleanup = function () local now = util.time() - - local move_to = 1 - for i = 1, public.length() do - local txn = self.list[i] - if txn ~= nil then - if txn.expiry <= now then - self.list[i] = nil - else - if self.list[move_to] == nil then - self.list[move_to] = txn - self.list[i] = nil - end - move_to = move_to + 1 - end - end - end + util.filter_table(self.list, function (txn) return txn.expiry > now end) end -- clear the transaction list diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index 88c57cd..d0b76cc 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -1,5 +1,6 @@ local log = require("scada-common.log") local mqueue = require("scada-common.mqueue") +local util = require("scada-common.util") local coordinator = require("supervisor.session.coordinator") local plc = require("supervisor.session.plc") @@ -99,22 +100,10 @@ end -- delete any closed sessions ---@param sessions table local function _free_closed(sessions) - local move_to = 1 - for i = 1, #sessions do - local session = sessions[i] ---@type plc_session_struct - if session ~= nil then - if session.open then - if sessions[move_to] == nil then - sessions[move_to] = session - sessions[i] = nil - end - move_to = move_to + 1 - else - log.debug("free'ing closed session " .. session.instance.get_id() .. " on remote port " .. session.r_port) - sessions[i] = nil - end - end - end + local f = function (session) return session.open end + local on_delete = function (session) log.debug("free'ing closed session " .. session.instance.get_id() .. " on remote port " .. session.r_port) end + + util.filter_table(sessions, f, on_delete) end -- PUBLIC FUNCTIONS --