MultiSchalten Modul für komplexere Signalverknüpfungen

This commit is contained in:
Nero 2023-07-21 22:54:14 +00:00
parent 52d1143fd4
commit b475984433
2 changed files with 118 additions and 2 deletions

73
MultiSchalten.lua Normal file
View File

@ -0,0 +1,73 @@
require("kskit\\On")
-- Die Indice der Schaltverbindungen, welche eben einen Callback reinbekommen haben und geprueft werden muessen
local IndexGeaendert={}
-- Die Tabelle mit den Schaltverbindungen, die wir vom User bekommen haben
local SchaltenTabelle={}
-- Ausgabefunktion, dummy
-- Wenn Ausgabe gewuenscht, mit MultiSchaltenMelden=print ueberschreiben
function MultiSchaltenMelden(...)
end
-- Fuer jedes Dann-Element in der Tabelle registrieren wir einen Callback
-- Dank des On-Modules koennen mehrere Zeilen einen Callback auf das selbe Signal oder Weiche eintragen
function MultiSchaltenInit(Tabelle)
SchaltenTabelle=Tabelle
for k, Eintrag in pairs(Tabelle) do
-- Grobe Fehlerueberpruefung
assert(#Eintrag.Wenn % 2 == 0, "Eintrag "..k..": Wenn-Liste muss eine gerade Anzahl Elemente haben")
assert(#Eintrag.Dann % 2 == 0, "Eintrag "..k..": Dann-Liste muss eine gerade Anzahl Elemente haben")
-- Fuer jede ID in der Liste einen Callback erstellen
for i=1,#Eintrag.Wenn,2 do
local ID=Eintrag.Wenn[i]
if EEPGetSignal(ID) > 0 then
OnSignal(ID, function()
-- Hier merken wir uns den Index unserer Zeile, das wir das von der Main aus ueberpruefen
IndexGeaendert[k]=true
end)
elseif EEPGetSwitch(ID) > 0 then
OnSwitch(ID, function()
IndexGeaendert[k]=true
end)
else
error("ID "..tostring(ID).." ist nicht vergeben")
end
end
end
end
-- Eingegangene Callbacks auswerten
function MultiSchaltenMain()
-- Nur die Zeilen auswerten, fuer die eben ein Callback eingegangen ist
for k, _ in pairs(IndexGeaendert) do
local Eintrag=SchaltenTabelle[k]
local BedingungErfuellt=true
-- Die Bedingungen durchgehen
for i=1,#Eintrag.Wenn,2 do
local ID=Eintrag.Wenn[i]
local Soll=Eintrag.Wenn[i+1]
-- Sowohl Signal als auch Switch abfragen, wir wissen ja nicht ob die ID ein Signal oder Weiche ist
if EEPGetSignal(ID) ~= Soll and EEPGetSwitch(ID) ~= Soll then
MultiSchaltenMelden("MultiSchalten "..tostring(k)..": ",ID," ist nicht ",Soll)
BedingungErfuellt=false
end
end
-- Die Folgen durchgehen
if BedingungErfuellt then
for i=1,#Eintrag.Dann,2 do
local ID=Eintrag.Dann[i]
local Soll=Eintrag.Dann[i+1]
if EEPGetSignal(ID) > 0 then
MultiSchaltenMelden("MultiSchalten "..tostring(k)..": Signal ",ID," auf ",Soll)
EEPSetSignal(ID, Soll, 1)
else
MultiSchaltenMelden("MultiSchalten "..tostring(k)..": Weiche ",ID," auf ",Soll)
EEPSetSwitch(ID, Soll, 1)
end
end
end
end
-- Gemerkte Callbacks loeschen
IndexGeaendert={}
end

View File

@ -13,6 +13,49 @@ Es ist auch immer dazugeschrieben, welche Vorraussetzungen man braucht.
Alle Scripte können [hier](https://github.com/nero/kskit/archive/refs/heads/master.zip) als Zip-Datei heruntergeladen werden, die lässt sich dann wie ein Modell installieren. Alle Scripte können [hier](https://github.com/nero/kskit/archive/refs/heads/master.zip) als Zip-Datei heruntergeladen werden, die lässt sich dann wie ein Modell installieren.
Die Scripte werden unterhalb vom LUA-Ordner im EEP-Stammverzeichnis installiert. Die Scripte werden unterhalb vom LUA-Ordner im EEP-Stammverzeichnis installiert.
## MultiSchalten: Signalverknüpfung mit mehreren Bedingungen
Bei der Verwendung der Ks-Signale von GK3 hatte ich schnell das Problem, das ich keine Ansteuerung für die Mehrabschnittssignale hatte.
MA-Signale haben neben der Hauptsignalfunktion noch eine Vorsignalfunktion.
In einer Fahrstrasse nehme ich das MA-Signal in der Stellung "Halt erwarten" auf, mitsamt eventuellen Geschwindigkeits-Zusatzanzeigern.
Wenn das Folgesignal dann von Halt auf Fahrt springt, UND das MA-Signal nicht bereits wieder Halt zeigt, nur dann soll es von Halt erwarten auf Fahrt umgestellt werden können.
Mit den klassischen Signalverknüpfungen ist die Abfrage von diesen zwei Bedingungen nicht möglich.
Daher habe ich eine Lua-basierte Signalverknüpfung geschrieben, die mehrere Bedingungen abfragen kann.
Die Verknüpfungen werden dabei in einer Tabelle eingetragen.
Jede Zeile in der Tabelle hat dabei zwei gleichartige Listen.
Die Listen beinhalten jeweils die ID und die Stellung eines Signals, jeweils abwechselnd.
Anstelle von Signalen können auch Weichen eingetragen werden.
In der `Wenn`-Liste werden die Bedigungen eingetragen, sie müssen alle erfüllt sein, damit die Zeile Wirkung zeigt.
In der `Dann`-Liste werden alle zu stellenden Signale und Weichen eingetragen.
```
require("kskit\\MultiSchalten")
Schalten={
-- 73 ist unser MA-Signal, 2=Halt erwarten, 3=Fahrt
-- 16 ist das Folgesignal, 2=Fahrt
{Wenn={16,2,73,2}, Dann={73,3}},
-- 1073 und 2073 sind Zusatzanzeiger, wenn wir auf Rot (1) gehen müssen die aus
{Wenn={73,1}, Dann={1073,1,2073,1}}
}
MultiSchaltenInit(Schalten)
function EEPMain()
MultiSchaltenMain()
return 1
end
```
Die Ausführung erfolgt einmalig nach dem Eintreffen der jeweiligen Callbacks.
Zum das Anlegen der Callbacks wird das `On`-Modul (folgend) verwendet.
Ist ein Signal oder Weiche als Bedingung in der MultiSchalten-Tabelle eingetragen, darf dazu keine `EEPOnSignal_`-Funktion definiert werden!
Es sind die OnSignal/OnSwitch-Funktionen des `On`-Moduls stattdessen zu benutzen.
## Serializer: Tabellen in EEP-Slots speichern ## Serializer: Tabellen in EEP-Slots speichern
Die Lua-Umgebung wird von EEP in bestimmten Situationen zurückgesetzt und verliert dabei die Inhalte aller Variablen. Die Lua-Umgebung wird von EEP in bestimmten Situationen zurückgesetzt und verliert dabei die Inhalte aller Variablen.
@ -224,9 +267,9 @@ require("Zugtuersteuerung_FS2.lua")
-- Definitionen für RUS-Packet hier -- Definitionen für RUS-Packet hier
# RUS-Packet von Parry36 aktivieren -- RUS-Packet von Parry36 aktivieren
Main(inEEPMain) Main(inEEPMain)
# Zugtuersteuerung vom Fried aktivieren -- Zugtuersteuerung vom Fried aktivieren
Main(BewegeZugtueren) Main(BewegeZugtueren)
``` ```