aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authororwell <orwell@bleipb.de>2024-02-06 21:10:40 +0100
committerorwell <orwell@bleipb.de>2024-02-06 21:10:40 +0100
commit2dab59f05572fe6cf73cde353446a5a501550b41 (patch)
tree9fb16d4b7cbf9f6752391cd0f32a63c0ec48cc2b
parentaa9033f9010b01e7ad28f2b8bb0c002f065ddc08 (diff)
downloadadvtrains-2dab59f05572fe6cf73cde353446a5a501550b41.tar.gz
advtrains-2dab59f05572fe6cf73cde353446a5a501550b41.tar.bz2
advtrains-2dab59f05572fe6cf73cde353446a5a501550b41.zip
Start changing APIs and applying proof-of-concept to ks signals
-rw-r--r--advtrains_interlocking/init.lua2
-rw-r--r--advtrains_interlocking/signal_api.lua105
-rwxr-xr-xadvtrains_signals_ks/init.lua138
3 files changed, 156 insertions, 89 deletions
diff --git a/advtrains_interlocking/init.lua b/advtrains_interlocking/init.lua
index 4d959cc..9aa0c06 100644
--- a/advtrains_interlocking/init.lua
+++ b/advtrains_interlocking/init.lua
@@ -12,7 +12,7 @@ end
local modpath = minetest.get_modpath(minetest.get_current_modname()) .. DIR_DELIM
-advtrains.interlocking.aspect = dofile(modpath.."aspect.lua")
+--advtrains.interlocking.aspect = dofile(modpath.."aspect.lua")
dofile(modpath.."database.lua")
dofile(modpath.."distant.lua")
diff --git a/advtrains_interlocking/signal_api.lua b/advtrains_interlocking/signal_api.lua
index 743e8e1..c2cc08b 100644
--- a/advtrains_interlocking/signal_api.lua
+++ b/advtrains_interlocking/signal_api.lua
@@ -2,18 +2,19 @@
local F = advtrains.formspec
-local DANGER = {
- main = 0,
- shunt = false,
+local signal = {}
+
+signal.MASP_HALT = {
+ name = "halt"
+ halt = true,
}
-advtrains.interlocking.DANGER = DANGER
-advtrains.interlocking.GENERIC_FREE = {
- main = -1,
+signal.ASPI_HALT = {
+ main = 0,
shunt = false,
- dst = false,
}
-advtrains.interlocking.FULL_FREE = {
+
+signal.ASPI_FREE = {
main = -1,
shunt = false,
proceed_as_main = true,
@@ -25,14 +26,12 @@ Most parts of ywang's implementation are fine, especially I like the formspecs.
- Signal gets distant assigned via field in signal aspect table (instead of explicitly)
- Signal speed/shunt are no longer free-text but rather they need to be predefined in the node definition
To do this: Differentiation between:
-== Aspect Group ==
+== Main Aspect ==
This is what a signal is assigned by either the route system or the user.
It is a string key which has an appropriate entry in the node definition (where it has a description assigned)
The signal mod defines a function to set a signal to the most appropriate aspect. This function gets
-a) the aspect group name
+a) the main aspect table (straight from node def)
b) the distant signal's aspect group name & aspect table
-EVERY signal must define the special aspect group "halt". This must always be the most restrictive aspect possible.
-The "halt" aspect group should ignore any distant info, in most cases it is called without them anyway.
== Aspect ==
One concrete combination of lights/shapes that a signal signal shows. Handling these is at the discretion of
@@ -50,6 +49,11 @@ Note that once apply_aspect returns, there is no need for advtrains anymore to q
When the signal, for any reason, wants to change its aspect by itself *without* going through the signal API then
it should update the aspect info cache by calling advtrains.interlocking.signal.update_aspect_info(pos)
+Note that the apply_aspect function MUST accept the following main aspect, even if it is not defined in the main_aspects table:
+{ name = "halt", halt = true }
+It should cause the signal to show its most restrictive aspect. Typically it is a halt aspect, but e.g. for distant-only
+signals this would be "expect stop".
+
== Aspect Info ==
The actual signal aspect in the already-known format. This is what the trains use to determine halt/proceed and speed. In this, the dst field has to be resolved.
asp = {
@@ -62,7 +66,10 @@ asp = {
Node definition of signals:
- The signal needs some logic to figure out, for each combination of its own aspect group and the distant signal's aspect, what aspect info it can/will show.
ndef.advtrains = {
- aspect_groups = { [name] = { description = "Proceed at full speed", <more data at discretion of signal>} }
+ main_aspects = {
+ { name = "proceed" description = "Proceed at full speed", <more data at discretion of signal>}
+ { name = "proceed2" description = "Proceed at full speed", <more data at discretion of signal>}
+ } -- The numerical order determines the layout of the list in the selection dialog.
apply_aspect = function(pos, asp_group, dst_aspgrp, dst_aspinfo)
-- set the node to show the desired aspect
-- called by advtrains when this signal's aspect group or the distant signal's aspect changes
@@ -72,28 +79,61 @@ ndef.advtrains = {
}
]]
-advtrains.interlocking.signal_convert_aspect_if_necessary = advtrains.interlocking.aspect
+-- Set a signal's aspect.
+-- Signal aspects should only be set through this function. It takes care of:
+-- - Storing the main aspect and dst pos for this signal permanently (until next change)
+-- - Assigning the distant signal for this signal
+-- - Calling apply_aspect() in the signal's node definition to make the signal show the aspect
+-- - Calling apply_aspect() again whenever the distant signal changes its aspect
+-- - Notifying this signal's distant signals about changes to this signal (unless skip_dst_notify is specified)
+function signal.set_aspect(pos, main_aspect, dst_pos, skip_dst_notify)
+ -- TODO
+end
+
+-- Gets the stored main aspect and distant signal position for this signal
+-- This information equals the information last passed to set_aspect
+-- It does not take into consideration the actual speed signalling, please use
+-- get_aspect_info() for this
+-- returns: main_aspect, dst_pos
+function signal.get_aspect(pos)
+ --TODO
+end
+
+function signal.get_distant_signals_of(pos)
+ --TODO
+end
-function advtrains.interlocking.update_signal_aspect(tcbs, skipdst)
+-- Called when either this signal has changed its main aspect
+-- or when this distant signal's currently assigned main signal has changed its aspect
+-- It retrieves the signal's main aspect and aspect info and calls apply_aspect of the node definition
+-- to update the signal's appearance and aspect info
+-- pts: The signal position to update as encoded_pos
+function signal.reapply_aspect(pts, p_mainaspect)
+ --TODO
+end
+
+-- Update this signal's aspect based on the set route
+--
+function signal.update_route_aspect(tcbs, skip_dst_notify)
if tcbs.signal then
- local asp = tcbs.aspect or DANGER
- advtrains.interlocking.signal_set_aspect(tcbs.signal, asp, skipdst)
+ local asp = tcbs.aspect or signal.MASP_HALT
+ signal.set_aspect(tcbs.signal, asp, skip_dst_notify)
end
end
-function advtrains.interlocking.signal_can_dig(pos)
+function signal.can_dig(pos)
return not advtrains.interlocking.db.get_sigd_for_signal(pos)
end
function advtrains.interlocking.signal_after_dig(pos)
-- clear influence point
-
advtrains.interlocking.signal_clear_aspect(pos)
- advtrains.distant.unassign_all(pos, true)
+ advtrains.distant.unassign_all(pos, true) -- TODO
end
--- should be called when aspect has changed on this signal.
-function advtrains.interlocking.signal_on_aspect_changed(pos)
+-- Update waiting trains and distant signals about a changed signal aspect
+function signal.notify_on_aspect_changed(pos, skip_dst_notify)
+ --TODO update distant?
local ipts, iconn = advtrains.interlocking.db.get_ip_by_signalpos(pos)
if not ipts then return end
local ipos = minetest.string_to_pos(ipts)
@@ -103,7 +143,7 @@ function advtrains.interlocking.signal_on_aspect_changed(pos)
minetest.after(0, advtrains.invalidate_all_paths, ipos)
end
-function advtrains.interlocking.signal_rc_handler(pos, node, player, itemstack, pointed_thing)
+function signal.on_rightclick(pos, node, player, itemstack, pointed_thing)
local pname = player:get_player_name()
local control = player:get_player_control()
if control.aux1 then
@@ -122,7 +162,7 @@ function advtrains.interlocking.show_signal_form(pos, node, pname)
if ndef.advtrains and ndef.advtrains.set_aspect then
-- permit to set aspect manually
local function callback(pname, aspect)
- advtrains.interlocking.signal_set_aspect(pos, aspect)
+ signal.set_aspect(pos, aspect)
end
local isasp = advtrains.interlocking.signal_get_aspect(pos, node)
@@ -138,18 +178,6 @@ function advtrains.interlocking.show_signal_form(pos, node, pname)
end
end
--- Returns the aspect the signal at pos is supposed to show
-function advtrains.interlocking.signal_get_supposed_aspect(pos)
- local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos)
- if sigd then
- local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
- if tcbs.aspect then
- return convert_aspect_if_necessary(tcbs.aspect)
- end
- end
- return DANGER;
-end
-
local players_assign_ip = {}
local function ipmarker(ipos, connid)
@@ -236,7 +264,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end)
-- inits the signal IP assignment process
-function advtrains.interlocking.signal_init_ip_assign(pos, pname)
+function signal.init_ip_assign(pos, pname)
if not minetest.check_player_privs(pname, "interlocking") then
minetest.chat_send_player(pname, "Insufficient privileges to use this!")
return
@@ -281,3 +309,6 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
players_assign_ip[pname] = nil
end
end)
+
+
+advtrains.interlocking.signal = signal
diff --git a/advtrains_signals_ks/init.lua b/advtrains_signals_ks/init.lua
index 7e285ae..c91b4ec 100755
--- a/advtrains_signals_ks/init.lua
+++ b/advtrains_signals_ks/init.lua
@@ -11,10 +11,9 @@ local function asp_to_zs3type(asp)
return math.min(16,4*math.floor(n/4))
end
-local function setzs3(msp, lim, rot)
+local function setzs3(msp, asp, rot)
local pos = {x = msp.x, y = msp.y+1, z = msp.z}
local node = advtrains.ndb.get_node(pos)
- local asp = asp_to_zs3type(lim)
if node.name:find("^advtrains_signals_ks:zs3_") then
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:zs3_"..asp.."_"..rot, param2 = node.param2})
end
@@ -50,67 +49,106 @@ local function getzs3v(msp)
end
local setaspectf = function(rot)
- return function(pos, node, asp)
- setzs3(pos, asp.main, rot)
- if asp.main == 0 then
- if asp.shunt then
- advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_shunt_"..rot, param2 = node.param2})
- else
- advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_danger_"..rot, param2 = node.param2})
- end
+ return function(pos, node, main_aspect, dst_aspect, dst_aspect_info)
+ -- set zs3 signal to show speed according to main_aspect
+ setzs3(pos, asp.zs3, rot)
+ -- select appropriate lamps based on mainaspect and dst
+ if main_aspect.shunt then
+ advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_shunt_"..rot, param2 = node.param2})
+ setzs3v(pos, nil, rot)
+ elseif main_aspect.halt then
+ advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_danger_"..rot, param2 = node.param2})
setzs3v(pos, nil, rot)
else
- if not asp.dst or asp.dst == -1 then
+ if not dst_aspect_info
+ or not dst_aspect_info.main
+ or dst_aspect_info.main == -1 then
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_free_"..rot, param2 = node.param2})
- elseif asp.dst == 0 then
+ setzs3v(pos, nil, rot)
+ elseif dst_aspect_info.main == 0 then
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_slow_"..rot, param2 = node.param2})
+ setzs3v(pos, nil, rot)
else
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_nextslow_"..rot, param2 = node.param2})
+ setzs3v(pos, dst_aspect_info.main, rot)
end
- setzs3v(pos, asp.dst, rot)
end
end
end
-
-local suppasp = {
- main = {0, 4, 6, 8, 12, 16, -1},
- dst = {0, 4, 6, 8, 12, 16, -1, false},
- shunt = nil,
- proceed_as_main = true,
- info = {
- call_on = false,
- dead_end = false,
- w_speed = nil,
- }
+-- Main aspects main signal
+-- These aspects tell only the speed signalization at this signal.
+-- Actual signal aspect is chosen based on this and the Dst signal.
+local mainaspects_main = {
+ {
+ name = "proceed"
+ description = "Proceed",
+ zs3 = "off"
+ },
+ {
+ name = "shunt"
+ description = "Shunt",
+ zs3 = "off",
+ shunt = true,
+ },
+ {
+ name = "proceed_16"
+ description = "Proceed (speed 16)",
+ zs3 = "16",
+ },
+ {
+ name = "proceed_12"
+ description = "Proceed (speed 12)",
+ zs3 = "12",
+ },
+ {
+ name = "proceed_8"
+ description = "Proceed (speed 8)",
+ zs3 = "8",
+ },
+ {
+ name = "proceed_6"
+ description = "Proceed (speed 6)",
+ zs3 = "6",
+ },
+ {
+ name = "proceed_4"
+ description = "Proceed (speed 4)",
+ zs3 = "4",
+ },
+ {
+ name = "halt"
+ description = "Halt",
+ zs3 = "off",
+ halt = true,
+ },
}
--Rangiersignal
-local setaspectf_ra = function(rot)
- return function(pos, node, asp)
- if asp.shunt then
+local applyaspectf_ra = function(rot)
+ -- we get here the full main_aspect table
+ return function(pos, node, main_aspect, dst_aspect, dst_aspect_info)
+ if main_aspect.shunt then
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:ra_shuntd_"..rot, param2 = node.param2})
else
advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:ra_danger_"..rot, param2 = node.param2})
end
- local meta = minetest.get_meta(pos)
- if meta then
- meta:set_string("infotext", minetest.serialize(asp))
- end
end
end
-local suppasp_ra = {
- main = { false },
- dst = { false },
- shunt = nil,
- proceed_as_main = false,
-
- info = {
- call_on = false,
- dead_end = false,
- w_speed = nil,
- }
+-- Main aspects shunt signal
+-- Shunt signals have only two states, distant doesn't matter
+local mainaspects_shunt = {
+ {
+ name = "shunt"
+ description = "Shunt",
+ shunt = true,
+ },
+ {
+ name = "halt"
+ description = "Halt",
+ halt = true,
+ },
}
advtrains.trackplacer.register_tracktype("advtrains_signals_ks:hs")
@@ -192,9 +230,9 @@ for _, rtab in ipairs({
drop = "advtrains_signals_ks:hs_danger_0",
inventory_image = "advtrains_signals_ks_hs_inv.png",
advtrains = {
- set_aspect = setaspectf(rot),
- supported_aspects = suppasp,
- get_aspect = afunc,
+ main_aspects = mainaspects_main
+ apply_aspect = applyaspectf_main(rot),
+ get_aspect_info = afunc,
},
on_rightclick = advtrains.interlocking.signal_rc_handler,
can_dig = advtrains.interlocking.signal_can_dig,
@@ -235,11 +273,9 @@ for _, rtab in ipairs({
drop = "advtrains_signals_ks:ra_danger_0",
inventory_image = "advtrains_signals_ks_ra_inv.png",
advtrains = {
- set_aspect = setaspectf_ra(rot),
- supported_aspects = suppasp_ra,
- get_aspect = function(pos, node)
- return prts.asp
- end,
+ main_aspects = mainaspects_ra,
+ apply_aspect = applyaspectf_ra(rot),
+ get_aspect_info = prts.asp,
},
on_rightclick = advtrains.interlocking.signal_rc_handler,
can_dig = advtrains.interlocking.signal_can_dig,
@@ -276,7 +312,7 @@ for _, rtab in ipairs({
drop = "advtrains_signals_ks:"..prefix.."_"..dtyp.."_0",
inventory_image = inv,
advtrains = {
- get_aspect = function() return asp end
+ get_aspect_info = asp
},
on_rightclick = advtrains.interlocking.signal_rc_handler,
can_dig = advtrains.interlocking.signal_can_dig,