Train Message "StartedMoving" abfangen

  • Moin zusammen.
    Ich sitze grad an einem Lok Skript und habe dabei akut ein Problem. Bitte entschuldigt meine Faulheit, dass ich die folgende Problembeschreibung aus dem auran forum kopiert und nicht nochmal explizit übersetzt neu geschrieben habe:
    Auran Forum Thread Link


    Hi,


    I don't know if I'm just being stupid here, but I'm running into a problem with MessageHandlers. I'm writing a script for a custom "class MyLoco isclass Locomotive" because I need to implement my own directional headlight functions. When the driving direction of a train changes (start to drive in reverse) trainz switches the headlights on locos automatically. I cannot use this default function so i'm trying to implement that for myself.


    I'm trying to capture this event via the "Train","StartedMoving" message. Wherever I look I find this bit of code in the Init() of the loco to do just that:
    AddHandler(me, "Train", "StartedMoving", "LocoMessageHandler");


    Looks perfectly reasonable, but at least for me this never gets triggered. And I believe I know why. Looking at the List of Standard Messages (under "T") I find:
    Train,StartedMoving - train>train - Sent when a train starts to move


    "Train","StartedMoving" is sent from Train to Train. So having my loco listed to itself ("me") for that message is no good. The whole thing works if I change my AddHandler call to:
    AddHandler(me.GetMyTrain(), "Train", "StartedMoving", "LocoMessageHandler");


    Unfortnately this is not the full solution to my problem. The handler is set up with the reference me.GetMyTrain() being the train my loco was Init()-ed with. If MyTrain() changes due to Couple/Uncouple then the message handler does not get updated, so my loco keeps listening to either the wrong train (after decouple) or potentially a train that no longer exists (after coupling two trains). Now, I could go ahead and occasionally check if me.GetMyTrain() has changed. If so then I could add a new hander. In my LocoMessageHandler() I could check "if msg.src==me.GetMyTrain()" to ignore all messages from trains I am still listening to but am no longer a part of. But that seems terribly memory-leaky just adding Handlers left and right, always considering that this may become an issue for large numer of locos on a route!!!


    I haven't done too much experimenting with Sniff() instead of AddHandler(), where Sniff() has a "active"-flag:
    public native void Sniff(GameObject target, string major, string minor, bool state)
    state = Boolean flag to set whether or not the handler is currently active.


    If I add a Sniff() with state=true and later "add" the same Sniff() with state=false, does that remove that Sniff() from the internal Message Handler System? Or will I still keep cluttering up the message sytem by adding more and more Sniffs() every time MyTrain() changes?


    I'd greatly appreciate some insight into the matter.
    - am I completely missing something here?
    - do AddHandler()s get removed from message system when their target (in this case train) stops existing?
    - can I overwrite AddHandler()s and/or Sniff()s? How does message system treat duplicate handlers? Will me.Sniff("consist20", "Train", "StartedMoving", false) overwrite/replace a previous me.Sniff("consist20", "Train", "StartedMoving", true)? Will me.AddHandler("consist20", "Train", "StartedMoving", "LocoMessageHandler") overwrite/replace me.AddHandler("consist69", "Train", "StartedMoving", "LocoMessageHandler")?


    Thanks in advance
    - oberskraut

  • Trainz erschafft jedes Mal eine neue Referenz auf ein Train-Objekt, sobald ein Zug sich teilt.
    Heißt, wenn du aus einem Fahrzeug aus einen Zug überwachen möchtest, kannst du das per "Sniff" tun.


    Hast du bei dir eine Library, so kannst du den Sniff auf die gesamte Spielwelt ausweiten und eine eigene Router-Nachricht in die
    Spielwelt broadcasten, als wenn jedes Fahrzeug eine eigene Thread-Funktion laufen lässt. Es ist einfacher und performance freundlicher, wenn du dir in deiner Bibliothek eine eigene Nachrichtenstruktur
    aufbaust. Im Gegensatz zu Started/StoppedMoving werden die Couple und Decouple Nachrichten gebroadcasted.
    Sprich: Du kannst deine Handler bei einer Decouple-Message in der Library zurücksetzen und neue für die neuen Züge setzen.
    Kommt dann eine Nachricht an, so schickst du per Router einfach eine Message "Router.PostMessage(TRAIN_ID, Router.MESSAGE_BROADCAST, "Train", "StoppedMovingNotify", 0.0f);"


    Einmal editiert, zuletzt von MisterSTrain ()