scada-common annotation updates
This commit is contained in:
parent
fb56634fc4
commit
3003e57531
@ -7,7 +7,7 @@
|
|||||||
-- note: max samples = 0x20000 (128 * 1024 samples)
|
-- note: max samples = 0x20000 (128 * 1024 samples)
|
||||||
|
|
||||||
local _2_PI = 2 * math.pi -- 2 whole pies, hope you're hungry
|
local _2_PI = 2 * math.pi -- 2 whole pies, hope you're hungry
|
||||||
local _DRATE = 48000 -- 48kHz audio
|
local _DRATE = 48000 -- 48kHz audio data rate
|
||||||
local _MAX_VAL = 127 / 2 -- max signed integer in this 8-bit audio
|
local _MAX_VAL = 127 / 2 -- max signed integer in this 8-bit audio
|
||||||
local _05s_SAMPLES = 24000 -- half a second worth of samples
|
local _05s_SAMPLES = 24000 -- half a second worth of samples
|
||||||
|
|
||||||
@ -28,6 +28,7 @@ local TONE = {
|
|||||||
|
|
||||||
audio.TONE = TONE
|
audio.TONE = TONE
|
||||||
|
|
||||||
|
---@type integer[][][]
|
||||||
local tone_data = {
|
local tone_data = {
|
||||||
{ {}, {}, {}, {} }, -- 340Hz @ 2Hz Intermittent
|
{ {}, {}, {}, {} }, -- 340Hz @ 2Hz Intermittent
|
||||||
{ {}, {}, {}, {} }, -- 544Hz 100mS / 440Hz 400mS Alternating
|
{ {}, {}, {}, {} }, -- 544Hz 100mS / 440Hz 400mS Alternating
|
||||||
@ -214,7 +215,14 @@ end
|
|||||||
|
|
||||||
-- generate all 8 tone sequences
|
-- generate all 8 tone sequences
|
||||||
function audio.generate_tones()
|
function audio.generate_tones()
|
||||||
gen_tone_1(); gen_tone_2(); gen_tone_3(); gen_tone_4(); gen_tone_5(); gen_tone_6(); gen_tone_7(); gen_tone_8()
|
gen_tone_1()
|
||||||
|
gen_tone_2()
|
||||||
|
gen_tone_3()
|
||||||
|
gen_tone_4()
|
||||||
|
gen_tone_5()
|
||||||
|
gen_tone_6()
|
||||||
|
gen_tone_7()
|
||||||
|
gen_tone_8()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- hard audio limiter
|
-- hard audio limiter
|
||||||
@ -226,7 +234,7 @@ local function limit(output)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- clear output buffer
|
-- clear output buffer
|
||||||
---@param buffer table quad buffer
|
---@param buffer integer[][] quad buffer
|
||||||
local function clear(buffer)
|
local function clear(buffer)
|
||||||
for i = 1, 4 do
|
for i = 1, 4 do
|
||||||
for s = 1, _05s_SAMPLES do buffer[i][s] = 0 end
|
for s = 1, _05s_SAMPLES do buffer[i][s] = 0 end
|
||||||
@ -239,7 +247,7 @@ function audio.new_stream()
|
|||||||
any_active = false,
|
any_active = false,
|
||||||
need_recompute = false,
|
need_recompute = false,
|
||||||
next_block = 1,
|
next_block = 1,
|
||||||
-- split audio up into 0.5s samples, so specific components can be ended quicker
|
---@type integer[][] split audio up into 0.5s samples, so specific components can be ended quicker
|
||||||
quad_buffer = { {}, {}, {}, {} },
|
quad_buffer = { {}, {}, {}, {} },
|
||||||
-- all tone enable states
|
-- all tone enable states
|
||||||
tone_active = { false, false, false, false, false, false, false, false }
|
tone_active = { false, false, false, false, false, false, false, false }
|
||||||
@ -263,14 +271,17 @@ function audio.new_stream()
|
|||||||
-- check if a tone is active
|
-- check if a tone is active
|
||||||
---@param index TONE tone index
|
---@param index TONE tone index
|
||||||
function public.is_active(index)
|
function public.is_active(index)
|
||||||
if self.tone_active[index] then return self.tone_active[index] end
|
return self.tone_active[index] or false
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set all tones inactive, reset next block, and clear output buffer
|
-- set all tones inactive, reset next block, and clear output buffer
|
||||||
function public.stop()
|
function public.stop()
|
||||||
for i = 1, #self.tone_active do self.tone_active[i] = false end
|
for i = 1, #self.tone_active do
|
||||||
|
self.tone_active[i] = false
|
||||||
|
end
|
||||||
|
|
||||||
self.next_block = 1
|
self.next_block = 1
|
||||||
|
|
||||||
clear(self.quad_buffer)
|
clear(self.quad_buffer)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -287,9 +298,11 @@ function audio.new_stream()
|
|||||||
for id = 1, #tone_data do
|
for id = 1, #tone_data do
|
||||||
if self.tone_active[id] then
|
if self.tone_active[id] then
|
||||||
self.any_active = true
|
self.any_active = true
|
||||||
|
|
||||||
for i = 1, 4 do
|
for i = 1, 4 do
|
||||||
local buffer = self.quad_buffer[i]
|
local buffer = self.quad_buffer[i]
|
||||||
local values = tone_data[id][i]
|
local values = tone_data[id][i]
|
||||||
|
|
||||||
for s = 1, _05s_SAMPLES do self.quad_buffer[i][s] = limit(buffer[s] + values[s]) end
|
for s = 1, _05s_SAMPLES do self.quad_buffer[i][s] = limit(buffer[s] + values[s]) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -305,8 +318,13 @@ function audio.new_stream()
|
|||||||
-- get the next audio block
|
-- get the next audio block
|
||||||
function public.get_next_block()
|
function public.get_next_block()
|
||||||
local block = self.quad_buffer[self.next_block]
|
local block = self.quad_buffer[self.next_block]
|
||||||
|
|
||||||
self.next_block = self.next_block + 1
|
self.next_block = self.next_block + 1
|
||||||
if self.next_block > 4 then self.next_block = 1 end
|
|
||||||
|
if self.next_block > 4 then
|
||||||
|
self.next_block = 1
|
||||||
|
end
|
||||||
|
|
||||||
return block
|
return block
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -405,7 +405,7 @@ function comms.modbus_packet()
|
|||||||
self.raw = { self.txn_id, self.unit_id, self.func_code }
|
self.raw = { self.txn_id, self.unit_id, self.func_code }
|
||||||
for i = 1, self.length do insert(self.raw, data[i]) end
|
for i = 1, self.length do insert(self.raw, data[i]) end
|
||||||
else
|
else
|
||||||
log.error("comms.modbus_packet.make(): data not table")
|
log.error("comms.modbus_packet.make(): data not a table")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -491,7 +491,7 @@ function comms.rplc_packet()
|
|||||||
self.raw = { self.id, self.type }
|
self.raw = { self.id, self.type }
|
||||||
for i = 1, #data do insert(self.raw, data[i]) end
|
for i = 1, #data do insert(self.raw, data[i]) end
|
||||||
else
|
else
|
||||||
log.error("comms.rplc_packet.make(): data not table")
|
log.error("comms.rplc_packet.make(): data not a table")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -573,7 +573,7 @@ function comms.mgmt_packet()
|
|||||||
self.raw = { self.type }
|
self.raw = { self.type }
|
||||||
for i = 1, #data do insert(self.raw, data[i]) end
|
for i = 1, #data do insert(self.raw, data[i]) end
|
||||||
else
|
else
|
||||||
log.error("comms.mgmt_packet.make(): data not table")
|
log.error("comms.mgmt_packet.make(): data not a table")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -652,7 +652,7 @@ function comms.crdn_packet()
|
|||||||
self.raw = { self.type }
|
self.raw = { self.type }
|
||||||
for i = 1, #data do insert(self.raw, data[i]) end
|
for i = 1, #data do insert(self.raw, data[i]) end
|
||||||
else
|
else
|
||||||
log.error("comms.crdn_packet.make(): data not table")
|
log.error("comms.crdn_packet.make(): data not a table")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ local util = require("scada-common.util")
|
|||||||
---@class logger
|
---@class logger
|
||||||
local log = {}
|
local log = {}
|
||||||
|
|
||||||
---@alias MODE integer
|
---@enum MODE
|
||||||
local MODE = { APPEND = 0, NEW = 1 }
|
local MODE = { APPEND = 0, NEW = 1 }
|
||||||
|
|
||||||
log.MODE = MODE
|
log.MODE = MODE
|
||||||
@ -18,7 +18,7 @@ local logger = {
|
|||||||
mode = MODE.APPEND,
|
mode = MODE.APPEND,
|
||||||
debug = false,
|
debug = false,
|
||||||
file = nil, ---@type table|nil
|
file = nil, ---@type table|nil
|
||||||
dmesg_out = nil,
|
dmesg_out = nil, ---@type table|nil
|
||||||
dmesg_restore_coord = { 1, 1 },
|
dmesg_restore_coord = { 1, 1 },
|
||||||
dmesg_scroll_count = 0
|
dmesg_scroll_count = 0
|
||||||
}
|
}
|
||||||
@ -37,7 +37,7 @@ local function _log(msg)
|
|||||||
|
|
||||||
local out_of_space = false
|
local out_of_space = false
|
||||||
local time_stamp = os.date("[%c] ")
|
local time_stamp = os.date("[%c] ")
|
||||||
local stamped = time_stamp .. util.strval(msg)
|
local stamped = util.c(time_stamp, msg)
|
||||||
|
|
||||||
-- attempt to write log
|
-- attempt to write log
|
||||||
local status, result = pcall(function ()
|
local status, result = pcall(function ()
|
||||||
@ -291,7 +291,7 @@ function log.dmesg_working(msg, tag, tag_color)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- log debug messages
|
-- log debug messages
|
||||||
---@param msg string message
|
---@param msg any message
|
||||||
---@param trace? boolean include file trace
|
---@param trace? boolean include file trace
|
||||||
function log.debug(msg, trace)
|
function log.debug(msg, trace)
|
||||||
if logger.debug then
|
if logger.debug then
|
||||||
@ -302,30 +302,30 @@ function log.debug(msg, trace)
|
|||||||
local name = ""
|
local name = ""
|
||||||
|
|
||||||
if info.name ~= nil then
|
if info.name ~= nil then
|
||||||
name = ":" .. info.name .. "():"
|
name = util.c(":", info.name, "():")
|
||||||
end
|
end
|
||||||
|
|
||||||
dbg_info = info.short_src .. ":" .. name .. info.currentline .. " > "
|
dbg_info = util.c(info.short_src, ":", name, info.currentline, " > ")
|
||||||
end
|
end
|
||||||
|
|
||||||
_log("[DBG] " .. dbg_info .. util.strval(msg))
|
_log(util.c("[DBG] ", dbg_info, msg))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- log info messages
|
-- log info messages
|
||||||
---@param msg string message
|
---@param msg any message
|
||||||
function log.info(msg)
|
function log.info(msg)
|
||||||
_log("[INF] " .. util.strval(msg))
|
_log(util.c("[INF] ", msg))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- log warning messages
|
-- log warning messages
|
||||||
---@param msg string message
|
---@param msg any message
|
||||||
function log.warning(msg)
|
function log.warning(msg)
|
||||||
_log("[WRN] " .. util.strval(msg))
|
_log(util.c("[WRN] ", msg))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- log error messages
|
-- log error messages
|
||||||
---@param msg string message
|
---@param msg any message
|
||||||
---@param trace? boolean include file trace
|
---@param trace? boolean include file trace
|
||||||
function log.error(msg, trace)
|
function log.error(msg, trace)
|
||||||
local dbg_info = ""
|
local dbg_info = ""
|
||||||
@ -335,19 +335,19 @@ function log.error(msg, trace)
|
|||||||
local name = ""
|
local name = ""
|
||||||
|
|
||||||
if info.name ~= nil then
|
if info.name ~= nil then
|
||||||
name = ":" .. info.name .. "():"
|
name = util.c(":", info.name, "():")
|
||||||
end
|
end
|
||||||
|
|
||||||
dbg_info = info.short_src .. ":" .. name .. info.currentline .. " > "
|
dbg_info = util.c(info.short_src, ":", name, info.currentline, " > ")
|
||||||
end
|
end
|
||||||
|
|
||||||
_log("[ERR] " .. dbg_info .. util.strval(msg))
|
_log(util.c("[ERR] ", dbg_info, msg))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- log fatal errors
|
-- log fatal errors
|
||||||
---@param msg string message
|
---@param msg any message
|
||||||
function log.fatal(msg)
|
function log.fatal(msg)
|
||||||
_log("[FTL] " .. util.strval(msg))
|
_log(util.c("[FTL] ", msg))
|
||||||
end
|
end
|
||||||
|
|
||||||
return log
|
return log
|
||||||
|
|||||||
@ -27,6 +27,7 @@ local remove = table.remove
|
|||||||
-- create a new message queue
|
-- create a new message queue
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function mqueue.new()
|
function mqueue.new()
|
||||||
|
---@type queue_item[]
|
||||||
local queue = {}
|
local queue = {}
|
||||||
|
|
||||||
---@class mqueue
|
---@class mqueue
|
||||||
|
|||||||
@ -85,18 +85,15 @@ function network.nic(modem)
|
|||||||
}
|
}
|
||||||
|
|
||||||
---@class nic
|
---@class nic
|
||||||
---@field open function
|
---@field isOpen fun(channel: integer) : boolean check if a channel is open
|
||||||
---@field isOpen function
|
---@field isWireless fun() : boolean determine if this is a wired or wireless modem
|
||||||
---@field close function
|
---@field getNamesRemote fun() : string[] list all remote peripherals on the wired network
|
||||||
---@field closeAll function
|
---@field isPresentRemote fun(name: string) : boolean determine if a peripheral is available on this wired network
|
||||||
---@field isWireless function
|
---@field getTypeRemote fun(name: string) : string|nil get the type of a peripheral is available on this wired network
|
||||||
---@field getNameLocal function
|
---@field hasTypeRemote fun(name: string, type: string) : boolean|nil check a peripheral is of a particular type
|
||||||
---@field getNamesRemote function
|
---@field getMethodsRemote fun(name: string) : string[] get all available methods for the remote peripheral with the given name
|
||||||
---@field isPresentRemote function
|
---@field callRemote fun(remoteName: string, method: string, ...) : table call a method on a peripheral on this wired network
|
||||||
---@field getTypeRemote function
|
---@field getNameLocal fun() : string|nil returns the network name of the current computer, if the modem is on
|
||||||
---@field hasTypeRemote function
|
|
||||||
---@field getMethodsRemote function
|
|
||||||
---@field callRemote function
|
|
||||||
local public = {}
|
local public = {}
|
||||||
|
|
||||||
-- check if this NIC has a connected modem
|
-- check if this NIC has a connected modem
|
||||||
|
|||||||
@ -23,7 +23,7 @@ ppm.VIRTUAL_DEVICE_TYPE = VIRTUAL_DEVICE_TYPE
|
|||||||
local REPORT_FREQUENCY = 20 -- log every 20 faults per function
|
local REPORT_FREQUENCY = 20 -- log every 20 faults per function
|
||||||
|
|
||||||
local ppm_sys = {
|
local ppm_sys = {
|
||||||
mounts = {},
|
mounts = {}, ---@type { [string]: ppm_entry }
|
||||||
next_vid = 0,
|
next_vid = 0,
|
||||||
auto_cf = false,
|
auto_cf = false,
|
||||||
faulted = false,
|
faulted = false,
|
||||||
@ -40,10 +40,10 @@ local function peri_init(iface)
|
|||||||
local self = {
|
local self = {
|
||||||
faulted = false,
|
faulted = false,
|
||||||
last_fault = "",
|
last_fault = "",
|
||||||
fault_counts = {},
|
fault_counts = {}, ---@type { [string]: integer }
|
||||||
auto_cf = true,
|
auto_cf = true,
|
||||||
type = VIRTUAL_DEVICE_TYPE,
|
type = VIRTUAL_DEVICE_TYPE, ---@type string
|
||||||
device = {}
|
device = {} ---@type { [string]: function }
|
||||||
}
|
}
|
||||||
|
|
||||||
if iface ~= "__virtual__" then
|
if iface ~= "__virtual__" then
|
||||||
@ -284,10 +284,10 @@ end
|
|||||||
---@param device table device table
|
---@param device table device table
|
||||||
function ppm.unmount(device)
|
function ppm.unmount(device)
|
||||||
if device then
|
if device then
|
||||||
for side, data in pairs(ppm_sys.mounts) do
|
for iface, data in pairs(ppm_sys.mounts) do
|
||||||
if data.dev == device then
|
if data.dev == device then
|
||||||
log.warning(util.c("PPM: manually unmounted ", data.type, " mounted to ", side))
|
log.warning(util.c("PPM: manually unmounted ", data.type, " mounted to ", iface))
|
||||||
ppm_sys.mounts[side] = nil
|
ppm_sys.mounts[iface] = nil
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -352,8 +352,8 @@ end
|
|||||||
---@return string|nil iface CC peripheral interface
|
---@return string|nil iface CC peripheral interface
|
||||||
function ppm.get_iface(device)
|
function ppm.get_iface(device)
|
||||||
if device then
|
if device then
|
||||||
for side, data in pairs(ppm_sys.mounts) do
|
for iface, data in pairs(ppm_sys.mounts) do
|
||||||
if data.dev == device then return side end
|
if data.dev == device then return iface end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -6,9 +6,10 @@ local util = require("scada-common.util")
|
|||||||
|
|
||||||
local psil = {}
|
local psil = {}
|
||||||
|
|
||||||
-- instantiate a new PSI layer
|
-- instantiate a new interconnect layer
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function psil.create()
|
function psil.create()
|
||||||
|
---@type { [string]: { subscribers: { notify: fun(param: any) }[], value: any } } interconnect table
|
||||||
local ic = {}
|
local ic = {}
|
||||||
|
|
||||||
-- allocate a new interconnect field
|
-- allocate a new interconnect field
|
||||||
|
|||||||
@ -113,10 +113,13 @@ assert(#dup_chk == rsio.NUM_PORTS, "port list malformed")
|
|||||||
local IO = IO_PORT
|
local IO = IO_PORT
|
||||||
|
|
||||||
-- list of all port names
|
-- list of all port names
|
||||||
|
---@type string[]
|
||||||
local PORT_NAMES = {}
|
local PORT_NAMES = {}
|
||||||
|
|
||||||
for k, v in pairs(IO) do PORT_NAMES[v] = k end
|
for k, v in pairs(IO) do PORT_NAMES[v] = k end
|
||||||
|
|
||||||
-- list of all port I/O modes
|
-- list of all port I/O modes
|
||||||
|
---@type { [IO_PORT]: IO_MODE }
|
||||||
local MODES = {
|
local MODES = {
|
||||||
[IO.F_SCRAM] = IO_MODE.DIGITAL_IN,
|
[IO.F_SCRAM] = IO_MODE.DIGITAL_IN,
|
||||||
[IO.F_ACK] = IO_MODE.DIGITAL_IN,
|
[IO.F_ACK] = IO_MODE.DIGITAL_IN,
|
||||||
@ -233,6 +236,7 @@ end
|
|||||||
|
|
||||||
--#region Generic Checks
|
--#region Generic Checks
|
||||||
|
|
||||||
|
---@type string[]
|
||||||
local RS_SIDES = rs.getSides()
|
local RS_SIDES = rs.getSides()
|
||||||
|
|
||||||
-- check if a port is valid
|
-- check if a port is valid
|
||||||
|
|||||||
@ -7,6 +7,7 @@ local util = require("scada-common.util")
|
|||||||
|
|
||||||
local tcd = {}
|
local tcd = {}
|
||||||
|
|
||||||
|
---@type { callback: function, duration: number, expiry: number }[]
|
||||||
local registry = {}
|
local registry = {}
|
||||||
|
|
||||||
-- request a function to be called after the specified time
|
-- request a function to be called after the specified time
|
||||||
|
|||||||
@ -24,7 +24,7 @@ local t_pack = table.pack
|
|||||||
local util = {}
|
local util = {}
|
||||||
|
|
||||||
-- scada-common version
|
-- scada-common version
|
||||||
util.version = "1.4.4"
|
util.version = "1.4.5"
|
||||||
|
|
||||||
util.TICK_TIME_S = 0.05
|
util.TICK_TIME_S = 0.05
|
||||||
util.TICK_TIME_MS = 50
|
util.TICK_TIME_MS = 50
|
||||||
@ -33,9 +33,9 @@ util.TICK_TIME_MS = 50
|
|||||||
|
|
||||||
-- trinary operator
|
-- trinary operator
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
---@param cond boolean|nil condition
|
---@param cond any condition
|
||||||
---@param a any return if true
|
---@param a any return if evaluated as true
|
||||||
---@param b any return if false
|
---@param b any return if false or nil
|
||||||
---@return any value
|
---@return any value
|
||||||
function util.trinary(cond, a, b)
|
function util.trinary(cond, a, b)
|
||||||
if cond then return a else return b end
|
if cond then return a else return b end
|
||||||
@ -84,7 +84,7 @@ end
|
|||||||
-- does not behave exactly like C's strtok
|
-- does not behave exactly like C's strtok
|
||||||
---@param str string string to tokenize
|
---@param str string string to tokenize
|
||||||
---@param sep string separator to tokenize by
|
---@param sep string separator to tokenize by
|
||||||
---@return table token_list
|
---@return string[] token_list
|
||||||
function util.strtok(str, sep)
|
function util.strtok(str, sep)
|
||||||
local list = {}
|
local list = {}
|
||||||
for part in string.gmatch(str, "([^" .. sep .. "]+)") do t_insert(list, part) end
|
for part in string.gmatch(str, "([^" .. sep .. "]+)") do t_insert(list, part) end
|
||||||
@ -123,7 +123,7 @@ end
|
|||||||
---@nodiscard
|
---@nodiscard
|
||||||
---@param str string
|
---@param str string
|
||||||
---@param limit integer line limit, must be greater than 0
|
---@param limit integer line limit, must be greater than 0
|
||||||
---@return table lines
|
---@return string[] lines
|
||||||
function util.strwrap(str, limit)
|
function util.strwrap(str, limit)
|
||||||
assert(limit > 0, "util.strwrap() limit not greater than 0")
|
assert(limit > 0, "util.strwrap() limit not greater than 0")
|
||||||
return cc_strings.wrap(str, limit)
|
return cc_strings.wrap(str, limit)
|
||||||
@ -343,8 +343,9 @@ end
|
|||||||
|
|
||||||
-- delete elements from a table if the passed function returns false when passed a table element<br>
|
-- delete elements from a table if the passed function returns false when passed a table element<br>
|
||||||
-- put briefly: deletes elements that return false, keeps elements that return true
|
-- put briefly: deletes elements that return false, keeps elements that return true
|
||||||
---@param t table table to remove elements from
|
---@generic Type
|
||||||
---@param f function should return false to delete an element when passed the element: f(elem) = true|false
|
---@param t Type[] table to remove elements from
|
||||||
|
---@param f fun(t_elem: Type) : boolean should return false to delete an element when passed the element
|
||||||
---@param on_delete? function optional function to execute on deletion, passed the table element to be deleted as the parameter
|
---@param on_delete? function optional function to execute on deletion, passed the table element to be deleted as the parameter
|
||||||
function util.filter_table(t, f, on_delete)
|
function util.filter_table(t, f, on_delete)
|
||||||
local move_to = 1
|
local move_to = 1
|
||||||
@ -366,9 +367,10 @@ function util.filter_table(t, f, on_delete)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- check if a table contains the provided element
|
-- check if a table contains the provided element
|
||||||
|
---@generic Type
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
---@param t table table to check
|
---@param t Type[] table to check
|
||||||
---@param element any element to check for
|
---@param element Type element to check for
|
||||||
function util.table_contains(t, element)
|
function util.table_contains(t, element)
|
||||||
for i = 1, #t do
|
for i = 1, #t do
|
||||||
if t[i] == element then return true end
|
if t[i] == element then return true end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user