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)) {