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