f063defdbe60834dd1cf3c7a6fc55980560e5c6b
[projects/chimara/chimara.git] / libchimara / timer.c
1 #include "timer.h"
2
3 extern ChimaraGlkPrivate *glk_data;
4
5 /**
6  * glk_request_timer_events:
7  * @millisecs: Interval in milliseconds to request timer events for, or 0 to
8  * stop timer events.
9  *
10  * Initially, there is no timer and you get no timer events. If you call
11  * <code>glk_request_timer_events(<emphasis>N</emphasis>)</code>, with 
12  * <emphasis>N</emphasis> not 0, you will get timer events about every 
13  * <emphasis>N</emphasis> milliseconds thereafter. (Assuming that they are 
14  * supported &mdash; if not, glk_request_timer_events() has no effect.) Unlike 
15  * keyboard and mouse events, timer events will continue until you shut them 
16  * off. You do not have to re-request them every time you get one. Call 
17  * <code>glk_request_timer_events(0)</code> to stop getting timer events. 
18  *
19  * The rule is that when you call glk_select() or glk_select_poll(), if it has
20  * been more than <emphasis>N</emphasis> milliseconds since the last timer 
21  * event, and (for glk_select()) if there is no player input, you will receive 
22  * an event whose type is %evtype_Timer. (@win, @val1, and @val2 will all be 0.) 
23  *
24  * Timer events do not stack up. If you spend 10<emphasis>N</emphasis> 
25  * milliseconds doing computation, and then call glk_select(), you will not get 
26  * ten timer events in a row. The library will simply note that it has been more
27  * than <emphasis>N</emphasis> milliseconds, and return a timer event right 
28  * away. If you call glk_select() again immediately, it will be 
29  * <emphasis>N</emphasis> milliseconds before the next timer event. 
30  *
31  * This means that the timing of timer events is approximate, and the library
32  * will err on the side of being late. If there is a conflict between player
33  * input events and timer events, the player input takes precedence.
34  * <note><para>
35  *  This prevents the user from being locked out by overly enthusiastic timer 
36  *  events. Unfortunately, it also means that your timer can be locked out on 
37  *  slower machines, if the player pounds too enthusiastically on the keyboard. 
38  *  Sorry. If you want a real-time operating system, talk to Wind River.
39  * </para></note>
40  *
41  * <note><para>
42  *  I don't have to tell you that a millisecond is one thousandth of a second,
43  *  do I?
44  * </para></note>
45  */
46 void
47 glk_request_timer_events(glui32 millisecs)
48 {
49         // Stop any existing timer
50         if(glk_data->timer_id != 0) {
51                 g_source_remove(glk_data->timer_id);
52                 glk_data->timer_id = 0;
53         }
54
55         if(millisecs == 0)
56                 return;
57         
58         glk_data->timer_id = g_timeout_add(millisecs, push_timer_event, NULL);
59 }
60
61 /*
62  * Internal function: push a new timer event on the event stack.
63  * Will always return TRUE
64  */
65 gboolean
66 push_timer_event(gpointer data)
67 {
68         event_throw(evtype_Timer, NULL, 0, 0);
69
70         return TRUE;
71 }