| 
									
										
										
										
											2008-02-21 20:12:37 -05:00
										 |  |  | ! Copyright (C) 2005, 2008 Slava Pestov, Doug Coleman. | 
					
						
							| 
									
										
										
										
											2007-11-06 16:51:50 -05:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2008-08-29 11:26:34 -04:00
										 |  |  | USING: accessors arrays calendar combinators generic init | 
					
						
							|  |  |  | kernel math namespaces sequences heaps boxes threads debugger | 
					
						
							|  |  |  | quotations assocs math.order ;
 | 
					
						
							| 
									
										
										
										
											2007-11-06 16:51:50 -05:00
										 |  |  | IN: alarms | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-29 11:26:34 -04:00
										 |  |  | TUPLE: alarm | 
					
						
							|  |  |  |     { quot callable initial: [ ] } | 
					
						
							|  |  |  |     { time timestamp } | 
					
						
							|  |  |  |     interval | 
					
						
							|  |  |  |     { entry box } ;
 | 
					
						
							| 
									
										
										
										
											2007-11-06 16:51:50 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 20:19:21 -05:00
										 |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 21:57:41 -05:00
										 |  |  | SYMBOL: alarms | 
					
						
							|  |  |  | SYMBOL: alarm-thread | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : notify-alarm-thread ( -- )
 | 
					
						
							|  |  |  |     alarm-thread get-global interrupt ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-29 11:26:34 -04:00
										 |  |  | ERROR: bad-alarm-frequency frequency ;
 | 
					
						
							|  |  |  | : check-alarm ( frequency/f -- frequency/f )
 | 
					
						
							|  |  |  |     dup [ duration? ] [ not ] bi or [ bad-alarm-frequency ] unless ;
 | 
					
						
							| 
									
										
										
										
											2007-11-06 16:51:50 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-22 00:47:06 -05:00
										 |  |  | : <alarm> ( quot time frequency -- alarm )
 | 
					
						
							| 
									
										
										
										
											2008-04-13 16:06:27 -04:00
										 |  |  |     check-alarm <box> alarm boa ;
 | 
					
						
							| 
									
										
										
										
											2007-11-06 16:51:50 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 21:57:41 -05:00
										 |  |  | : register-alarm ( alarm -- )
 | 
					
						
							| 
									
										
										
										
											2008-08-29 11:26:34 -04:00
										 |  |  |     dup dup time>> alarms get-global heap-push* | 
					
						
							|  |  |  |     swap entry>> >box | 
					
						
							| 
									
										
										
										
											2008-02-21 21:57:41 -05:00
										 |  |  |     notify-alarm-thread ;
 | 
					
						
							| 
									
										
										
										
											2007-11-06 16:51:50 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 20:12:37 -05:00
										 |  |  | : alarm-expired? ( alarm now -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-08-29 11:26:34 -04:00
										 |  |  |     [ time>> ] dip before=? ;
 | 
					
						
							| 
									
										
										
										
											2007-11-06 16:51:50 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 20:12:37 -05:00
										 |  |  | : reschedule-alarm ( alarm -- )
 | 
					
						
							| 
									
										
										
										
											2008-08-29 11:26:34 -04:00
										 |  |  |     dup [ swap interval>> time+ ] change-time register-alarm ;
 | 
					
						
							| 
									
										
										
										
											2007-11-06 16:51:50 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : call-alarm ( alarm -- )
 | 
					
						
							| 
									
										
										
										
											2008-08-29 11:26:34 -04:00
										 |  |  |     [ entry>> box> drop ] | 
					
						
							|  |  |  |     [ quot>> "Alarm execution" spawn drop ] | 
					
						
							|  |  |  |     [ dup interval>> [ reschedule-alarm ] [ drop ] if ] tri ;
 | 
					
						
							| 
									
										
										
										
											2008-02-21 20:12:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : (trigger-alarms) ( alarms now -- )
 | 
					
						
							|  |  |  |     over heap-empty? [ | 
					
						
							|  |  |  |         2drop
 | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         over heap-peek drop over alarm-expired? [ | 
					
						
							| 
									
										
										
										
											2008-03-03 03:22:27 -05:00
										 |  |  |             over heap-pop drop call-alarm (trigger-alarms) | 
					
						
							| 
									
										
										
										
											2008-02-21 20:12:37 -05:00
										 |  |  |         ] [ | 
					
						
							|  |  |  |             2drop
 | 
					
						
							|  |  |  |         ] if
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : trigger-alarms ( alarms -- )
 | 
					
						
							|  |  |  |     now (trigger-alarms) ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-23 23:29:46 -05:00
										 |  |  | : next-alarm ( alarms -- timestamp/f )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 20:12:37 -05:00
										 |  |  |     dup heap-empty? | 
					
						
							| 
									
										
										
										
											2008-08-29 11:26:34 -04:00
										 |  |  |     [ drop f ] [ heap-peek drop time>> ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-02-21 20:12:37 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | : alarm-thread-loop ( -- )
 | 
					
						
							|  |  |  |     alarms get-global
 | 
					
						
							| 
									
										
										
										
											2008-02-25 07:31:18 -05:00
										 |  |  |     dup next-alarm sleep-until | 
					
						
							| 
									
										
										
										
											2008-03-12 03:36:58 -04:00
										 |  |  |     trigger-alarms ;
 | 
					
						
							| 
									
										
										
										
											2008-02-21 20:12:37 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-22 17:16:00 -05:00
										 |  |  | : cancel-alarms ( alarms -- )
 | 
					
						
							|  |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-08-29 11:26:34 -04:00
										 |  |  |         heap-pop-all [ nip entry>> box> drop ] assoc-each
 | 
					
						
							| 
									
										
										
										
											2008-02-22 17:16:00 -05:00
										 |  |  |     ] when* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 20:12:37 -05:00
										 |  |  | : init-alarms ( -- )
 | 
					
						
							| 
									
										
										
										
											2008-02-22 17:16:00 -05:00
										 |  |  |     alarms global [ cancel-alarms <min-heap> ] change-at
 | 
					
						
							| 
									
										
										
										
											2008-03-12 03:36:58 -04:00
										 |  |  |     [ alarm-thread-loop t ] "Alarms" spawn-server | 
					
						
							| 
									
										
										
										
											2008-02-21 20:12:37 -05:00
										 |  |  |     alarm-thread set-global ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [ init-alarms ] "alarms" add-init-hook | 
					
						
							| 
									
										
										
										
											2008-02-21 20:19:21 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-22 00:47:06 -05:00
										 |  |  | : add-alarm ( quot time frequency -- alarm )
 | 
					
						
							| 
									
										
										
										
											2008-02-21 21:57:41 -05:00
										 |  |  |     <alarm> [ register-alarm ] keep ;
 | 
					
						
							| 
									
										
										
										
											2008-02-21 20:19:21 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-04 19:14:24 -04:00
										 |  |  | : later ( quot duration -- alarm )
 | 
					
						
							| 
									
										
										
										
											2008-07-08 16:50:38 -04:00
										 |  |  |     hence f add-alarm ;
 | 
					
						
							| 
									
										
										
										
											2008-02-22 00:47:06 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-04 19:14:24 -04:00
										 |  |  | : every ( quot duration -- alarm )
 | 
					
						
							| 
									
										
										
										
											2008-07-08 16:50:38 -04:00
										 |  |  |     [ hence ] keep add-alarm ;
 | 
					
						
							| 
									
										
										
										
											2008-03-07 17:59:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-21 20:19:21 -05:00
										 |  |  | : cancel-alarm ( alarm -- )
 | 
					
						
							| 
									
										
										
										
											2008-08-29 11:26:34 -04:00
										 |  |  |     entry>> [ alarms get-global heap-delete ] if-box? ;
 |