Neuer Callback-Handler

This commit is contained in:
Nero 2023-07-21 22:26:42 +00:00
parent 2c8372bc9e
commit 52d1143fd4
2 changed files with 160 additions and 8 deletions

48
On.lua Normal file
View File

@ -0,0 +1,48 @@
-- Schluessel ist der Callback-Name, Wert ist eine Tabelle mit den Funktionen
local Callbacks = {}
function On(Name, UserFunktion)
-- Das folgende muss nur fuer den ersten Aufruf je Callback gemacht werden
-- Spaetere Aufrufe koennen mit dem exitierenden Eintrag weiterarbeiten
if not Callbacks[Name] then
-- Wenn der User den Callback bereits definiert hat, alles abbrechen
-- Sonst kommt schwer nachzuvollziehende Gruetze raus
assert(_G[Name] == nil, Name.." bereits definiert")
-- Bei Weichen und Signalen muss der Callback registriert werden
-- Item ist entweder "Switch" oder "Signal"
local Item, Number = string.match(Name, 'EEPOn(.+)_(%d+)')
if Number ~= nil then
local RegisterFunc="EEPRegister"..Item
local ok = _G[RegisterFunc](Number)
if (ok==0) then print(RegisterFunc.."("..Number..") fehlgeschlagen") end
end
-- Tabelleneintrag fuer diesen Callback eroeffnen
Callbacks[Name] = {}
-- Hier erstellen wir den echten Callback, welcher dann von EEP aufgerufen wird
-- und der jede in unserer Tabelle eingetragene Funktion aufruft
_G[Name] = function(...)
for _, UserFunktion in pairs(Callbacks[Name]) do
UserFunktion(...)
end
-- Wir sind vielleicht die EEPMain und muessen daher 1 zurueckgeben
return 1
end
end
-- Die uns gegebene Funktion an unseren Tabelleneintrag anhaengen
table.insert(Callbacks[Name], UserFunktion)
end
-- EEPMain-Callback registrieren
function Main(Funktion)
On("EEPMain", Funktion)
end
-- Signal-Callback registrieren
function OnSignal(Signal, Funktion)
On("EEPOnSignal_"..tostring(Signal), Funktion)
end
-- Weichen-Callbacks registrieren
function OnSwitch(Switch, Funktion)
On("EEPOnSwitch_"..tostring(Switch), Funktion)
end

120
README.md
View File

@ -6,14 +6,14 @@ lang: de
# KsKit für Eisenbahn.exe
KsKit sind ein paar Lua-Scripte und Anleitungen, welche ich auf meinen Anlagen nutze.
KsKit sind ein paar Lua-Scripte, welche ich auf meinen Anlagen nutze.
Von denen habe ich ein paar Dokumentiert, sie sind bisweilen recht nützlich.
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 Teilscripte werden in den LUA-Ordner im EEP-Stammverzeichnis installiert.
Die Scripte werden unterhalb vom LUA-Ordner im EEP-Stammverzeichnis installiert.
## 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.
Daher müssen persistente Werte via `EEPSaveData` gespeichert und nach dem Reset wieder geladen werden.
@ -29,7 +29,7 @@ Sie nimmt ein Argument und gibt eine Zeichenkette zurück.
Der Return-Wert ist gültiges Lua und kann mittels `load()`-Funktion wieder in die Tabellenform zurückgewandelt werden.
```
require("Serializer")
require("kskit\\Serializer")
Tabelle={
str = "abcdef",
@ -57,7 +57,7 @@ Daher wird das Zwischenergebnis nochmal in ein `urlencode`-ähnliches Format umk
Dabei werden sämtliche Steuerzeichen und Hochkommas sicher verpackt.
```
require("Serializer")
require("kskit\\Serializer")
Tabelle={
str = "abcdef",
@ -82,9 +82,9 @@ Dabei wird das `urlencode` wieder entfernt und die Daten mittels `load`-Funktion
Ist der Slot unleserlich oder wurde in diesen noch keine Tabelle geschrieben, wird eine Warnmeldung in das Ereignisfenster geschrieben und eine leere Tabelle zurückgegeben.
```
require("Serializer")
require("kskit\\Serializer")
dump(ladeTabelle(1))
print(serialize(ladeTabelle(1)))
-- Ausgabe: {bol=true,lst={1,2,3},str="abcdef"}
```
@ -100,7 +100,7 @@ Die Kontakte und Callbacks werden davor abgearbeitet.
Daher reicht es aus, wenn die Tabelle nur einmalig am Ende der EEPMain zurückgeschrieben wird.
```
require("Serializer")
require("kskit\\Serializer")
-- Die Tabelle wird nur beim Starten von Lua einmal geladen
Zugdaten_Slotnummer = 1
@ -127,3 +127,107 @@ 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", ...)`