There are a number of ways to implement timers. There are slight differences between them all.
The first way is just to use task_sleep
from within task context.
A task can sleep in between actions to enforce a particular delay.
Note that this gives a minimum delay; the actual delay may be longer.
If you are not in a task context that can sleep, you can create a new task which is allowed to sleep. Starting and stopping such tasks is equivalent to starting and stopping a timer. Querying the task by its GID is equivalent to checking if the timer is still running.
If you want to use this model, consider using the timer_
xxx APIs,
which do this underneath a standard API that clearly shows what you are trying
to accomplish.
Because these timers are based on tasks, they do not need to be statically declared in advance. They are limited in number only by the maximum number of tasks.
Sometimes you may want a timer, but without the overhead of a separate task.
Then use the free_timer_
xxx functions. Free timers
are small counters that are updated in realtime context. They do not
support pausing (hence, the name) but can be started/stopped. The set
of all free timers must be declared in advance in the machine
configuration file.
Free timers are useful for the case when you need to run a timer, and no code needs to be executed when the timer expires. You can always write code to query the timer value, but if it expires to zero, then nothing special happens. One common use is for detecting certain playfield shots when a series of switches needs to activate within a certain amount of time, say 1 second apart.
Free timers can only be started in multiples of 1/3 second, up to 8 seconds.
Periodic functions can be declared to do timing. Your choices for frequency are limited to 16ms, 100ms, 1 second, or 10 seconds; if you need other timing, you'll have to implement it yourself. For example, display effects get updated every 500ms by scheduling a 100ms periodic function, but only acting every 5 calls.
These functions are statically scheduled and so run continuously; you cannot directly start or stop them. However, you can use variables to control whether they do anything or not; but note that there is overhead in calling them all the time.
Precision timing should use realtime functions. They give you the most accurate timing and allow measuring down to 1ms, but they can be high overhead. They should be used carefully when no alternative works.