Behandeln von Befehlen oder Ereignissen, die darauf warten, dass eine Aktion anschließend abgeschlossen wird

7

Angenommen, Sie haben zwei Ereignisse: Aktion1 und Aktion2. Wenn Sie Action1 erhalten, möchten Sie einige beliebige Daten speichern, die beim nächsten Rolling von Action2 verwendet werden sollen. Optimalerweise ist Aktion1 normalerweise ein Befehl, es können jedoch auch andere Ereignisse sein. Die Idee ist immer noch dieselbe.

Die aktuelle Art, wie ich dies implementiere, besteht darin, den Status zu speichern und dann einfach zu überprüfen, wann Action2 aufgerufen wird, ob dieser bestimmte Status vorhanden ist. Dies ist offensichtlich etwas chaotisch und führt zu viel redundantem Code. Hier ist ein Beispiel dafür, wie ich das mache, in Pseudocode-Form (und offensichtlich ziemlich aufgeschlüsselt):

void onAction1(event) {
    Player = event.getPlayer()
    Player.addState("my_action_to_do")
}

void onAction2(event) {
    Player = event.getPlayer()

    if not Player.hasState("my_action_to_do") {
        return
    }

    // Do something
}

Wenn ich dies für viele andere Aktionen mache, wird es etwas hässlich und ich wollte wissen, ob ich etwas tun kann, um es zu verbessern.

Ich dachte an so etwas, für das keine Daten weitergegeben werden müssten, aber ist das auch nicht die richtige Richtung?

void onAction1(event) {
   Player = event.getPlayer()
   Player.onAction2(new Runnable() {

       public void run() {
           // Do something
       }

   })
}

Wenn man noch weiter gehen wollte, konnte man das nicht einfach tun?

void onPlayerEnter(event) { // When they join the server
    Player = event.getPlayer()
    Player.onAction1(new Runnable() {

       public void run() {

           // Now wait for action 2
           Player.onAction2(new Runnable() {
               // Do something
           })

       }

    }, true) // TRUE would be to repeat the event,
             // not remove it after it is called.
}

Jede Eingabe wäre wunderbar.

virulent
quelle
4
Schlagen Sie das Muster der Aktionsliste (auch Befehlswarteschlange) nach. Erwarten Sie jedoch im Allgemeinen, dass eine gewisse Schlamperei bestehen bleibt. Spielelogik ist normalerweise nicht in der Lage, in ordentliche Muster verschoben zu werden.
Sean Middleditch

Antworten:

1

Ich denke, Ihr erstes Beispiel ist das einfachste. Wenn ich etwas tun würde, hätte ich einen zentralen ActionManager. Aktionen können Daten an sie senden, damit andere Aktionen sie später abrufen können. Ich wäre fast wie ein Ereignissystem, nur dass "Nachrichten" nicht an eine Entität übermittelt werden, sondern einfach sitzen und darauf warten, dass eine Aktion sie aufnimmt.

Dies würde dazu beitragen, Action1 von Action2 zu entkoppeln, sodass Sie dies auch tun könnten, wenn Sie Action3 mit Action2 verbinden möchten. Action2 kennt oder kümmert sich nicht um 1 oder 3, es geht nur darum, nach einer Action2Message zu suchen.

Michael
quelle
0

Es ist schwierig, eine Lösung zu finden, ohne zu wissen, wie Ihr ActionListener / Handler / Manager aussieht

so wie ich es machen würde (ich bin ac # Entwickler, aber ich denke das gleiche ist in Java möglich):

anstatt den Staat zu registrieren

Player.addState("my_action_to_do")

Ich hätte einen Stapel von ActionListeners für Action2-Ereignisse, zu denen das void onAction1 () -Ereignis einen Handler hinzufügen würde, der aufgerufen wird, wenn Action2 aufgerufen wird:

(Ich werde es in Java versuchen, ist aber möglicherweise nicht ausführbar):

Stack<ActionListener> onAction2Events = new ...;

void onAction1(event) {
    Player = event.getPlayer();
    onAction2Events.add(new ActionListener() {
      public void actionPerformed(ActionEvent e) { 
          // this code will be called if onAction2 is invoked
      }
    });
}

void onAction2(event) {
    Player = event.getPlayer()

    InvokeEvent(onAction2Events); // calls all ActionListeners / states that ware added

    // ...
}

void InvokeEvent(Stack<ActionListener> listenerStack) {

    while(listenerStack not empty)
    {
        listenerStack.pop().actionPerformed(...);
    }
}
cppanda
quelle