Properly implement invalidate_all_paths, recheck lzb on aspect change
This commit is contained in:
parent
33c839b40d
commit
842a85606e
|
@ -208,7 +208,7 @@ function o.get_occupations(train, index)
|
||||||
return r, pos
|
return r, pos
|
||||||
end
|
end
|
||||||
-- Gets a mapping of train id's to indexes of trains that stand or drive over
|
-- Gets a mapping of train id's to indexes of trains that stand or drive over
|
||||||
-- returns (table with train_id->index), position
|
-- returns (table with train_id->index)
|
||||||
function o.get_trains_at(ppos)
|
function o.get_trains_at(ppos)
|
||||||
local pos = advtrains.round_vector_floor_y(ppos)
|
local pos = advtrains.round_vector_floor_y(ppos)
|
||||||
local t = occget(pos)
|
local t = occget(pos)
|
||||||
|
@ -226,4 +226,22 @@ function o.get_trains_at(ppos)
|
||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Gets a mapping of train id's to indexes of trains that have a path
|
||||||
|
-- generated over this node
|
||||||
|
-- returns (table with train_id->index)
|
||||||
|
function o.get_trains_over(ppos)
|
||||||
|
local pos = advtrains.round_vector_floor_y(ppos)
|
||||||
|
local t = occget(pos)
|
||||||
|
if not t then return {} end
|
||||||
|
local r = {}
|
||||||
|
local i = 1
|
||||||
|
while t[i] do
|
||||||
|
local train = advtrains.trains[t[i]]
|
||||||
|
local idx = t[i+1]
|
||||||
|
r[t[i]] = idx
|
||||||
|
i = i + 2
|
||||||
|
end
|
||||||
|
return r
|
||||||
|
end
|
||||||
|
|
||||||
advtrains.occ = o
|
advtrains.occ = o
|
||||||
|
|
|
@ -1037,26 +1037,23 @@ function advtrains.get_train_at_pos(pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- ehm... I never adapted this function to the new path system ?!
|
||||||
function advtrains.invalidate_all_paths(pos)
|
function advtrains.invalidate_all_paths(pos)
|
||||||
--if a position is given, only invalidate inside a radius to save performance
|
local tab
|
||||||
local inv_radius=50
|
if pos then
|
||||||
atprint("invalidating all paths")
|
-- if position given, check occupation system
|
||||||
for k,v in pairs(advtrains.trains) do
|
tab = advtrains.occ.get_trains_over(pos)
|
||||||
local exec=true
|
else
|
||||||
if pos and v.path and v.index and v.end_index then
|
tab = advtrains.trains
|
||||||
--start and end pos of the train
|
|
||||||
local cmp1=v.path[atround(v.index)]
|
|
||||||
local cmp2=v.path[atround(v.end_index)]
|
|
||||||
if vector.distance(pos, cmp1)>inv_radius and vector.distance(pos, cmp2)>inv_radius then
|
|
||||||
exec=false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if exec then
|
|
||||||
advtrains.invalidate_path(k)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for id, _ in pairs(tab) do
|
||||||
|
advtrains.invalidate_path(id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function advtrains.invalidate_path(id)
|
function advtrains.invalidate_path(id)
|
||||||
|
atdebug("Path invalidate:",id)
|
||||||
local v=advtrains.trains[id]
|
local v=advtrains.trains[id]
|
||||||
if not v then return end
|
if not v then return end
|
||||||
advtrains.path_invalidate(v)
|
advtrains.path_invalidate(v)
|
||||||
|
|
|
@ -105,6 +105,7 @@ local signal_assignments = {}
|
||||||
-- track+direction -> signal position
|
-- track+direction -> signal position
|
||||||
local influence_points = {}
|
local influence_points = {}
|
||||||
|
|
||||||
|
|
||||||
function ildb.load(data)
|
function ildb.load(data)
|
||||||
if not data then return end
|
if not data then return end
|
||||||
if data.tcbs then
|
if data.tcbs then
|
||||||
|
@ -119,6 +120,9 @@ function ildb.load(data)
|
||||||
if data.rs_locks then
|
if data.rs_locks then
|
||||||
advtrains.interlocking.route.rte_locks = data.rs_locks
|
advtrains.interlocking.route.rte_locks = data.rs_locks
|
||||||
end
|
end
|
||||||
|
if data.rs_callbacks then
|
||||||
|
advtrains.interlocking.route.rte_callbacks = data.rs_callbacks
|
||||||
|
end
|
||||||
if data.influence_points then
|
if data.influence_points then
|
||||||
influence_points = data.influence_points
|
influence_points = data.influence_points
|
||||||
end
|
end
|
||||||
|
@ -130,6 +134,7 @@ function ildb.save()
|
||||||
ts=track_sections,
|
ts=track_sections,
|
||||||
signalass = signal_assignments,
|
signalass = signal_assignments,
|
||||||
rs_locks = advtrains.interlocking.route.rte_locks,
|
rs_locks = advtrains.interlocking.route.rte_locks,
|
||||||
|
rs_callbacks = advtrains.interlocking.route.rte_callbacks,
|
||||||
influence_points = influence_points,
|
influence_points = influence_points,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -177,14 +177,22 @@ local function apply_control(id, train)
|
||||||
train.ctrl.lzb = nil
|
train.ctrl.lzb = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function invalidate(train)
|
||||||
advtrains.te_register_on_new_path(function(id, train)
|
|
||||||
train.lzb = {
|
train.lzb = {
|
||||||
trav = atfloor(train.index),
|
trav = atfloor(train.index),
|
||||||
travsht = train.is_shunt,
|
travsht = train.is_shunt,
|
||||||
oncoming = {}
|
oncoming = {}
|
||||||
}
|
}
|
||||||
train.ctrl.lzb = nil
|
train.ctrl.lzb = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function advtrains.interlocking.lzb_invalidate(train)
|
||||||
|
invalidate(train)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
advtrains.te_register_on_new_path(function(id, train)
|
||||||
|
invalidate(train)
|
||||||
look_ahead(id, train)
|
look_ahead(id, train)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
|
@ -66,9 +66,10 @@ advtrains = {
|
||||||
|
|
||||||
-- The aspect passed in here can always be queried using the
|
-- The aspect passed in here can always be queried using the
|
||||||
-- advtrains.interlocking.signal_get_supposed_aspect(pos) function.
|
-- advtrains.interlocking.signal_get_supposed_aspect(pos) function.
|
||||||
|
-- It is always DANGER when the signal is not used as route signal.
|
||||||
|
|
||||||
-- For static signals, this function should be completely omitted
|
-- For static signals, this function should be completely omitted
|
||||||
-- If this function is ommitted, it won't be possible to use
|
-- If this function is omitted, it won't be possible to use
|
||||||
-- route setting on this signal.
|
-- route setting on this signal.
|
||||||
end
|
end
|
||||||
function get_aspect(pos, node)
|
function get_aspect(pos, node)
|
||||||
|
@ -89,6 +90,18 @@ after_dig_node = advtrains.interlocking.signal_after_dig
|
||||||
|
|
||||||
(If you need to specify custom can_dig or after_dig_node callbacks,
|
(If you need to specify custom can_dig or after_dig_node callbacks,
|
||||||
please call those functions anyway!)
|
please call those functions anyway!)
|
||||||
|
|
||||||
|
Important note: If your signal should support external ways to set its
|
||||||
|
aspect (e.g. via mesecons), there are some things that need to be considered:
|
||||||
|
- advtrains.interlocking.signal_get_supposed_aspect(pos) won't respect this
|
||||||
|
- Whenever you change the signal aspect, and that aspect change
|
||||||
|
did not happen through a call to
|
||||||
|
advtrains.interlocking.signal_set_aspect(pos, asp), you are
|
||||||
|
*required* to call this function:
|
||||||
|
advtrains.interlocking.signal_on_aspect_changed(pos)
|
||||||
|
in order to notify trains about the aspect change.
|
||||||
|
This function will query get_aspect to retrieve the new aspect.
|
||||||
|
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
local DANGER = {
|
local DANGER = {
|
||||||
|
@ -128,6 +141,22 @@ function advtrains.interlocking.signal_set_aspect(pos, asp)
|
||||||
local ndef=minetest.registered_nodes[node.name]
|
local ndef=minetest.registered_nodes[node.name]
|
||||||
if ndef and ndef.advtrains and ndef.advtrains.set_aspect then
|
if ndef and ndef.advtrains and ndef.advtrains.set_aspect then
|
||||||
ndef.advtrains.set_aspect(pos, node, asp)
|
ndef.advtrains.set_aspect(pos, node, asp)
|
||||||
|
advtrains.interlocking.signal_on_aspect_changed(pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- should be called when aspect has changed on this signal.
|
||||||
|
function advtrains.interlocking.signal_on_aspect_changed(pos)
|
||||||
|
local ipts, iconn = advtrains.interlocking.db.get_ip_by_signalpos(pos)
|
||||||
|
if not ipts then return end
|
||||||
|
local ipos = minetest.string_to_pos(ipts)
|
||||||
|
|
||||||
|
local tns = advtrains.occ.get_trains_over(ipos)
|
||||||
|
for id, sidx in pairs(tns) do
|
||||||
|
local train = advtrains.trains[id]
|
||||||
|
if train.index <= sidx then
|
||||||
|
advtrains.interlocking.lzb_invalidate(train)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue