{ $values { "alarm" alarm } }\r
{ $description "Starts an alarm." } ;\r
\r
+HELP: restart-alarm\r
+{ $values { "alarm" alarm } }\r
+{ $description "Starts or restarts an alarm. Restarting an alarm causes the a sleep of initial delay nanoseconds before looping. An alarm's parameters may be modified and restarted with this word." } ;\r
+\r
HELP: stop-alarm\r
{ $values { "alarm" alarm } }\r
{ $description "Prevents an alarm from calling its quotation again. Has no effect on alarms that are not currently running." } ;\r
"Create an alarm before starting it:"\r
{ $subsections <alarm> }\r
"Starting an alarm:"\r
-{ $subsections start-alarm }\r
+{ $subsections start-alarm restart-alarm }\r
"Stopping an alarm:"\r
{ $subsections stop-alarm }\r
\r
2 seconds sleep stop-alarm\r
1/2 seconds sleep\r
] unit-test\r
+\r
+[ { 0 } ] [\r
+ { 0 }\r
+ dup '[ 1 _ set-first ] 300 milliseconds later\r
+ 150 milliseconds sleep\r
+ [ restart-alarm ] [ 200 milliseconds sleep stop-alarm ] bi\r
+] unit-test\r
+\r
+[ { 1 } ] [\r
+ { 0 }\r
+ dup '[ 0 _ [ 1 + ] change-nth ] 200 milliseconds later\r
+ 100 milliseconds sleep restart-alarm 300 milliseconds sleep\r
+] unit-test\r
+\r
+[ { 4 } ] [\r
+ { 0 }\r
+ dup '[ 0 _ [ 1 + ] change-nth ] 300 milliseconds 300 milliseconds\r
+ <alarm> dup start-alarm\r
+ 700 milliseconds sleep dup restart-alarm\r
+ 700 milliseconds sleep stop-alarm 500 milliseconds sleep\r
+] unit-test\r
interval-nanos
iteration-start-nanos
quotation-running?
+ restart?
thread ;
<PRIVATE
>>iteration-start-nanos ;
: stop-alarm? ( alarm -- ? )
- thread>> self eq? not ;
+ { [ thread>> self eq? not ] [ restart?>> ] } 1|| ;
DEFER: call-alarm-loop
maybe-loop-alarm
] if ;
+: sleep-delay ( alarm -- )
+ nano-count >>start-nanos
+ delay-nanos>> [ sleep ] when* ;
+
+: alarm-loop ( alarm -- )
+ [ sleep-delay ]
+ [ nano-count >>iteration-start-nanos call-alarm-loop ]
+ [ dup restart?>> [ f >>restart? alarm-loop ] [ drop ] if ] tri ;
+
PRIVATE>
: <alarm> ( quot delay-duration/f interval-duration/f -- alarm )
: start-alarm ( alarm -- )
[
- '[
- _ nano-count >>start-nanos
- [ delay-nanos>> [ sleep ] when* ]
- [ nano-count >>iteration-start-nanos call-alarm-loop ] bi
- ] "Alarm execution" spawn
+ '[ _ alarm-loop ] "Alarm execution" spawn
] keep thread<< ;
: stop-alarm ( alarm -- )
[ [ interrupt ] when* f ] change-thread drop
] if ;
+: restart-alarm ( alarm -- )
+ t >>restart? [ stop-alarm ] [ start-alarm ] bi ;
+
<PRIVATE
: (start-alarm) ( quot start-duration interval-duration -- alarm )