Wrote platform-dependent dispatch code
[rodin/chimara.git] / libchimara / timer.c
1 #include "timer.h"
2
3 extern GPrivate *glk_data_key;
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         ChimaraGlkPrivate *glk_data = g_private_get(glk_data_key);
50         
51         // Stop any existing timer
52         if(glk_data->timer_id != 0) {
53                 g_source_remove(glk_data->timer_id);
54                 glk_data->timer_id = 0;
55         }
56
57         if(millisecs == 0)
58                 return;
59         
60         glk_data->timer_id = g_timeout_add(millisecs, (GSourceFunc)push_timer_event, glk_data->self);
61 }
62
63 /*
64  * Internal function: push a new timer event on the event stack.
65  * Will always return TRUE
66  */
67 gboolean
68 push_timer_event(ChimaraGlk *glk)
69 {
70         event_throw(glk, evtype_Timer, NULL, 0, 0);
71
72         return TRUE;
73 }