1 ! Copyright (C) 2005, 2008 Slava Pestov, Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
4 USING: accessors calendar fry kernel math quotations system
10 { quot callable initial: [ ] }
19 GENERIC: >nanoseconds ( obj -- duration/f )
21 M: real >nanoseconds >integer ;
22 M: duration >nanoseconds duration>nanoseconds >integer ;
24 : delay-nanos ( timer -- n )
25 delay-nanos>> 0 or nano-count + ;
27 : interval-nanos ( timer -- n/f )
28 [ next-nanos>> nano-count over - ] [ interval-nanos>> ] bi
29 [ dupd [ mod ] [ swap - ] bi + + ] [ 2drop f ] if* ;
31 : next-nanos ( timer -- timer n/f )
32 dup thread>> self eq? [ dup next-nanos>> ] [ f ] if ;
34 : run-timer ( timer -- timer )
35 dup interval-nanos >>next-nanos
36 t >>quotation-running?
38 f >>quotation-running? ;
40 : timer-loop ( timer -- )
47 ] while* dup thread>> self eq? [ f >>thread ] when drop ;
49 : ?interrupt ( thread timer -- )
50 quotation-running?>> [ drop ] [ [ interrupt ] when* ] if ;
54 ERROR: timer-already-started timer ;
56 : <timer> ( quot delay-duration/f interval-duration/f -- timer )
58 swap >nanoseconds >>interval-nanos
59 swap >nanoseconds >>delay-nanos
62 : start-timer ( timer -- )
63 dup thread>> [ timer-already-started ] when
64 dup delay-nanos >>next-nanos
65 dup '[ _ timer-loop ] "Timer" <thread>
66 [ >>thread drop ] [ (spawn) ] bi ;
68 : stop-timer ( timer -- )
69 [ f ] change-thread ?interrupt ;
71 : restart-timer ( timer -- )
73 dup delay-nanos >>next-nanos
74 [ thread>> ] [ ?interrupt ] bi
81 : (start-timer) ( quot start-duration interval-duration -- timer )
82 <timer> [ start-timer ] keep ; inline
86 : every ( quot interval-duration -- timer )
87 f swap (start-timer) ;
89 : later ( quot delay-duration -- timer )
92 : delayed-every ( quot duration -- timer )