Mercurial > MadButterfly
comparison src/timer.c @ 39:db2aa914e14b
timer for animation
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Wed, 06 Aug 2008 21:05:11 +0800 |
parents | |
children | 400b4b5db0dc |
comparison
equal
deleted
inserted
replaced
38:8d219ebd729e | 39:db2aa914e14b |
---|---|
1 #include <stdio.h> | |
2 #include <stdint.h> | |
3 #include <stdlib.h> | |
4 #include "mb_timer.h" | |
5 #include "tools.h" | |
6 | |
7 | |
8 #define OK 0 | |
9 #define ERR -1 | |
10 | |
11 struct _mb_timer { | |
12 mbsec_t sec; | |
13 mbusec_t usec; | |
14 mb_tmo_hdlr hdlr; | |
15 void *arg; | |
16 mb_timer_t *next; | |
17 }; | |
18 | |
19 struct _mb_tman { | |
20 STAILQ(mb_timer_t) timers; | |
21 elmpool_t *timer_pool; | |
22 }; | |
23 | |
24 mb_tman_t *mb_tman_new(void) { | |
25 mb_tman_t *tman; | |
26 | |
27 tman = (mb_tman_t *)malloc(sizeof(mb_tman_t)); | |
28 if(tman == NULL) | |
29 return NULL; | |
30 | |
31 tman->timer_pool = elmpool_new(sizeof(mb_timer_t), 32); | |
32 if(tman->timer_pool == NULL) { | |
33 free(tman); | |
34 return NULL; | |
35 } | |
36 | |
37 STAILQ_INIT(tman->timers); | |
38 | |
39 return tman; | |
40 } | |
41 | |
42 void mb_tman_free(mb_tman_t *tman) { | |
43 elmpool_free(tman->timer_pool); | |
44 free(tman); | |
45 } | |
46 | |
47 mb_timer_t *mb_tman_timeout(mb_tman_t *tman, | |
48 mbsec_t sec, mbusec_t usec, | |
49 mb_tmo_hdlr hdlr, void *arg) { | |
50 mb_timer_t *timer, *visit, *last; | |
51 | |
52 timer = elmpool_elm_alloc(tman->timer_pool); | |
53 if(timer == NULL) | |
54 return NULL; | |
55 | |
56 timer->sec = sec; | |
57 timer->usec = usec; | |
58 timer->hdlr = hdlr; | |
59 timer->arg = arg; | |
60 | |
61 last = NULL; | |
62 for(visit = STAILQ_HEAD(tman->timers); | |
63 visit != NULL; | |
64 visit = STAILQ_NEXT(mb_timer_t, next, visit)) { | |
65 if(sec < visit->sec) | |
66 break; | |
67 if(sec == visit->sec && usec < visit->usec) | |
68 break; | |
69 last = visit; | |
70 } | |
71 | |
72 if(last == NULL) | |
73 STAILQ_INS(tman->timers, mb_timer_t, next, timer); | |
74 else if(visit == NULL) | |
75 STAILQ_INS_TAIL(tman->timers, mb_timer_t, next, timer); | |
76 else | |
77 STAILQ_INS_AFTER(mb_timer_t, next, timer, last); | |
78 | |
79 return timer; | |
80 } | |
81 | |
82 int mb_tman_remove(mb_tman_t *tman, mb_timer_t *timer) { | |
83 STAILQ_REMOVE(tman->timers, mb_timer_t, next, timer); | |
84 elmpool_elm_free(tman->timer_pool, timer); | |
85 | |
86 return OK; | |
87 } | |
88 | |
89 int mb_tman_next_timeout(mb_tman_t *tman, | |
90 mbsec_t now_sec, mbusec_t now_usec, | |
91 mbsec_t *after_sec, mbusec_t *after_usec) { | |
92 mb_timer_t *timer; | |
93 | |
94 timer = STAILQ_HEAD(tman->timers); | |
95 if(timer == NULL) | |
96 return ERR; | |
97 | |
98 if(now_sec > timer->sec || | |
99 (now_sec == timer->usec && now_usec >= timer->usec)) { | |
100 *after_sec = 0; | |
101 *after_usec = 0; | |
102 return OK; | |
103 } | |
104 | |
105 *after_sec = timer->sec - now_sec; | |
106 if(now_usec > timer->usec) { | |
107 --*after_sec; | |
108 *after_usec = 1000000 + timer->usec - now_usec; | |
109 } else | |
110 *after_usec = timer->usec - now_usec; | |
111 | |
112 return OK; | |
113 } | |
114 | |
115 int mb_tman_handle_timeout(mb_tman_t *tman, | |
116 mbsec_t now_sec, mbusec_t now_usec) { | |
117 mb_timer_t *timer; | |
118 | |
119 while((timer = STAILQ_HEAD(tman->timers)) != NULL){ | |
120 if(now_sec < timer->sec || | |
121 (now_sec == timer->sec && now_usec < timer->usec)) | |
122 break; | |
123 timer->hdlr(timer->sec, timer->usec, | |
124 now_sec, now_usec, | |
125 timer->arg); | |
126 STAILQ_REMOVE(tman->timers, mb_timer_t, next, timer); | |
127 elmpool_elm_free(tman->timer_pool, timer); | |
128 } | |
129 | |
130 return OK; | |
131 } |