Skip to content

Loops and Iterations

There are different ways to repeat sequences in adaptor:ex. Things can be arranged in a circle at any time and complex loops can be realized with Logic actions such as Switch and Iterate. Other actions can also take on a special function in repetitive sequences. This chapter is intended to explain a selection of different loop variants and show how common programming routines can be implemented in adaptor:ex.

Repeat

A sequence of states can be repeated at any time. Whenever a later state refers to a previous state, this and any subsequent states are triggered again.

Screenshot

A loop that is not interrupted otherwise, runs until the associated session is ended.

A loop can comprise any number of states and contain any type of action.

You could for example use the time actions Timeout, Date and Time and Schedule to program recurring events.

Screenshot: adaptor:ex level that sends a cat GIF generated by the webservice cataas via telegram every day at 9 o'clock

Example Level File

Download: cat_each_day.json

In this example, a cat GIF is generated every day at 9 am by the webservice Cat as a service and sent via Telegram Bot.

End loops

Every action that can trigger a Next State can also be used to interrupt or break a loop.

This is comparable to a While loop, which runs until a condition is met that ends it.

A common example: A counter variable count is increased by 1 with each iteration. A Switch action checks whether count is greater than 4, and then triggers a Next State (here Proceed), which is outside the loop.

Screenshot

In pseudo code this might look like while count < 5; count++

The Iterate action can also be used to limit a loop to a number of repetitions as in the example above. An integer in with determines how many iterations are performed until Iterate is skipped.

Screenshot

If the loop is located in a separate Path, the loop can also be ended with the Join Path action from a parallel path at any point.

Screenshot

Loops are of course also ended when the session in which the loop is running is canceled. The Cancel Session action can therefore also be used to end potential loops that are running in other levels and their respective sessions.

For Each Loop

The Iterate action makes it possible to access a different entry from a data set with each round of a loop.

This allows you to execute one or more actions with the next element from an array, an object or a Collection.

You can specify the elements to be iterated within the Iterate action or iterate over the elements of a variable that was created elsewhere.

Once all elements have been iterated over, Iterate will be skipped and will no longer trigger a Next State.

This is a simple way to build a For Each Loop like:

for each item in collection:
  do something to item
Excerpt from Wikipedia article Foreach Loop

In the example below, a selection of items is retrieved from the players collection and the same Telegram message is sent to each player. Each player is addressed personally using their name variable and an entry in the respective player item is changed furthermore.

Screenshot

Once the action has been carried out for each players item, Iterate is skipped in the following iteration and the Next State action below continues with Done.

Listeners and loops

An event that triggers a reaction can lead back to the original event listener at any time.

This is particularly useful for processing events that cause a reaction but do not continue the main strand of the level.

Subroutines

In this level section of a Telegram adventure, the Arrived state is used to wait for an "arrived" message from the player. To ensure that the required geo location has reached the player, it is sent again with every response that does not match the conditions (else).

Screenshot

The Telegram On Incoming Message action makes it possible to respond to incoming messages within the action itself without leaving the state. However, Geo Locations cannot be sent as such a "direct response". If an unknown message comes in, the NotFound state is triggered. As soon as the Geo Location has been sent with Send Geo Location, the system switches back to the Arrived state and listens for incoming messages again.

Keep listening and queue

One problem that occurs with this type of loop is that events that arrive at the wrong time might be missed.

As soon as we leave the state that contains the listener, it is closed and will no longer react to incoming messages or other events. In some cases the time that the listener is not "listening" can be reduced to a fairly short period, for example with a separate path that executes the sequence of actions asynchronously. However, there will always be a time window in which we cannot be sure that we have heard everything.

On Incoming Message and other listeners such as On Event and On MQTT Message have the option of being "muted" instead of deactivating them completely. If you activate the keep listening and queue option, the listener action will continue to listen for incoming messages without responding immediately.

Screenshot

The listener will then add incoming events or messages to a queue. If the listener is then triggered again, first off the queued messages are checked for matches.

Screen Recording

Example Level File

Download: listener_and_loop.json

Here the message Achso, ja habe ich! is sent in the short time window in which the On Incoming Message listener is not active because we are not in the Incoming state. However, if keep listening and queue was activated, the message is still responded to shortly afterwards, once we switch back to Incoming.

In particular, IoT devices that trigger a subroutine when they send a specific message, for example via MQTT, can be integrated reliably this way.