Jump to content
Sign in to follow this  
Timba

Benutzerdefinierte Ereignisse in Ereignismodulen

Recommended Posts

Hallo alle,

bevor jetzt ein schlimmes Bahnunglück mit Hunderten virtuellen Verletzten passiert eine Frage: Wenn ich zwei nahezu identische Ereignismodule nebeneinander habe und in jedem dieser Module existiert ein benutzerdefiniertes Ereignis mit dem Namen "Prüfung", das jeweils innerhalb des Moduls aufgerufen wird, kann ich mich dann darauf verlassen, dass jeweils nur das Ereignis des eigenen Moduls aufgerufen wird und nicht das Ereignis des anderen Moduls? Oder muss ich vorsichtshalber unterschiedliche Namen vergeben?

Gruß Timba

Share this post


Link to post
Share on other sites

Hallo Timba,
für die Unterscheidung hat das Modul doch einen Namen. Unterschiedliche Modulnamen sind wichtig.
Das Problem ist nur - wenn du einen Modulnamen nachträglich änderst, ändert er die Verweise mit? Also, da wäre ich vorsichtig.

Gruß
  Andy

Share this post


Link to post
Share on other sites
vor 7 Minuten schrieb Andy:

Unterschiedliche Modulnamen sind wichtig.

Jepp, Weiß ich. Module haben verschiedene Namen. So wie Andy und Timba z.B. :D

vor 8 Minuten schrieb Andy:

Das Problem ist nur - wenn du einen Modulnamen nachträglich änderst, ändert er die Verweise mit?

Nicht alle. Manche ja, manche nein. Ist mir schon aufgefallen. In Fällen, wo eine nachträgliche Änderung unvermeidbar ist, überprüfe ich das immer. In diesem speziellen Fall ist eine nachträgliche Änderung ausgeschlossen. Aber danke trotzdem für den Hinweis.

Gruß Timba

Share this post


Link to post
Share on other sites

Nachtrag: Ich hatte nur Sorge, weil der Aufruf des benutzerdefinierten Ereignisses über Lua nicht die Modulbezeichnung voranstellt, also nicht etwa $(Modulname).(Benutzerdef. Ereignis), sondern einfach $(Benutzerdefiniertes Ereignis). Deshalb mein Zweifel, ob das Ding kapiert hat, in welchem Modul es sich gerade befindet.

Share this post


Link to post
Share on other sites

Ich habe gerade kein Beispiel zur Hand. Wenn Du auswählen mußt dürfte die Referenz gebildet werden. Wenn Du einen Namen eintippen mußt wird's kritisch. Wenn Du's gesetzt hast, mach mal eine Kopie und übersetze die in Lua. Schau mal, ob da ein Modulname davor steht. Wenn ja, wird der bei der Ausgabe 'eingespart'.

Edited by Andy

Share this post


Link to post
Share on other sites
vor 8 Stunden schrieb Andy:

Wenn Du's gesetzt hast, mach mal eine Kopie und übersetze die in Lua. Schau mal, ob da ein Modulname davor steht. Wenn ja, wird der bei der Ausgabe 'eingespart'.

Moin,

das habe ich ganz am Anfang gemacht. Ich hatte doch keine Ahnung, wie der Aufruf in Lua aussehen muss. Da steht kein Modulname davor. Eintippen geht auch nicht so einfach, weil sobald man das Dollarzeichen tippt muss man auswählen zwischen Objekt und Ereignis, Für die Syntax des benutzerdefinierten Ereignisses ist beides nicht zutreffend. Da es nicht anders geht, wähle ich Objekt und nehme wahllos das erste, danach ersetze ich händisch den Objektnamen durch den Namen des benutzerdefinierten Ereignisses. Etwas umständlich, aber ich wüsste nicht, wie es sonst gehen sollte.

Gruß Timba

Share this post


Link to post
Share on other sites

Ich hab's mal versucht:
Also, prinzipiell sollte man das benutzerdefinierte Ereignis ja auswählen. Damit wird wohl die Referenz hergestellt.
Wenn Du den Namen nachträglich änderst, weißt Du nicht mehr, welches er auswählt.
Ich hab's so gemacht:
Modul kopiert.
Im zweiten Modul einen Aufruf manuell geändert.
Dann die Namen der beiden b.E. geändert mit Endungen 1 bzw. 2
Die $-Einträge sollten die Namen mitändern - es sei denn, das ist mit denen wie mit Timern oder Modulnamen, deshalb beide Namen ändern.
Dann nachschauen. Hat er überhaupt geändert? Hat er nun den Namen desjenigen im eigenen Modul - oder doch das erste in der EV?
Also, im 1.Modul hat er die ...1 gerufen, im 2.Modul die ...2, auch an der Stelle des manuell geänderten Aufrufs.
Ich denke nicht, dass dies Zufall war.
 

Share this post


Link to post
Share on other sites
vor 10 Stunden schrieb Timba:

kann ich mich dann darauf verlassen, dass jeweils nur das Ereignis des eigenen Moduls aufgerufen wird

Ja, kannst du.

Das benutzerdefinierte Ereignis ist nichts anderes als eine Funktion. Die weiß, wer sie aufgerufen hat, bekommt ihre Argumente vom Aufrufer und gibt auch ihr Ergebnis an den Aufrufer zurück. Ganz zuverlässig.

Share this post


Link to post
Share on other sites

Danke. Das ist beruhigend. Ist eigentlich dieses "invoke()" zwingend oder kann man es weglassen, wenn keine Argumente übergeben werden müssen?

Share this post


Link to post
Share on other sites
vor 14 Minuten schrieb Goetz:

Die weiß, wer sie aufgerufen hat, bekommt ihre Argumente vom Aufrufer

Ähm ... ok, aber eigentlich geht es um die Frage, ob der Aufrufer weiß, welche Funktion er aufrufen soll, also genau umgekehrt. Ich unterstelle aber mal, dass das in dem Fall identisch ist.

Share this post


Link to post
Share on other sites
vor 41 Minuten schrieb Andy:

Ich hab's mal versucht:
Also, prinzipiell sollte man das benutzerdefinierte Ereignis ja auswählen. Damit wird wohl die Referenz hergestellt.

Ja, Andy, wenn man das benutzerdefinierte Ereignis über die grafische EV anspricht, wählt man es aus. In Lua aber nicht. Und wenn man die grafische EV nach Lua umwandelt, steht da auch nur der Aufruf des Ereignisses ohne eine Referenz zum Modul, von daher bezweifele ich, dass eine Referenzierung stattfindet bzw. denke ich, dass es intern klar ist, welches Ereignis mit welchem Aufruf in Verbindung steht, also so wie Goetz es darstellt. Für mich ist ja nur wichtig, wie ich es schreiben muss. Die internen Abläufe sind sekundär, nice to know, aber nicht essentiell.

Share this post


Link to post
Share on other sites

Jetzt habe ich mal folgendes ausprobiert:

In der grafischen EV habe ich in Modul 2 das benutzerdefinierte Ereignis in Modul 1 aufgerufen. Das Ergebnis in Lua sieht völlig identisch aus. Anders ausgedrückt: Ob ich aus Modul 2 das Ereignis in Modul 1 oder in Modul 2 aufrufe, es lautet in beiden Fällen $("blabla"):Invoke(). Kein Unterschied. Woher das Programm nun wissen soll, was ich will, ist mir schleierhaft.

Hm ....

Share this post


Link to post
Share on other sites

Finaler Test. Du hattest recht, Andy. Es muss das benutzerdefinierte Ereignis unbedingt ausgewählt werden, wobei offenbar ein Referenzierung stattfindet. Bislang habe ich das wohl falsch gemacht. Es ist doch möglich, in Lua direkt das Ereignis auszuwählen. Schreibt man nur den Namen des Ereignisses, dann kann das falsche aufgerufen werden, wie ich gerade ausprobiert habe.

beispiel.thumb.jpg.5139a482525d0f1f8d735ee06ad20757.jpg

Ob ich an der Stelle auf "MyEvent" in Modul 1 oder auf "MyEvent" in Modul 2 klicke, bringt oberflächlich zwar denselben Befehl, in der Ausführung ist es jedoch unterschiedlich. Wie du eingangs schon geschrieben hast, manuelle Änderungen sind hier absolut heikel und sollten möglichst vermieden werden. Ansonsten muss man die Ereignisse unterschiedlich benennen, dann wird es wohl auch gehen.

Share this post


Link to post
Share on other sites
vor 1 Stunde schrieb Timba:

ob der Aufrufer weiß, welche Funktion er aufrufen soll

Warum hast du zwei benutzerdefinierte Ereignisse mit identischen Namen?

Entweder machen beide im Prinzip das selbe - dann brauchst du nur eins und musst beim Aufruf die individuellen Parameter mitgeben.

Oder sie tun unterschiedliche Dinge. Dann wären unterschiedliche Namen ratsam, egal ob der Aufrufer die individuellen Adressen richtig speichert oder nicht. Denn mit identischen Namen hast du doch selbst nicht sicher im Blick, welches der beiden Ereignisse da nun tatsächlich in deiner EV steht. 

Share this post


Link to post
Share on other sites

Sowas habe ich befürchtet. Das ist ein grundlegendes syntaktisches Problem. Ein direkte referenzierende Zuordnung eines $-Elements darf eigentlich nicht vollzogen werden, wenn die Möglichkeit besteht, dass dieses Element selbst in einer Abhängigkeit steht, also selbst einen Punkt davor hat, der in diesem Fall sogar fehlt. Das fällt unter 'dumm gelaufen'. Ich weiß nicht, inwieweit Neo da noch was retten kann. Es ist hier dann sogar dringend nötig unterschiedliche Namen zu verwenden.
Sicherlich hat Götz insofern recht, dass das jetzt auch eine 'Design'-Geschichte des Programmierenden ist. Aber hallo - von den alten Versionen sind's die Leute einfach gewohnt, mal schnell zu kopieren. Dass diese Schwierigkeit dabei entsteht, muß keiner so direkt erwarten.

Gruß
  Andy

Share this post


Link to post
Share on other sites
vor einer Stunde schrieb Goetz:

Warum hast du zwei benutzerdefinierte Ereignisse mit identischen Namen?

Das benutzerdefinierte Ereignis ist Teil der Bahnhofssteuerung. Die Steuerung habe ich für einen Bahnhof erstellt und getestet, danach für den nächsten Bahnhof kopiert. Deshalb identische Namen.

vor einer Stunde schrieb Goetz:

Entweder machen beide im Prinzip das selbe - dann brauchst du nur eins und musst beim Aufruf die individuellen Parameter mitgeben. 

Die Funktion ist recht umfangreich, ca. 70 Zeilen Programmcode. Die Struktur ist annähernd gleich (deswegen Kopie), aber im Detail schon unterschiedlich und benötigt Anpassung. Je nachdem wieviel Zu- bzw. Abfahrwege und vorhanden sind müssen Änderungen vorgenommen werden. Mit ein paar Parametern ist das nicht getan, denke ich. Was natürlich nicht heißt, dass das nicht geht, aber für mich ist es im Moment so einfacher.

Nun kann ich natürlich nach dem Kopieren die Funktion umbenennen - ein vorangestelltes A, B oder C würde ja völlig genügen. Dann ist der Name wenigstens eindeutig.

vor 1 Stunde schrieb Goetz:

Denn mit identischen Namen hast du doch selbst nicht sicher im Blick, welches der beiden Ereignisse da nun tatsächlich in deiner EV steht.  

Ja eben! Genau diese Unsicherheit führte ja zu meiner Anfrage hier. Würde das beim Testlauf nicht funktionieren, sucht man sich einen Wolf nach dem Fehler. Dass da das "falsche" benutzerdefinierte Ereignis aufgerufen wird, da kommt man wahrscheinlich nicht gleich drauf.

Share this post


Link to post
Share on other sites

Hallo,

vor 8 Stunden schrieb Andy:

Ich weiß nicht, inwieweit Neo da noch was retten kann. Es ist hier dann sogar dringend nötig unterschiedliche Namen zu verwenden.

ich sehe das Problem nicht, bzw. ich glaube, ihr seht Probleme, wo keine sind. Weder sind für den $-Operator unterschiedliche Namen notwendig, noch spielen die Namen überhaupt eine Rolle. Die Namen werden nur zur Unterstützung angezeigt, weil niemand weiß, was hinter der ID 38753956 steht. Der $-Operator funktioniert bei Ereignisreferenzen exakt wie bei den Objektreferenzen, intern erfolgt die Referenzierung über eine eindeutige ID. In welchem Modul ein Ereignis liegt und ob es andere Ereignisse gibt, die den gleichen Namen haben, ist nicht wichtig, eine einmal hergestellte Referenzierung über die Auswahlbox wird dauerhaft beibehalten.

Gleiche Ereignisnamen führen lediglich beim Betrachten des Codes zu Verwirrung, weil nicht ersichtlich ist, welches Ereignis aufgerufen wird. Unter dem Aspekt empfiehlt es sich, unterschiedliche Namen zu verwenden, oder einen Kommentar im Code zu hinterlassen.

Viele Grüße,

Neo

Share this post


Link to post
Share on other sites

Hallo Neo,
bei einer Ausgabe ist das klar. Aber die Problematik hier ist die, dass Timba den Namen eines benutzerdefinierten Ereignisses in Lua manuell ändert. Es wird also nichts aus einer Liste eindeutig ausgewählt. Wenn es hier nun aber Namensgleichheiten gibt, weiß man nicht, zu welchem MBS die Bindung nun aufbaut. Offensichtlich kann dabei auch ein 'modulfremdes' erwischt werden.

Gruß
  Andy

Edited by Andy

Share this post


Link to post
Share on other sites

Hallo,

vor 3 Minuten schrieb Andy:

Offensichtlich kann dabei auch ein 'modulfremdes' erwischt werden.

ja, hier verhält sich das Studio konsistent. Wie bei den Objekten wird bei doppelten Namen das "erste" Ereignis verwendet, wobei das erste nicht wirklich definiert ist. Wurde es jedoch verlinkt, bleibt die Referenz anschließend dauerhaft gültig. Durch einen kleinen Testlauf mit einem print() sollte sich dann schnell herausfinden lassen, ob das korrekte Ereignis aufgerufen wurde (oder man wählt das Ereignis gleich über die Auswahlbox aus).

Der $-Operator arbeitet mit absoluten Referenzen. Timba scheint jedoch eine Art relative Referenzierung zu benötigen, in dem ein Ereignis eines übergeordneten Moduls ermittelt werden soll. Das riecht nach einer neuen Funktion:

self.parent:getEventByName("MyEvent")

in Anlehnung an layout:getEntityByName(). self entspricht dem aktuellen Ereignis, parent wäre das übergeordnete Modul.

Viele Grüße,

Neo

Share this post


Link to post
Share on other sites
vor 2 Stunden schrieb Neo:

Timba scheint jedoch eine Art relative Referenzierung zu benötigen, in dem ein Ereignis eines übergeordneten Moduls ermittelt werden soll.

Hallo @Neo,

nein, eigentlich nicht. Als ich vor einiger Zeit erstmalig ein benutzerdefiniertes Ereignis mit Lua aufrief, habe ich das zunächst mit der grafischen EV gemacht und dann nach Lua konvertiert, um die Syntax zu sehen. Danach beim Tippen war ich offenbar zu ungeduldig und habe, weil das durch $ aufgerufene Dialogfenster nicht unmittelbar das gewünschte Ereignis hergab, einfach händisch den Namen eingegeben und diese Arbeitsweise dann beibehalten. Wie ich jetzt weiß, ist das Quatsch und falsch. Richtig und zuverlässig ist:

vor 2 Stunden schrieb Neo:

oder man wählt das Ereignis gleich über die Auswahlbox aus

So mache ich das jetzt und das funktioniert ja auch. Man muss nur halt aufpassen, wenn man den Aufruf manuell verändert wegen der Referenzierung. Oder wenn man den Aufruf kopiert. Wobei ich festgestellt habe, dass bei der Kopie eines kompletten Moduls die Referenzierungen innerhalb des Moduls alle richtig sind. Nur die Variablen verweisen teilweise noch auf das Originalmodul. Aber damit komme ich schon klar.

 

vor 2 Stunden schrieb Neo:

Das riecht nach einer neuen Funktion:


self.parent:getEventByName("MyEvent")

in Anlehnung an layout:getEntityByName(). self entspricht dem aktuellen Ereignis, parent wäre das übergeordnete Modul.

Die Funktion wäre mir sehr willkommen. Bei einem achtgleisigen Bahnhof mit 4 zweigleisigen Anschlüssen habe ich insgesamt 64 verschiedene Fahrwegschaltungen. Die sind mit Bezeichnungen in der Art "xx-->yy" in 64 benutzerdefinierten Ereignissen hinterlegt und werden durch entsprechend viele if...then... Bedingungen ausgewählt und aufgerufen. Da Herkunft und Ziel des Zugs dem Programm bereits bekannt sind, könnte daraus leicht ein String mit dem Namen des benutzerdefinierten Ereignisses erzeugt und das Event aufgerufen werden. Wäre wesentlich einfacher. Vielleicht kannst du uns ja irgendwann mit dieser Funktion erfreuen.

Gruß Timba

Share this post


Link to post
Share on other sites
vor 6 Minuten schrieb Timba:

in 64 benutzerdefinierten Ereignissen

*räusper* Ich glaube, ich habe noch ein paar mehr. Sowas solltest Du in eine Tabelle tun. Anzahl der Ereignisse minimieren!
Gruß
  Andy

Share this post


Link to post
Share on other sites
vor 1 Minute schrieb Andy:

Ich glaube, ich habe noch ein paar mehr.

Du bist ja auch noch jünger als ich. :D

vor 4 Minuten schrieb Andy:

Sowas solltest Du in eine Tabelle tun. Anzahl der Ereignisse minimieren!

Das kann ich ja später (mit mehr Durchblick) ändern. Vielleicht muss ich mir das mal ansehen bei dir. Die Anzahl der Ereignisse stören mich eigentlich nicht so sehr, einmal erstellt, klappe ich das Modul zu und sehe sie nicht mehr. Viel mehr stört der Aufruf bzw. die Auswahl des "richtigen" Ereignisses über die vielen if...then...Bedingungen.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×