diff --git a/MultiSchalten.lua b/MultiSchalten.lua new file mode 100644 index 0000000..3800122 --- /dev/null +++ b/MultiSchalten.lua @@ -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 diff --git a/README.md b/README.md index df2d5a9..60b1e9e 100755 --- a/README.md +++ b/README.md @@ -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. 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 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 -# RUS-Packet von Parry36 aktivieren +-- RUS-Packet von Parry36 aktivieren Main(inEEPMain) -# Zugtuersteuerung vom Fried aktivieren +-- Zugtuersteuerung vom Fried aktivieren Main(BewegeZugtueren) ```