Control-flow actors

These actors provide control-flow constructs for other actors. They send messages to user-specified message groups as the results of their actions -- looping, conditional statements, random number generation.

To use the LoopActor, load control.so and create an actor of type LoopActor.

LoopActor messages

The LoopActor periodically sends a single floating-point value to a message group. You can control three aspects of the loop: initialization; termination conditions; and step behavior (just like the three parts of a C-language for(;;) loop). You can also control the number of times to repeat the loop, and optionally "swing" back and forth through the loop.

A loop has three states: its data value, its elapsed time, and how many steps (iterations) it has taken so far. You can control the loop's execution with all three of these. Moreover, since these produce an overdetermined system when taken as a whole, you can specify which of these shall be constrained by the others (e.g., figure out what the data and time increments will be, given a data range of 0 to 10, a time duration of 20 seconds, and exactly 42 steps through the loop).

This is trickier than it looks. Watch out particularly that you terminate the loop in the way you intend to: when the data value reaches a limit, when a fixed number of steps have completed, or when a certain amount of time has elapsed. (If you don't do one of these things, the loop is infinite.)

The default loop "does nothing": it sends out a stream of zeros, unchanging, without termination. (It only does this once a message group has been set to receive the stream, and once a SetNumLoops message has activated it, though.)

In addition to the messages understood by all actors, the LoopActor understands the following messages:

Examples

LoadDSO debug.so;
pr = Create PrintfActor;
// This prints debugging messages.

LoadDSO msgGroup.so;
printme = Create MessageGroup;
AddMessage printme printf pr *0;
// Call this message group to print a number.

LoadDSO control.so;
loop = Create LoopActor;
SetMessageGroup loop printme;
// Attach mg to our loop actor, so our loop will print numbers.
Print 2, 4, 6, 8, one number per second (with debugging info):

Active loop 0;
Debug loop 1;
SetNumLoops loop 1;
SetDataStart loop 2;
SetDataStep loop 2;
SetDataLimit loop 8;
Active loop 1;
sleep 15;

Print 2, 4, 6, 8, one number per second, for one hour:

Active loop 0;
SetNumLoops loop -1; // loop forever
SetDataStart loop 2;
SetDataStep loop 2;
SetDataLimit loop 8;
Active loop 1;
sleep 3600;

Print 2, 4, 6, 8, 6, 4, 2, ten numbers per second, for one minute:

Active loop 0;
SetSwing loop 1; // back and forth
SetTimeStep loop 0.1;
SetNumLoops loop -1; // loop forever
SetDataStart loop 2;
SetDataStep loop 2;
SetDataLimit loop 8;
Active loop 1;
sleep 60;

Print increasing even numbers, ten per second, for one minute:

Active loop 0;
SetSwing loop 1;
SetTimeStep loop 0.1;
SetTimeLimit loop 60; // this replaces SetDataLimit as termination condition
SetNumLoops loop 1; // do this only once
SetDataStart loop 2;
SetDataStep loop 2;
Active loop 1;
sleep 65;

Print "42" ten times:

Active loop 0;
SetStepLimit loop 9; // "for (i=0; i<=9; i++)"
SetDataStart loop 42;
SetDataStep loop 0; // Don't change 42 to anything else (default)
SetNumLoops loop 1;
Active loop 1;
sleep 60;

Print "42" ten times (using 10 loops, instead of 10 steps through one loop):

Active loop 0;
SetStepLimit loop 0; // "for (i=0; i<=0; i++)"
SetDataStart loop 42;
SetNumLoops loop 10; // Do all of the above ten times
Active loop 1;
sleep 60;

Print "42" ten times (using 2 loops of 5 steps each):

Active loop 0;
SetStepLimit loop 4; // "for (i=0; i<=4; i++)"
SetDataStart loop 42;
SetNumLoops loop 2; // Do it twice
Active loop 1;
sleep 60;