diff --git a/README.md b/README.md index 60b1e9e..a1b129a 100755 --- a/README.md +++ b/README.md @@ -13,48 +13,152 @@ 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 +## On-Modul -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. +Bisher konnte an jedes Signal oder Weiche nur ein Callback gebunden werden. +Das ist kein Problem, wenn man das Anlagenscript komplett selber schreibt. +Sobald man aber mehrere Module hat, welche unabhängig voneinander Callbacks definieren, braucht man einen Mechanismus, um die alle unter einen Hut zu kriegen. -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. +Als Lösung dafür erfolgt mit dem `On`-Modul ein Paradigmenwechsel. +Anstelle den Callback direkt als Funktion zu definieren, wird der Callbackname und eine anonyme Funktion an das Modul übergeben. -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. +Die bisherige Syntax für Callbacks und die EEPMain sah wie folgt aus: ``` -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) +EEPRegisterSignal(5) +function EEPOnSignal_5(Stellung) + ... +end function EEPMain() - MultiSchaltenMain() - return 1 + ... end ``` -Die Ausführung erfolgt einmalig nach dem Eintreffen der jeweiligen Callbacks. +Die Verwendung des On-Modules erfordert eine andere Syntax. -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. +``` +require("kskit\\On") + +OnSignal(5, function(Stellung) + ... +end) + +Main(function() + ... +end) +``` + +Die Callback-Funktion wird nicht mehr auf der globalen Ebene definiert, sondern als Argument an eine andere Funktion übergeben. +Daher auch die sich schließende Klammer nach dem `end` - sie schließt den Funktionsaufruf von OnSignal/Main ab. + +Das ist umständlich, das ist ungewohnt, ermöglicht aber einige Vorteile: + +- Die On-Funktionen können mehrmals aufgerufen werden, mehrere Funktionen an einem EEP Callback sind kein Problem +- Module können unabhängig voneinander Code durch einen Callback ausführen lassen +- Module können unabhängig voneinander ihre eigene EEPMain definieren + +Ebenfalls werden zwei größere Fehlerquellen ausgeschlossen: + +- Der Aufruf von EEPRegisterSignal/EEPRegisterSwitch wird vom `On`-Module automatisch gemacht +- Bei dem Anlegen von Signal/Weichencallbacks wird die Existenz dieser Objekte überprüft + +Zum Beispiel können eine Vorsignalsteuerung und eine Türsteuerung beide einen Callback auf das Abfahrtssignal registrieren, ohne voneinander zu wissen zu müssen. + +### On + +So wie das Modul heisst auch die zentrale Funktion. +Diese registriert eine Funktion für einen EEP-Callback. +Das Anlegen der Callback-Funktion wird bei dem Registrieren der ersten Funktion vorgenommen. +Dabei wird, falls notwendig, der Callback von `On` auch bei EEP registriert. +Das händische Aufrufen von `EEPRegister*` entfällt! + +Als erster Parameter wird dabei der Name des Callbacks als String übergeben. +Als zweiter Parameter wird eine Funktion übergeben. + +Man beachte die Syntax: Es wird eine Funktion ohne Namen verwendet, ebenfalls ist die Funktion innerhalb der Parameterübergabe definiert. +Die Funktion wird nicht ausgeführt, sondern selbst als Wert übergeben. + +Der übergebenen Funktion werden die Callback-Parameter weitergeleitet, als wäre sie selbst von EEP aufgerufen worden. + +``` +require("kskit\\On") + +On("EEPOnTrainCoupling", function(Zug_A, Zug_B, Zug_neu) + print(" Aus "Zug_A.." und "..Zug_B.." wurde "..Zug_neu) +end) +``` + +Das ganze in längerer Form mit Umweg über eine Variable: + +``` +require("kskit\\On") + +callback4=function(Zug_A, Zug_B, Zug_neu) + print(" Aus "Zug_A.." und "..Zug_B.." wurde "..Zug_neu) +end + +On("EEPOnTrainCoupling", callback4) +``` + +Diese Funktion wird im Hintergrund von allen anderen Funktionen des `On`-Moduls benutzt. + +### OnSignal + +Die wohl meistgenutzte Funktion dieses Modules. +Als ersten Parameter nimmt sie die ID eines Signales, als zweiten Parameter nimmt sie eine Funktion. +Die übergebene Funktion bekommt die Parameter wie üblich übergeben. +Der Aufruf von `EEPRegisterSignal` erfolgt automatisch. + +Hier werden zwei anonyme Funktionen an ein Signal gebunden: + +``` +require("kskit\\On") + +OnSignal(3, function(Stellung) + print("Signal 3 zeigt "..tonumber(Stellung)) +end) + +OnSignal(3, function(Stellung) + print("Signal umgestellt") +end) +``` + +Man beachte die sich schließende Klammer nach dem `end`. + +Es können auch vorhandene Funktionen mittels Namen an `OnSignal` übergeben werden: + +``` +require("kskit\\On") + +OnSignal(4, print) +``` + +In dem Falle wird die neue Signalstellung direkt an `print` weitergegeben und ausgegeben. + +### OnSwitch + +Das selbe wie `OnSignal`, nur für Weichen statt für Signale. + +### Main + +Jetzt muss man wissen, die `EEPMain` ist auch nur ein Callback, mit dem Unterschied, das er ohne Grund immer wieder aufgerufen wird. +Dafür gibt es in diesem Modul eine `Main`-Funktion. +Diese Funktion nimmt nur einen Parameter, jener beinhaltet die Funktion, welche an die `EEPMain` gebunden werden soll. + +``` +require("kskit\\On") +require("Zugtuersteuerung_FS2.lua") + +-- Definitionen für RUS-Packet hier + +-- RUS-Packet von Parry36 aktivieren +Main(inEEPMain) +-- Zugtuersteuerung vom Fried aktivieren +Main(BewegeZugtueren) +``` + +`Main(...)` ist auch nichts weiteres als ein Bequemlichkeits-Aufruf von `On("EEPMain", ...)` ## Serializer: Tabellen in EEP-Slots speichern @@ -170,107 +274,3 @@ function EEPMain() return 1 end ``` - -## On: Multiple Callbacks - -Bestimmte Mechanismen erfordern das automatische Registrieren von zahlreichen Signal- oder Weichencallbacks. -Bei KsKit ist es erforderlich, das unterschiedliche Module ihre eigenen Callbacks registrieren können, ohne voneinander Wissen zu müssen. -Daher bietet das `On`-Modul die Möglichkeit, beliebig viele Funktionen für einen Callback zu registrieren. -Ruft EEP dann den Callback auf, werden alle für diesen Callback registrierten Funktionen aufgerufen. - -Das ganze ist sehr bequem, wenn man eine große Anzahl Callbacks mittels for-Schleife aus einer Tabelle erzeugt. - -### On - -So wie das Modul heisst auch die zentrale Funktion. -Diese registriert eine Funktion für einen EEP-Callback. -Das Anlegen der Callback-Funktion wird bei dem Registrieren der ersten Funktion vorgenommen. -Dabei wird, falls notwendig, der Callback von `On` auch bei EEP registriert. -Das händische Aufrufen von `EEPRegister*` entfällt! - -Als erster Parameter wird dabei der Name des Callbacks als String übergeben. -Als zweiter Parameter wird eine Funktion übergeben. - -Man beachte die Syntax: Es wird eine Funktion ohne Namen verwendet, ebenfalls ist die Funktion innerhalb der Parameterübergabe definiert. -Die Funktion wird nicht ausgeführt, sondern selbst als Wert übergeben. - -Der übergebenen Funktion werden die Callback-Parameter weitergeleitet, als wäre sie selbst von EEP aufgerufen worden. - -``` -require("kskit\\On") - -On("EEPOnTrainCoupling", function(Zug_A, Zug_B, Zug_neu) - print(" Aus "Zug_A.." und "..Zug_B.." wurde "..Zug_neu) -end) -``` - -Das ganze in längerer Form mit Umweg über eine Variable: - -``` -require("kskit\\On") - -callback4=function(Zug_A, Zug_B, Zug_neu) - print(" Aus "Zug_A.." und "..Zug_B.." wurde "..Zug_neu) -end - -On("EEPOnTrainCoupling", callback4) -``` - -Diese Funktion wird im Hintergrund von allen anderen Funktionen des `On`-Moduls benutzt. - -### OnSignal - -Die wohl meistgenutzte Funktion dieses Modules. -Als ersten Parameter nimmt sie die ID eines Signales, als zweiten Parameter nimmt sie eine Funktion. -Die übergebene Funktion bekommt die Parameter wie üblich übergeben. -Der Aufruf von `EEPRegisterSignal` erfolgt automatisch. - -Hier werden zwei anonyme Funktionen an ein Signal gebunden: - -``` -require("kskit\\On") - -OnSignal(3, function(Stellung) - print("Signal 3 zeigt "..tonumber(Stellung)) -end) - -OnSignal(3, function(Stellung) - print("Signal umgestellt") -end) -``` - -Man beachte die sich schließende Klammer nach dem `end`. - -Es können auch vorhandene Funktionen mittels Namen an `OnSignal` übergeben werden: - -``` -require("kskit\\On") - -OnSignal(4, print) -``` - -In dem Falle wird die neue Signalstellung direkt an `print` weitergegeben und ausgegeben. - -### OnSwitch - -Das selbe wie `OnSignal`, nur für Weichen statt für Signale. - -### Main - -Jetzt muss man wissen, die `EEPMain` ist auch nur ein Callback, mit dem Unterschied, das er ohne Grund immer wieder aufgerufen wird. -Dafür gibt es in diesem Modul eine `Main`-Funktion. -Diese Funktion nimmt nur einen Parameter, jener beinhaltet die Funktion, welche an die `EEPMain` gebunden werden soll. - -``` -require("kskit\\On") -require("Zugtuersteuerung_FS2.lua") - --- Definitionen für RUS-Packet hier - --- RUS-Packet von Parry36 aktivieren -Main(inEEPMain) --- Zugtuersteuerung vom Fried aktivieren -Main(BewegeZugtueren) -``` - -`Main(...)` ist auch nichts weiteres als ein Bequemlichkeits-Aufruf von `On("EEPMain", ...)`