diff options
author | orwell <orwell@bleipb.de> | 2024-04-08 21:52:32 +0200 |
---|---|---|
committer | orwell <orwell@bleipb.de> | 2024-04-08 21:52:32 +0200 |
commit | 852da6bcaeeb8c39ce73639ef64f10ebc5b127b0 (patch) | |
tree | ebd944b0b8a763b63f128e7a7bf81882a4e8c29f /advtrains_interlocking/signal_aspect_accessors.lua | |
parent | 9fa43cb7bfc25ba71d16c8210f0074797a7bca1a (diff) | |
parent | 1f74697e85d456e97e201cdd9edef91a2df4fc14 (diff) | |
download | advtrains-852da6bcaeeb8c39ce73639ef64f10ebc5b127b0.tar.gz advtrains-852da6bcaeeb8c39ce73639ef64f10ebc5b127b0.tar.bz2 advtrains-852da6bcaeeb8c39ce73639ef64f10ebc5b127b0.zip |
Merge branch 'new-ks-orwell' into route_prog_rework
Diffstat (limited to 'advtrains_interlocking/signal_aspect_accessors.lua')
-rw-r--r-- | advtrains_interlocking/signal_aspect_accessors.lua | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/advtrains_interlocking/signal_aspect_accessors.lua b/advtrains_interlocking/signal_aspect_accessors.lua new file mode 100644 index 0000000..d91df31 --- /dev/null +++ b/advtrains_interlocking/signal_aspect_accessors.lua @@ -0,0 +1,163 @@ +--- Signal aspect accessors +-- @module advtrains.interlocking + +local A = advtrains.interlocking.aspect +local D = advtrains.distant +local I = advtrains.interlocking +local N = advtrains.ndb +local pts = advtrains.roundfloorpts + +local get_aspect + +local supposed_aspects = {} + +--- Replace the signal aspect cache. +-- @function load_supposed_aspects +-- @param db The new database. +function I.load_supposed_aspects(tbl) + if tbl then + supposed_aspects = {} + for k, v in pairs(tbl) do + supposed_aspects[k] = A(v) + end + end +end + +--- Retrieve the signal aspect cache. +-- @function save_supposed_aspects +-- @return The current database in use. +function I.save_supposed_aspects() + local t = {} + for k, v in pairs(supposed_aspects) do + t[k] = v:plain(true) + end + return t +end + +--- Read the aspect of a signal strictly from cache. +-- @param pos The position of the signal. +-- @return[1] The aspect of the signal (if present in cache). +-- @return[2] The nil constant (otherwise). +local function get_supposed_aspect(pos) + return supposed_aspects[pts(pos)] +end + +--- Update the signal aspect information in cache. +-- @param pos The position of the signal. +-- @param asp The new signal aspect +local function set_supposed_aspect(pos, asp) + supposed_aspects[pts(pos)] = asp +end + +--- Get the definition of a node. +-- @param pos The position of the node. +-- @return[1] The definition of the node (if present). +-- @return[2] An empty table (otherwise). +local function get_ndef(pos) + local node = N.get_node(pos) + return (minetest.registered_nodes[node.name] or {}), node +end + +--- Get the aspects supported by a signal. +-- @function signal_get_supported_aspects +-- @param pos The position of the signal. +-- @return[1] The table of supported aspects (if present). +-- @return[2] The nil constant (otherwise). +local function get_supported_aspects(pos) + local ndef = get_ndef(pos) + if ndef.advtrains and ndef.advtrains.supported_aspects then + return ndef.advtrains.supported_aspects + end + return nil +end + +--- Adjust a new signal aspect to fit a signal. +-- @param pos The position of the signal. +-- @param asp The new signal aspect. +-- @return The adjusted signal aspect. +-- @return The information to pass to the `advtrains.set_aspect` field in the node definitions. +local function adjust_aspect(pos, asp) + local asp = A(asp) + + local mainpos = D.get_main(pos) + local nxtasp + if mainpos then + nxtasp = get_aspect(mainpos) + end + local suppasp = get_supported_aspects(pos) + if not suppasp then + return asp + end + return asp:adjust_distant(nxtasp, suppasp.dst_shift):to_group(suppasp.group) +end + +--- Get the aspect of a signal without accessing the cache. +-- For most cases, `get_aspect` should be used instead. +-- @function signal_get_real_aspect +-- @param pos The position of the signal. +-- @return[1] The signal aspect adjusted using `adjust_aspect` (if present). +-- @return[2] The nil constant (otherwise). +local function get_real_aspect(pos) + local ndef, node = get_ndef(pos) + if ndef.advtrains and ndef.advtrains.get_aspect then + local asp = ndef.advtrains.get_aspect(pos, node) or I.DANGER + return adjust_aspect(pos, asp) + end + return nil +end + +--- Get the aspect of a signal. +-- @function signal_get_aspect +-- @param pos The position of the signal. +-- @return[1] The aspect of the signal (if present). +-- @return[2] The nil constant (otherwise). +get_aspect = function(pos) + local asp = get_supposed_aspect(pos) + if not asp then + asp = get_real_aspect(pos) + set_supposed_aspect(pos, asp) + end + return asp +end + +--- Set the aspect of a signal. +-- @function signal_set_aspect +-- @param pos The position of the signal. +-- @param asp The new signal aspect. +-- @param[opt=false] skipdst Whether to skip updating distant signals. +local function set_aspect(pos, asp, skipdst) + local node = N.get_node(pos) + local ndef = minetest.registered_nodes[node.name] + if ndef and ndef.advtrains and ndef.advtrains.set_aspect then + local oldasp = I.signal_get_aspect(pos) or DANGER + local newasp = adjust_aspect(pos, asp) + set_supposed_aspect(pos, newasp) + ndef.advtrains.set_aspect(pos, node, newasp) + I.signal_on_aspect_changed(pos) + local aspect_changed = oldasp ~= newasp + if (not skipdst) and aspect_changed then + D.update_main(pos) + end + end +end + +--- Remove a signal from cache. +-- @function signal_clear_aspect +-- @param pos The position of the signal. +local function clear_aspect(pos) + set_supposed_aspect(pos, nil) +end + +--- Readjust the aspect of a signal. +-- @function signal_readjust_aspect +-- @param pos The position of the signal. +local function readjust_aspect(pos) + set_aspect(pos, get_aspect(pos)) +end + +I.signal_get_supported_aspects = get_supported_aspects +I.signal_get_real_aspect = get_real_aspect +I.signal_get_aspect = get_aspect +I.signal_set_aspect = set_aspect +I.signal_clear_aspect = clear_aspect +I.signal_readjust_aspect = readjust_aspect |