# /repeat

Usage:

/REPEAT [-w[world]] [-n] {[-time]|-S|-P} count command

Repeats command, count times. Command may be any legal macro body. If count is "`i`", the command repeats indefinitely. This works through a process, which runs concurrently with normal operations.

Options:

-w[world]
  Command will execute with world as the current world. If world is omitted, it is assumed to be the world that was current for /repeat. If this option is omitted entirely, the command's current world will be whatever world happens to be in the foreground when it's time for command to run.
-time
  Time is the delay between each execution of command. Time may be specified in the format "hours:minutes:seconds", "hours:minutes", or "seconds" (seconds may be specified to the nearest microsecond).
-S
  The repeat will run synchronously.
-P
  The repeat will run whenever a prompt is received.
-n
  When combined with the -time option, this makes the first execution of command happen with no delay.

At most one of the -S, -P, and -time options should be specified. If none are specified, the delay between each execution of command is determined by the variable %{ptime}. See "processes" for more information on process timing.

The command undergoes macro body substitution when it is executed.

An asynchronous /repeat (without -S) returns the pid of the new process, or 0 if an error occurred. A synchronous /repeat returns the return value of the last command.

Since the first run is not done until after the first interval (for /repeat without -S or -n), a useful trick is to use "/repeat -time 1 command" to delay the execution of a single command.

Example: `/repeat -0:30 1 /echo -ab Dinner's ready`

There is no good way to directly "sleep" within a macro body. Any attempt to write your own /sleep macro will, at best, "freeze" tf for the duration of the sleep, or even worse hog the machine's CPU time in a busy wait. The best way to achieve the effect a sleep in a /while loop is probably to use a /repeat where each execution of the /repeat body corresponds to an iteration of the desired /while loop. That is, if you want to write

        /def foo = \
    	/before_stuff%; \
    	/while (condition) \
                /do_stuff%; \
                /sleep 5%; \
    	/done%; \
    	/after_stuff

you must instead write:

        /def foo = \
    	/before_stuff%; \
    	/foo_loop

        /def foo_loop = \
    	/if (condition) \
                /do_stuff%; \
    	    /repeat -5 1 /foo_loop%; \
    	/else
    	    /after_stuff%; \
    	/endif

Of course, local variables will not survive between calls of /do_stuff in the second version as they would in the first (if it were possible), so any variables you need to share between iterations must be global.

But, if the reason you want to sleep is to wait for a response from a server, then you really don't want to sleep at all: you want a trigger. First, set up triggers on the possible responses, then send the command. If one of the possible responses is no response at all, then a /repeat can be useful to wait for some maximum timeout and then handle the no-reponse case and delete the response triggers. This is in general the best way to write macros that interact with a server.

See: processes, %ptime, /at

Back to index
Back to tf home page

Copyright © 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004 Ken Keys