Mercurial > MadButterfly
comparison src/animate.c @ 46:46b77c92d118
Rewrite mb_progm_step()
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Sat, 09 Aug 2008 16:33:33 +0800 |
parents | 83ee36f19210 |
children | f3818d996f4f |
comparison
equal
deleted
inserted
replaced
45:83ee36f19210 | 46:46b77c92d118 |
---|---|
36 /*! \brief A program describe a series of actions to animate shapes. | 36 /*! \brief A program describe a series of actions to animate shapes. |
37 */ | 37 */ |
38 struct _mb_progm { | 38 struct _mb_progm { |
39 redraw_man_t *rdman; | 39 redraw_man_t *rdman; |
40 | 40 |
41 mb_timeval_t start_time, last_time; | 41 mb_timeval_t start_time; |
42 int first_playing; /*!< first playing word. */ | 42 int first_playing; /*!< first playing word. */ |
43 mb_tman_t *tman; | 43 mb_tman_t *tman; |
44 | 44 |
45 int n_words; | 45 int n_words; |
46 int max_words; | 46 int max_words; |
155 act = STAILQ_NEXT(mb_action_t, next, act)) { | 155 act = STAILQ_NEXT(mb_action_t, next, act)) { |
156 act->stop(act, tmo, rdman); | 156 act->stop(act, tmo, rdman); |
157 } | 157 } |
158 } | 158 } |
159 | 159 |
160 /* | |
161 * Any two actions in concurrent words never change the same attribute. | |
162 * Start time of words in a program are specified in incremental order. | |
163 */ | |
160 static void mb_progm_step(const mb_timeval_t *tmo, | 164 static void mb_progm_step(const mb_timeval_t *tmo, |
161 const mb_timeval_t *now, | 165 const mb_timeval_t *now, |
162 void *arg) { | 166 void *arg) { |
163 mb_progm_t *progm = (mb_progm_t *)arg; | 167 mb_progm_t *progm = (mb_progm_t *)arg; |
164 mb_timeval_t next_tmo, w_stp_tm; | 168 mb_timeval_t next_tmo, word_stop; |
165 mb_timeval_t tmo_diff, next_diff; | 169 mb_timeval_t tmo_diff, next_diff; |
166 mb_word_t *word; | 170 mb_word_t *word; |
167 mb_timer_t *timer; | 171 mb_timer_t *timer; |
168 int i; | 172 int i; |
169 | 173 |
170 MB_TIMEVAL_CP(&tmo_diff, tmo); | 174 MB_TIMEVAL_CP(&tmo_diff, tmo); |
171 MB_TIMEVAL_DIFF(&tmo_diff, &progm->start_time); | 175 MB_TIMEVAL_DIFF(&tmo_diff, &progm->start_time); |
172 | 176 |
177 MB_TIMEVAL_SET(&next_diff, 0, STEP_INTERVAL); | |
178 MB_TIMEVAL_ADD(&next_diff, &tmo_diff); | |
179 | |
173 i = progm->first_playing; | 180 i = progm->first_playing; |
174 for(word = progm->words + i; | 181 for(word = progm->words + i; |
175 i < progm->n_words && MB_TIMEVAL_LATER(&tmo_diff, &word->start_time); | 182 i < progm->n_words && |
183 MB_TIMEVAL_LATER(&tmo_diff, &word->start_time); | |
176 word = progm->words + ++i) { | 184 word = progm->words + ++i) { |
177 MB_TIMEVAL_CP(&w_stp_tm, &progm->start_time); | 185 MB_TIMEVAL_CP(&word_stop, &word->start_time); |
178 MB_TIMEVAL_ADD(&w_stp_tm, &word->start_time); | 186 MB_TIMEVAL_ADD(&word_stop, &word->playing_time); |
179 MB_TIMEVAL_ADD(&w_stp_tm, &word->playing_time); | 187 if(MB_TIMEVAL_LATER(&next_diff, &word_stop)) |
180 if(MB_TIMEVAL_LATER(&w_stp_tm, tmo)) | 188 mb_word_stop(word, tmo, now, progm->rdman); |
189 else | |
181 mb_word_step(word, tmo, now, progm->rdman); | 190 mb_word_step(word, tmo, now, progm->rdman); |
182 else { | 191 } |
183 if(MB_TIMEVAL_LATER(&w_stp_tm, &progm->last_time)) | 192 |
184 mb_word_stop(word, tmo, now, progm->rdman); | |
185 if(i == progm->first_playing) | |
186 progm->first_playing++; | |
187 } | |
188 } | |
189 | |
190 MB_TIMEVAL_SET(&next_tmo, 0, STEP_INTERVAL); | |
191 MB_TIMEVAL_ADD(&next_tmo, tmo); | |
192 | |
193 MB_TIMEVAL_CP(&next_diff, &next_tmo); | |
194 MB_TIMEVAL_DIFF(&next_diff, &progm->start_time); | |
195 for(word = progm->words + i; | 193 for(word = progm->words + i; |
196 i < progm->n_words && MB_TIMEVAL_LATER(&next_diff, &word->start_time); | 194 i < progm->n_words && |
195 MB_TIMEVAL_LATER(&next_diff, &word->start_time); | |
197 word = progm->words + ++i) { | 196 word = progm->words + ++i) { |
198 mb_word_start(word, tmo, now, progm->rdman); | 197 mb_word_start(word, tmo, now, progm->rdman); |
199 } | 198 MB_TIMEVAL_CP(&word_stop, &word->start_time); |
200 | 199 MB_TIMEVAL_ADD(&word_stop, &word->playing_time); |
201 /* Setup next timeout. */ | 200 if(MB_TIMEVAL_LATER(&next_diff, &word_stop)) |
201 mb_word_stop(word, tmo, now, progm->rdman); | |
202 } | |
203 | |
204 i = progm->first_playing; | |
205 for(word = progm->words + i; | |
206 i < progm->n_words && | |
207 MB_TIMEVAL_LATER(&next_diff, &word->start_time); | |
208 word = progm->words + ++i) { | |
209 MB_TIMEVAL_CP(&word_stop, &word->start_time); | |
210 MB_TIMEVAL_ADD(&word_stop, &word->playing_time); | |
211 if(!MB_TIMEVAL_LATER(&next_diff, &word_stop)) | |
212 break; | |
213 progm->first_playing++; | |
214 } | |
215 | |
202 if(progm->first_playing < progm->n_words) { | 216 if(progm->first_playing < progm->n_words) { |
203 word = progm->words + progm->first_playing; | 217 word = progm->words + progm->first_playing; |
204 MB_TIMEVAL_CP(&w_stp_tm, &word->start_time); | 218 if(MB_TIMEVAL_LATER(&word->start_time, &next_diff)) { |
205 MB_TIMEVAL_ADD(&w_stp_tm, &progm->start_time); | 219 MB_TIMEVAL_CP(&next_tmo, &word->start_time); |
206 | 220 MB_TIMEVAL_ADD(&next_tmo, &progm->start_time); |
207 if(MB_TIMEVAL_LATER(&w_stp_tm, &next_tmo)) | 221 } else { |
208 timer = mb_tman_timeout(progm->tman, &w_stp_tm, | 222 MB_TIMEVAL_CP(&next_tmo, &next_diff); |
209 mb_progm_step, progm); | 223 MB_TIMEVAL_ADD(&next_tmo, &progm->start_time); |
210 else | 224 } |
211 timer = mb_tman_timeout(progm->tman, &next_tmo, | 225 timer = mb_tman_timeout(progm->tman, &next_tmo, |
212 mb_progm_step, progm); | 226 mb_progm_step, progm); |
213 ASSERT(timer != NULL); | 227 } |
214 } | |
215 | |
216 MB_TIMEVAL_CP(&progm->last_time, tmo); | |
217 } | 228 } |
218 | 229 |
219 void mb_progm_start(mb_progm_t *progm, mb_tman_t *tman, | 230 void mb_progm_start(mb_progm_t *progm, mb_tman_t *tman, |
220 mb_timeval_t *now) { | 231 mb_timeval_t *now) { |
221 mb_timeval_t next_time; | 232 mb_timeval_t next_time; |
224 if(progm->n_words == 0) | 235 if(progm->n_words == 0) |
225 return; | 236 return; |
226 | 237 |
227 progm->tman = tman; | 238 progm->tman = tman; |
228 MB_TIMEVAL_CP(&progm->start_time, now); | 239 MB_TIMEVAL_CP(&progm->start_time, now); |
229 MB_TIMEVAL_CP(&progm->last_time, now); | |
230 progm->first_playing = 0; | 240 progm->first_playing = 0; |
231 | 241 |
232 MB_TIMEVAL_CP(&next_time, &progm->words[0].start_time); | 242 MB_TIMEVAL_CP(&next_time, &progm->words[0].start_time); |
233 MB_TIMEVAL_ADD(&next_time, now); | 243 MB_TIMEVAL_ADD(&next_time, now); |
234 if(!MB_TIMEVAL_LATER(&next_time, now)) { | 244 if(!MB_TIMEVAL_LATER(&next_time, now)) { |