X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=libchimara%2Ftimer.c;fp=libchimara%2Ftimer.c;h=8d2087af9e87120c2fcee985965c6909bc0ec472;hb=78652af29a2f39e626febd5f4213da57d3a13901;hp=0000000000000000000000000000000000000000;hpb=91214934fbcdfd363202a65c142194506604ff7b;p=projects%2Fchimara%2Fchimara.git diff --git a/libchimara/timer.c b/libchimara/timer.c new file mode 100644 index 0000000..8d2087a --- /dev/null +++ b/libchimara/timer.c @@ -0,0 +1,67 @@ +#include "timer.h" + +extern ChimaraGlkPrivate *glk_data; + +/** + * You can request that an event be sent at fixed intervals, regardless of what + * the player does. Unlike input events, timer events can be tested for with + * glk_select_poll() as well as glk_select(). + * + * Initially, there is no timer and you get no timer events. If you call + * glk_request_timer_events(N), with N not 0, you will get timer events about + * every N milliseconds thereafter. (Assuming that they are supported -- if + * not, glk_request_timer_events() has no effect.) Unlike keyboard and mouse + * events, timer events will continue until you shut them off. You do not have + * to re-request them every time you get one. Call glk_request_timer_events(0) + * to stop getting timer events. + * + * The rule is that when you call glk_select() or glk_select_poll(), if it has + * been more than N milliseconds since the last timer event, and (for + * glk_select()) if there is no player input, you will receive an event whose + * type is evtype_Timer. (win, val1, and val2 will all be 0.) + * + * Timer events do not stack up. If you spend 10N milliseconds doing + * computation, and then call glk_select(), you will not get ten timer events + * in a row. The library will simply note that it has been more than N + * milliseconds, and return a timer event right away. If you call glk_select() + * again immediately, it will be N milliseconds before the next timer event. + * + * This means that the timing of timer events is approximate, and the library + * will err on the side of being late. If there is a conflict between player + * input events and timer events, the player input takes precedence. [This + * prevents the user from being locked out by overly enthusiastic timer events. + * Unfortunately, it also means that your timer can be locked out on slower + * machines, if the player pounds too enthusiastically on the keyboard. Sorry. + * If you want a real-time operating system, talk to Wind River.] + * + * [I don't have to tell you that a millisecond is one thousandth of a second, + * do I?] + * + * NOTE: setting a new timer will overwrite the old timer if one was in place. + */ +void +glk_request_timer_events(glui32 millisecs) +{ + // Stop any existing timer + if(glk_data->timer_id != 0) { + g_source_remove(glk_data->timer_id); + glk_data->timer_id = 0; + } + + if(millisecs == 0) + return; + + glk_data->timer_id = g_timeout_add(millisecs, push_timer_event, NULL); +} + +/** + * Internal function: push a new timer event on the event stack. + * Will always return TRUE + */ +gboolean +push_timer_event(gpointer data) +{ + event_throw(evtype_Timer, NULL, 0, 0); + + return TRUE; +}