| Minerva supports timer handling.
There exist a small set of predicates to support timer handling.
- timer_create/2
- timer_close/2
- timer_start/2
- timer_stop/1
- timer_is_active/1
A timer can be created, deleted, started, stopped and the state of a timer
(running or not running) can be checked. There is a user defined callback
predicate, that can be bound to a timer. When a timer runs down, then this
callback predicate will be called. Each timer is implemented as a thread.
So timer callbacks may be fired asynchronously. However, there is no
multithreading support in Minerva, that is: at any time Minerva
can only execute one goal. Only when the execution of one goal has
been finished another goal (maybe called from another thread) may be executed.
Therefore, if you need timer support, then your program should have the following
structure:
main(..) :-
...
timer_create(mycallback(_,...), Timer),
...
timer_start(Timer, T).
mycallback(Timer, ...) :-
...
When executing your program you have to call Minerva with the program flag
-daemon. This prevents, that Minerva stops execution when
the main/1 predicate has been executed. Minerva will only be
stopped when all of his threads have been stopped.
Example
main(_) :- ticker.
ticker :-
set_global(ticker, 10),
% create a timer, that should call tick/1 when running down
timer_create(tick(_), Timer),
% start the timer ...
timer_start(Timer, 1000).
% ... and (very important!!) ... stop the execution of main/1
tick(Timer) :-
count_down(ticker, N),
( N > 0 ->
% write 'tick' ...
write(tick), nl,
% .. and restart the timer ...
timer_start(Timer, 1000)
% ... and (very important!!) ... stop the execution of tick/1
% as the execution of the callback predicate will be pending
% until the execution of tick/1 has been finished
; timer_close(Timer)
).
count_down(Counter, Value) :-
get_global(Counter, OldValue),
Value is OldValue - 1,
set_global(Counter, Value).
|