Zum Inhalt

Loops und Iterationen

Es gibt unterschiedliche Möglichkeiten in adaptor:ex Abfolgen zu wiederholen. Abläufe können jederzeit im Kreis angeordnet werden und mit Logic Actions wie Switch und Iterate lassen sich komplexe Schleifen realisieren. Auch andere Actions können in sich wiederholenden Abläufen eine besondere Funktion einnehmen. Dieses Kapitel soll eine Auswahl verschiedener Loop Varianten erläutern und zeigen wie gängige Programmierroutinen in adaptor:ex umgesetzt werden können.

Abläufe Wiederholen

Eine Abfolge von States kann jederzeit wiederholt werden. Sobald ein späterer State auf einen vorherigen State verweist wird dieser und ggf. folgende States ein weiteres mal ausgelöst.

Screenshot

Eine Schleife, die nicht unterbrochen wird, läuft solange bis die zugehörige Session beendet wird.

Eine Schleife kann beliebig viele States umfassen und jede Art von Action enthalten.

Mit den Time Actions Timeout, Date and Time und Schedule lassen sich so z.B. wiederkehrende Ereignisse programmieren.

Screenshot: adaptor:ex level das täglich um 9 Uhr ein Katzen GIF generiert durch den webservice cataas per telegram versendet

Example Level File

Download: cat_each_day.json

In diesem Beispiel etwa, wird jeden Tag um 9 Uhr ein Katzen GIF durch den webservice Cat as a service generiert und von einem Telegram Bot versendet.

Loops beenden

Jede Action, die einen Next State auslösen kann, kann auch dazu genutzt werden eine Schleife zu unterbrechen.

Das ist dann Vergleichbar mit einer While Schleife, die solange läuft, bis eine Bedingung eintrifft, die die Schleife beendet.

Ein gängiges Beispiel: Eine counter variable count wird mit jeder Iteration um 1 erhöht. Eine Switch action überprüft, ob count größer ist als 4, also 5 ist und löst dann einen Next State aus (hier Proceed), der sich nicht innerhalb der Schleife befindet.

Screenshot

Also in etwa while count < 5; count++

Auch die Iterate Action kann genutzt werden um eine Schleife wie im obigen Beispiel auf eine Anzahl Wiederholungen zu begrenzen. Eine Ganzzahl in with legt fest, wie viele Iterationen durchgeführt werden bis Iterate übersprungen wird.

Screenshot

Wenn sich der Loop in einem separaten Path befindet, kann die Schleife auch mit der Join Path Action von einem parallel laufenden Pfad an beliebiger Stelle beendet werden.

Screenshot

Loops werden natürlich auch beendet, wenn die Session beendet wird, in der der Loop läuft. Mit der Cancel Session Action lassen sich also auch potentielle Schleifen, die in anderen Levels bzw. Sessions laufen beenden.

For Each Loop

Die Iterate Action ermöglicht es mit jeder Runde eines Loops auf einen anderen Eintrag aus einem Datensatz zuzugreifen.

So kannst du eine oder mehrere Aktionen mit dem jeweils nächsten Element aus einem Array, einem Objekt oder einer Collection ausführen.

Du kannst die Elemente, die Iteriert werden sollen innerhalb der Iterate Action angeben oder über die Elemente einer variable iterieren, die an anderer Stelle erstellt wurde.

Sobald über alle Elemente iteriert wurde, wird Iterate übersprungen und wird nicht mehr einen Next State auslösen.

So lässt sich auf einfache weise ein For Each Loop bauen. Also etwa:

for each item in collection:
  do something to item
Auszug aus Wikipedia Artikel Foreach Loop

In diesem Beispiel wird eine Auswahl an Items aus der players Collection geholt und an jeden player die selbe Telegram Nachricht gesendet. Dabei wird auch die Ansprache mit der name variable personalisiert und zusätzlich ein Eintrag im jeweiligen players Item geändert.

Screenshot

Wurde die Aktion für jedes players Item durchgeführt, wird Iterate in der folgenden Schleife übersprungen und durch die darunter stehenden Next State Action geht es mit Done weiter.

Listener und Loops

Ein Ereignis, dass eine Reaktion hervorruft kann jederzeit zum ursprünglichen Ereignis Listener zurückführen.

Das ist besonders praktisch um Ereignisse zu verarbeiten, die zwar eine Reaktion hervorrufen, aber nicht den Haupt Strang des Levels weiterführen.

Subroutinen

In diesem Level Abschnitt eines Telegram Adventures wird im Angekommen State auf eine Nachricht "angekommen" durch den player gewartet. Um sicher zu gehen, dass die benötigte Geo location den player erreicht hat, wird diese bei jeder Antwort, die nicht explizit abgefragt wird erneut verschickt.

Screenshot

Die Telegram On Incoming Message Action ermöglicht es auch innerhalb der Action auf eingehende Nachrichten zu reagieren ohne den State zu verlassen. Geo Locations können aber nicht als so eine "direkt Antwort" gesendet werden. Kommt eine unbekannte Nachricht rein, wird also der NichtGefunden State ausgelöst. Sobald die Geo Location mit Send Geo Location versendet wurde, wird in den Angekommen State zurück gewechselt und wieder auf eingehende Nachrichten gehört.

Keep listening and queue

Ein Problem, dass bei dieser Art Loops auftritt ist, dass Ereignisse, die zur Unzeit eintreffen, verpasst werden können.

Sobald wir den State mit dem Listener verlassen wird dieser geschlossen und wird nicht weiter auf eingehende Nachrichten oder andere Ereignisse reagieren. Die Dauer, die der Listener nicht "zuhört" lässt sich zwar in manchen Fällen auf einen kurzen Zeitraum reduzieren, etwa mit einem separaten Pfad, der die Folge Aktionen asynchron ausführt. Es wird aber immer ein Zeitfenster entstehen, in dem wir nicht sicherstellen können ob wir alles mitbekommen haben.

On Incoming Message und andere Listener wie On Event und On MQTT Message haben die Möglichkeit "Stumm" geschaltet zu werden, anstatt sie ganz zu deaktivieren. Aktivierst du die Option keep listening and queue, wird die listener Action weiter auf eingehende Nachrichten hören, ohne direkt darauf zu reagieren.

Screenshot

Der Listener wird dann eingehende Ereignisse bzw. Nachrichten in einer Liste einreihen. Wird der Listener dann erneut getriggert, werden zunächst die eingereihten Nachrichten auf matches überprüft.

Screen Recording

Example Level File

Download: listener_and_loop.json

Die Nachricht Achso, ja habe ich! wird hier in dem kurzen Zeitfenster gesendet, indem der On Incoming Message Listener im Angekommen State nicht aktiv ist. Auf die Nachricht wird aber trotzdem kurz darauf reagiert, da keep listening and queue aktiviert ist.

Insbesondere auch IoT Geräte, die eine Subroutine auslösen, wenn sie eine Bestimmte Nachricht schicken, etwa per MQTT, können so zuverlässig eingebunden werden.