? Reagieren auf Wertänderungen ohne Message

  • Moin,


    ich bin grade dabei mich in TrainzScript einzuarbeiten und wollte mir mal anschauen, wie man aufbauend auf dem "Automatic Random Running-Number System" eine Prüfziffer generieren und anhängen kann.

    Die Kurzfassung: Mit GetRunningNumber() kann die aktuelle Fahrzeugnummer abgefragt, und mit SetRunningNumber() geschrieben werden. In der Config kann über den Eintrag running-numbers eine Vielzahl von möglichen Nummern festgelegt werden - wahlweise über Intervalle, Listen oder eine Kombination aus beidem.


    Ist das Asset mit diesem Eintrag konfiguriert, so weißt Trainz beim Initialisieren des Objektes im Surveyor diesem eine zufällige Nummer im zulässigen Rahmen zu. Bei Bedarf kann diese über das Eigenschaften-Fenster (?) geändert - oder nach manueller Eingabe wieder auf einen Zufallswert zurückgestellt werden. Soweit so gut.

    Leider gibt es keine Message, auf die gehört werden kann, sobald sich die Loknummer ändert - also ein Nutzer per Interface oder Script die Loknummer manipuliert.


    Daher die Frage, wie kann in TrainzScript auf die Änderung von Werten gehört werden, ohne per Timer alle n Sekunden danach zu fragen?


    Ein Usecase wäre z.B. folgender:

    Ich stelle die Lok (z.B. eine V200) auf die Gleise und es wird ihr automatisch die Nummer "220012" gegeben. Das Script welches im Constructor einen Aufruf zur Berechnung der Prüfziffer hat, würde entsprechend die Nummer abfragen, die Prüfziffer "9" bestimmen und anschließend die neue Loknummer "2200129" setzen. Wenn der Nutzer allerdings gerne seine Lieblingsnummer "023" hätte, gibt er über das Einstellungsfenster die neue Nummer "220023" an und würde erwarten, dass die Lok anschließend "2200236" heißt - also "220 023-6". Die letztgenannte Änderung bekomme ich allerdings nicht mehr mit…


    Cheers

    Sachsenbahner

  • Kurzum, diese Möglichkeit gibt es nicht, es sei denn das Runningnumber-Element im Browser schickt so eine live:// message, weiss ich gerade nicht. Ansonsten kannst du auf das Schließen des Browserfensters warten und dann deinen Check durchführen.


    Ich würde aber grundsätzlich von der Benutzung des eingebauten Nummernsystems Abstand nehmen, das ist eher für Amerikanische "Road Numbers" geeignet als für unser System. Ich denke du hast auf längere Sicht mehr Ärger damit, das eingebaute System so hinzubiegen, dass es mit deutschen Nummern läuft als wenn du gleich ein eigenes schreibst.


    Die Baureihennummer bleibt fix, du kannst sie im extensions-table der Fahrzeugconfig schreiben.

    Das Nummernspektrum kannst du auch dort in den Extensions hinterlegen.

    Dein Skript bietet dann im Optionenfenster des Fahrzeuges nur noch ein Feld für die Fahrzeugnummer an, denn die Baureihe kann der User ja nicht ändern. So ein selbstgemachtes Browserfeld schickt auf jeden fall eine live:// message auf die du warten und den Wert auslesen kannst.

    Nach dieser Eingabe kannst du dann die Prüfziffer berechnen und die neue Fahrzeugnummer setzen. Du kannst auch den User anmeckern, wenn er versucht eine nicht existierende Fahrzeugnummer einzugeben, wenn du willst. :P


    Zum Schluss fügst du noch in der Init Funktion ein Random(maximaleFahrzeugnummer - minimaleFahrzeugnummer) + minimaleFahrzeugnummer hinzu und das Fahrzeug erhält beim setzen eine zufällige Nummer.




    Greets, Mika

    Aufgaben- und Streckenbauer, Repainter und Skriptnovize.

    "Its always more fun to share with everyone." - Jack Johnson

  • Die SetProperties-Methode, schießt dann, wenn der Nutzer das Konfigurationsfenster mit dem Haken schließt. Da kannst du dich dann reinhaken.

    Ob sich zur "Laufzeit" per drittem Script die Loknummer ändert, ist nur über Workarounds ermittelbar, da es standardmäßig keinen Callback und keine Message dafür gibt, die schießt, wenn die "native" Methode "SetRunningNumber" der "Vehicle"-Klasse aufgerufen wird.


    Ich hatte zwar vor einiger Zeit an Möglichkeiten für Callbacks gearbeitet, aber auch da kann ich nur meine eigenen Implementierungen mit ausstatten.

    Alles, was native also nicht im eigentlichen Script-Code geschrieben ist, kannst du nicht ändern, somit bleibt nur die Timer-Lösung.


    Ich denke du hast auf längere Sicht mehr Ärger damit, das eingebaute System so hinzubiegen, dass es mit deutschen Nummern läuft als wenn du gleich ein eigenes schreibst.

    Das kann man so und so sehen. Wenn man es richtig machen wollte, so ginge man hin und überschreibt sämtliche Funktionen, die in einer GUI die Fahrzeugdaten ausgeben, um das eingebaute System durch die Anzeige des eigenen zu ersetzen. Das habe ich zwar bei den TD Fahrzeugen auch nicht gemacht, aber das wäre m.A. nach die schönste Weise und auch die, die es sein sollte, um den Nutzer nicht zu verwirren.


    Nachtrag:
    Natürlich ist ein eigenes System weitaus flexibler, dennoch ist das nicht pauschal die richtige Antwort auf ein Problem.
    Es ist immer der richtige Weg, sich in einer Umgebung wie Trainz nach Funktionen umzusehen, die mit ein wenig Anpassung vielleicht schon den Bedürfnissen gerecht werden. Ganz gemäß einer Aufwand-Nutzen-Rechnung.


    Das wäre ein guter grober Entwurf, um sich dem Problem zu nähern, welches auch eine Art Callback beinhaltet.


    Nutzung wäre dann diese:


    Ist ungetestet, aber dürfte gehen.

    Ich schreibe alle Beiträge aus meiner persönlichen, differenzierten Sicht. Schade, dass es echt notwendig ist, obwohl mein Name hinter einem Beitrag steht, dies so hervorheben zu müssen. Ich schreibe also in meinem Namen, nicht im Namen von Gruppierungen oder Unternehmen.

    6 Mal editiert, zuletzt von callavsg ()

  • Moin ihr beiden,


    danke für die schnelle Antwort.

    Die Baureihennummer bleibt fix, du kannst sie im extensions-table der Fahrzeugconfig schreiben.

    Das Nummernspektrum kannst du auch dort in den Extensions hinterlegen.

    Ja, das war auch der Plan - für das Beispiel wollte ich es nur etwas vereinfachen. Zudem unterstützt Trainz auch nur 6-stellige Zahlen, sodass mir für die vollständige Nummer bis zu zwei Stellen fehlen.


    Ich würde aber grundsätzlich von der Benutzung des eingebauten Nummernsystems Abstand nehmen, das ist eher für Amerikanische "Road Numbers" geeignet als für unser System. Ich denke du hast auf längere Sicht mehr Ärger damit, das eingebaute System so hinzubiegen, dass es mit deutschen Nummern läuft als wenn du gleich ein eigenes schreibst.

    Genau genommen ist das Grundsystem sogar recht flexibel - und bietet obendrein die Funktionalität der Anzeige der Nummer auf dem Fahrzeug mit eigenen Texturen, was das Hauptziel der ganzen Aktion ist.

    Modellieren lässt sich das ganze recht gut auf einem Int-Array mit 8 Stellen in folgender Aufteilung (die Grundidee kommt von Pascal in seinem Tutorial):

    • Indizes 0-3 bilden die Baureihennummer und können - wie von dir schon beschrieben - aus der Config oder aus dem Fahrzeugscript kommen
    • Indizes 4-6 bilden die (meistens) fortlaufende Ordnungsnummer, dies ist der Teil, der durch Trainz zugewiesen wird
    • Index 7 ist die Prüfziffer

    Nutzt man für diesen Fall die BuiltIn-Funktionalität, spart man sich das generieren der Zufallszahl, das Parsen der Soup und das Validieren der zulässigen Intervalle.

    Zugegebener Maßen ist der unschöne Teil dann, dass ein Nutzer "123" eingibt und danach "123X" in dem Feld steht.


    Die Zuweisung sieht bei mir derzeit etwa so aus:

    Wie genau ich die Aufteilung und Speicherung der Segmente vornehme, ist noch nicht ganz klar.


    Fürs Erste werde ich mal versuchen auf SetProperties zu horchen und mal schauen, wie sich die Eingabe so angenehm wie möglich gestalten lässt.


    Noch eine Frage am Rande:
    Kann ein Array in einer statischen Klasse bereits mit einer bestimmten Belegung initialisiert werden? Bei meinen Versuchen bekam ich stets einen Parsing-Error. In anderen Sprachen könnte man z.B. so etwas machen:

    Java
    1. class Luhn
    2. {
    3. public int[] preCalc = new int[] {0,2,4,6,8,1,3,5,7,9};
    4. }


    Cheers

    Sachsenbahner