kskit/Fahrstrassen.lua

138 lines
5.0 KiB
Lua

require("kskit\\Serializer")
require("kskit\\On")
local Anmeldungen={}
local Dirty=false
local function IstIn(Tabelle, Wert)
for _, v in ipairs(Tabelle) do
if v == Wert then return true end
end
return false
end
function FahrstrassenMelden(...)
end
function FahrstrassenInit(Slot)
Anmeldungen = ladeTabelle(Slot) or {}
Main(function()
-- Anmeldungen abarbeiten
for Zugname, Anmeldung in pairs(Anmeldungen) do
-- Freigefahrene Fahrstrassen aus Belegtliste entfernen
while Anmeldung[3][1] and EEPGetSignal(Anmeldung[3][1]) == 1 do
table.remove(Anmeldung[3], 1)
Dirty=true
end
-- Haben wir es im letzten Zyklus zu schalten versucht und ist jetzt etwas eingestellt?
if Anmeldung[2] > 0 and EEPGetSignal(Anmeldung[2]) > 1 then
local FStartIst=Anmeldung[2]
local FZielIst=EEPGetSignal(FStartIst)-1
local FStartSoll=table.remove(Anmeldung[1], 1)
local FZielSoll=table.remove(Anmeldung[1], 1)
-- Erfolg vermelden!
FahrstrassenMelden("Fahrt ",Zugname," ueber ",serialize{FStartIst,FZielIst})
if FStartIst ~= FStartSoll or FZielIst ~= FZielSoll then
-- Was ist hier passiert. Wir haben gerade eine Fahrstrasse geschaltet, die nicht gefordert war.
-- Das kann passieren, wenn eine wiederholte Anmeldung kurz vor uns das Fahrstrassenziel umgestellt hat
FahrstrassenMelden("Fehlschlag Schalten ",Zugname," an ",serialize(Anmeldung[1]),": alternative Fahrstrasse bereits geschaltet")
-- Die Anmeldung passt jetzt nicht mehr, weil wir fahren ja schon woanders hin
Anmeldung[1]={}
end
Anmeldung[2]=0
-- Fahrstrassen Startsignal als belegt (durch uns) markieren
table.insert(Anmeldung[3], FStartIst)
Dirty=true
end
-- Prüfung, das es den Zug überhaupt noch gibt
-- Das passiert nachdem wir das Fahrstrassensignal auf erfolgreiche Schaltung geprüft haben
-- War sie erfolgreich und der Zug ist jetzt weg, ist sie in der Belegtliste schon drin
local ok, Speed = EEPGetTrainSpeed(Zugname)
if not ok then
Anmeldungen[Zugname]=nil
Dirty=true
-- Durch den Zug belegte Fahrstrassen auflösen
for _, FStart in ipairs(Anmeldung[3]) do
if EEPGetSignal(FStart) > 1 then
EEPSetSignal(FStart, 1, 1)
FahrstrassenMelden("FS ",FStart," hilfsweise aufgeloest, ",Zugname," verschollen")
end
end
-- Abbrechen, wir brauchen für den Zug nix mehr zu schalten
break
end
-- Wenn noch eine Anmeldung vorhanden und FS-Signal aufgelöst ist, dann versuchen wir zu schalten
local FSignal = 0
if Anmeldung[1][1] and EEPGetSignal(Anmeldung[1][1]) == 1 then
FSignal=Anmeldung[1][1]
EEPSetSignal(FSignal, Anmeldung[1][2] + 1, 1)
end
-- Und uns merken, das wir einen Schaltversuch unternommen haben
-- In FSignal steht noch eine 0 drin, falls die FS noch durch anderen Zug geschaltet ist
if Anmeldung[2] ~= FSignal then Dirty = true end
Anmeldung[2]=FSignal
-- Wenn wir alles abgearbeitet haben, können wir den Zug auch vergessen
if #Anmeldung[1]==0 and #Anmeldung[3]==0 then
Anmeldungen[Zugname]=nil
Dirty=true
end
end
-- Hat sich was geändert? Anmeldungen wegspeichern!
if Dirty then
speicherTabelle(Slot, Anmeldungen)
Dirty=false
end
end)
end
function FahrstrassenDebug()
r=""
for Zugname, Anmeldung in pairs(Anmeldungen) do
r=r..Zugname..":Angemeldet="..serialize(Anmeldung[1])..",InArbeit="..serialize(Anmeldung[2])..",Geschaltet="..serialize(Anmeldung[3]).."\n"
end
return r
end
function FS(Zugname, ...)
local Route = {...}
if #Route % 2 ~= 0 then
error("FS() hat immer eine ungerade Anzahl von Argumenten")
end
if Anmeldungen[Zugname] == nil then
Anmeldungen[Zugname] = {{},0,{}}
end
local Anmeldung = Anmeldungen[Zugname]
while Route[1] do
-- Ist die Anmeldung noch nicht Teil unserer belegtliste, alles ok und weitermachen
if not IstIn(Anmeldung[3], Route[1]) then
break
end
-- Die Fahrstrasse ist bereits geschalten, mist!
-- Ist sie in der richtigen Stellung?
if Route[2] == EEPGetSignal(Route[1]) - 1 then
-- Ja! Alles gut. Dieser Teil der Anmeldung wird ignoriert
FahrstrassenMelden("Anmeldung ",Zugname," an ",serialize{Route[1],Route[2]}," wiederholt")
table.remove(Route, 1)
table.remove(Route, 1)
else
-- Wenn das Ziel auch noch falsch ist, komplette Anmeldung verwerfen, wir fahren jetzt schon woanders hin
FahrstrassenMelden("Fehlschlag ",Zugname," an ",serialize(Route),": alternative Fahrstrasse bereits geschaltet")
return
end
end
-- Wenn von unserer Anmeldung jetzt nix mehr übrig ist, brauchen wir auch nichts zu machen
if #Route == 0 then return end
-- Anmeldung durchführen
FahrstrassenMelden("Anmeldung ",Zugname," an ",serialize(Route))
Anmeldung[1]=Route
Dirty = true
end