comparison src/animate.c @ 1044:5d4bc2a93c09

Merge from refine_backend_if branch
author Thinker K.F. Li <thinker@codemud.net>
date Tue, 23 Nov 2010 11:58:04 +0800
parents 63f2f1daf5d3
children e415c55b4a0d
comparison
equal deleted inserted replaced
1035:18329b6f77a4 1044:5d4bc2a93c09
24 * called periodically in duration of playing time start at 24 * called periodically in duration of playing time start at
25 * 'start time'. When the clock run out the playing time of 25 * 'start time'. When the clock run out the playing time of
26 * a word, it call stop of actions in the word. 26 * a word, it call stop of actions in the word.
27 * 27 *
28 * A program is driven by a timer. Once a program is started, it registers 28 * A program is driven by a timer. Once a program is started, it registers
29 * with timer for periodic running. \ref mb_tman_t is timer of 29 * with timer for periodic running. \ref mb_timer_man_t is timer of
30 * MadButterfly. The update frequence is 10fps by default, now. 30 * MadButterfly. The update frequence is 10fps by default, now.
31 * 31 *
32 * \section use_progm How to Use Animation Program? 32 * \section use_progm How to Use Animation Program?
33 * Following code block creates a program with 2 words. First word is 33 * Following code block creates a program with 2 words. First word is
34 * started immediately after the program been started. It is consisted 34 * started immediately after the program been started. It is consisted
59 * act = mb_shift_new(0, -20, coord2, word); 59 * act = mb_shift_new(0, -20, coord2, word);
60 * act = mb_visibility_new(VIS_HIDDEN, coord3, word); 60 * act = mb_visibility_new(VIS_HIDDEN, coord3, word);
61 * 61 *
62 * gettimeofday(&tv, NULL); 62 * gettimeofday(&tv, NULL);
63 * MB_TIMEVAL_SET(&mbtv, tv.tv_sec, tv.tv_usec); 63 * MB_TIMEVAL_SET(&mbtv, tv.tv_sec, tv.tv_usec);
64 * mb_progm_start(progm, tman, &mbtv); 64 * mb_progm_start(progm, timer_man, &mbtv);
65 * \endcode 65 * \endcode
66 * 66 *
67 * 67 *
68 * \sa \ref animate.c 68 * \sa \ref animate.c
69 */ 69 */
96 struct _mb_progm { 96 struct _mb_progm {
97 redraw_man_t *rdman; 97 redraw_man_t *rdman;
98 98
99 mb_timeval_t start_time; 99 mb_timeval_t start_time;
100 int first_playing; /*!< first playing word. */ 100 int first_playing; /*!< first playing word. */
101 mb_tman_t *tman; 101 mb_timer_man_t *timer_man;
102 subject_t *complete; /*!< notify when a program is completed. */ 102 subject_t *complete; /*!< notify when a program is completed. */
103 mb_timer_t *cur_timer; 103 int cur_timer;
104 104
105 int n_words; 105 int n_words;
106 int max_words; 106 int max_words;
107 mb_word_t words[1]; 107 mb_word_t words[1];
108 }; 108 };
137 137
138 progm->n_words = 0; 138 progm->n_words = 0;
139 progm->max_words = max_words; 139 progm->max_words = max_words;
140 for(i = 0; i < max_words; i++) 140 for(i = 0; i < max_words; i++)
141 STAILQ_INIT(progm->words[i].actions); 141 STAILQ_INIT(progm->words[i].actions);
142 progm->cur_timer = -1;
142 return progm; 143 return progm;
143 } 144 }
144 145
145 void mb_progm_free(mb_progm_t *progm) { 146 void mb_progm_free(mb_progm_t *progm) {
146 int n_words; 147 int n_words;
231 * \note Program will take a big step at last monent. It is because 232 * \note Program will take a big step at last monent. It is because
232 * mb_progm_step() running mb_word_stop() if the word being stop 233 * mb_progm_step() running mb_word_stop() if the word being stop
233 * between now and next_tmo. It is not obviously if time stepping 234 * between now and next_tmo. It is not obviously if time stepping
234 * small. 235 * small.
235 */ 236 */
236 static void mb_progm_step(const mb_timeval_t *tmo, 237 static void mb_progm_step(int timer_hdl,
238 const mb_timeval_t *tmo,
237 const mb_timeval_t *now, 239 const mb_timeval_t *now,
238 void *arg) { 240 void *arg) {
239 mb_progm_t *progm = (mb_progm_t *)arg; 241 mb_progm_t *progm = (mb_progm_t *)arg;
240 #ifndef UNITTEST 242 #ifndef UNITTEST
241 /*! \todo Leverage aspective programming to prevent problem of unittest. 243 /*! \todo Leverage aspective programming to prevent problem of unittest.
287 /* Setup timeout for next update. */ 289 /* Setup timeout for next update. */
288 if(progm->first_playing < progm->n_words) { 290 if(progm->first_playing < progm->n_words) {
289 word = progm->words + progm->first_playing; 291 word = progm->words + progm->first_playing;
290 if(MB_TIMEVAL_LATER(&word->abs_start, &next_tmo)) 292 if(MB_TIMEVAL_LATER(&word->abs_start, &next_tmo))
291 MB_TIMEVAL_CP(&next_tmo, &word->abs_start); 293 MB_TIMEVAL_CP(&next_tmo, &word->abs_start);
292 timer = mb_tman_timeout(progm->tman, &next_tmo, 294 timer = mb_timer_man_timeout(progm->timer_man, &next_tmo,
293 mb_progm_step, progm); 295 mb_progm_step, progm);
294 progm->cur_timer = timer; 296 progm->cur_timer = timer;
295 } else { 297 } else {
296 /* Make program to complete. */ 298 /* Make program to complete. */
297 #ifndef UNITTEST 299 #ifndef UNITTEST
298 comp_evt.event.type = EVT_PROGM_COMPLETE; 300 comp_evt.event.type = EVT_PROGM_COMPLETE;
299 comp_evt.event.tgt = comp_evt.event.cur_tgt = progm->complete; 301 comp_evt.event.tgt = comp_evt.event.cur_tgt = progm->complete;
300 comp_evt.progm = progm; 302 comp_evt.progm = progm;
301 subject_notify(progm->complete, &comp_evt.event); 303 subject_notify(progm->complete, &comp_evt.event);
302 #endif /* UNITTEST */ 304 #endif /* UNITTEST */
303 progm->cur_timer = NULL; 305 progm->cur_timer = -1;
304 } 306 }
305 } 307 }
306 308
307 void mb_progm_start(mb_progm_t *progm, mb_tman_t *tman, 309 void mb_progm_start(mb_progm_t *progm, mb_timer_man_t *timer_man,
308 mb_timeval_t *now) { 310 mb_timeval_t *now) {
309 mb_timer_t *timer; 311 int timer;
310 mb_word_t *word; 312 mb_word_t *word;
311 int i; 313 int i;
312 314
313 if(progm->n_words == 0) 315 if(progm->n_words == 0)
314 return; 316 return;
315 317
316 progm->tman = tman; 318 progm->timer_man = timer_man;
317 MB_TIMEVAL_CP(&progm->start_time, now); 319 MB_TIMEVAL_CP(&progm->start_time, now);
318 progm->first_playing = 0; 320 progm->first_playing = 0;
319 321
320 for(i = 0; i < progm->n_words; i++) { 322 for(i = 0; i < progm->n_words; i++) {
321 word = progm->words + i; 323 word = progm->words + i;
324 MB_TIMEVAL_CP(&word->abs_stop, &word->abs_start); 326 MB_TIMEVAL_CP(&word->abs_stop, &word->abs_start);
325 MB_TIMEVAL_ADD(&word->abs_stop, &word->playing_time); 327 MB_TIMEVAL_ADD(&word->abs_stop, &word->playing_time);
326 } 328 }
327 329
328 if(MB_TIMEVAL_EQ(&progm->words[0].abs_start, now)) { 330 if(MB_TIMEVAL_EQ(&progm->words[0].abs_start, now)) {
329 mb_progm_step(now, now, progm); 331 mb_progm_step(-1, now, now, progm);
330 return; 332 return;
331 } 333 }
332 334
333 timer = mb_tman_timeout(tman, &progm->words[0].abs_start, 335 timer = mb_timer_man_timeout(timer_man, &progm->words[0].abs_start,
334 mb_progm_step, progm); 336 mb_progm_step, progm);
335 ASSERT(timer != NULL); 337 ASSERT(timer != -1);
336 338
337 /* We need timer to abort it. */ 339 /* We need timer to abort it. */
338 progm->cur_timer = timer; 340 progm->cur_timer = timer;
339 } 341 }
340 342
341 void mb_progm_finish(mb_progm_t *progm) { 343 void mb_progm_finish(mb_progm_t *progm) {
342 mb_timeval_t infi; 344 mb_timeval_t infi;
343 345
344 mb_progm_abort(progm); 346 mb_progm_abort(progm);
345 MB_TIMEVAL_SET(&infi, 0x7fffffff,0); 347 MB_TIMEVAL_SET(&infi, 0x7fffffff,0);
346 mb_progm_step(&progm->start_time, &infi,progm); 348 mb_progm_step(-1, &progm->start_time, &infi,progm);
347 } 349 }
348 void mb_progm_abort(mb_progm_t *progm) { 350 void mb_progm_abort(mb_progm_t *progm) {
349 /*! \todo Make sure abort release resources. */ 351 /*! \todo Make sure abort release resources. */
350 if(progm->cur_timer) { 352 if(progm->cur_timer != -1) {
351 mb_tman_remove(progm->tman, progm->cur_timer); 353 mb_timer_man_remove(progm->timer_man, progm->cur_timer);
352 progm->cur_timer = NULL; 354 progm->cur_timer = -1;
353 } 355 }
354 } 356 }
355 357
356 /*! \brief Return event subject for completion of a program. 358 /*! \brief Return event subject for completion of a program.
357 */ 359 */
373 subject_add_observer(complete, _free_completed_hdlr, progm); 375 subject_add_observer(complete, _free_completed_hdlr, progm);
374 } 376 }
375 377
376 #ifdef UNITTEST 378 #ifdef UNITTEST
377 379
380 #include "mb_backend_utils.h"
378 #include <CUnit/Basic.h> 381 #include <CUnit/Basic.h>
379 382
380 typedef struct _mb_dummy mb_dummy_t; 383 typedef struct _mb_dummy mb_dummy_t;
381 384
382 struct _mb_dummy { 385 struct _mb_dummy {
439 442
440 void test_animate_words(void) { 443 void test_animate_words(void) {
441 mb_progm_t *progm; 444 mb_progm_t *progm;
442 mb_word_t *word; 445 mb_word_t *word;
443 mb_action_t *acts[4]; 446 mb_action_t *acts[4];
447 mb_timer_man_t *timer_man;
444 mb_tman_t *tman; 448 mb_tman_t *tman;
445 mb_timeval_t tv1, tv2, now, tmo_after; 449 mb_timeval_t tv1, tv2, now, tmo_after;
446 int logcnt = 0; 450 int logcnt = 0;
447 int logs[256]; 451 int logs[256];
448 int r; 452 int r;
449 453
450 tman = mb_tman_new(); 454 timer_man = mb_timer_man_new(&tman_timer_factory);
451 CU_ASSERT(tman != NULL); 455 CU_ASSERT(timer_man != -1);
456
457 tman = tman_timer_man_get_tman(timer_man);
452 458
453 progm = mb_progm_new(3, NULL); 459 progm = mb_progm_new(3, NULL);
454 CU_ASSERT(progm != NULL); 460 CU_ASSERT(progm != NULL);
455 461
456 MB_TIMEVAL_SET(&tv1, 1, 0); 462 MB_TIMEVAL_SET(&tv1, 1, 0);
473 CU_ASSERT(word != NULL); 479 CU_ASSERT(word != NULL);
474 acts[2] = mb_dummy_new(2, &logcnt, logs, word); 480 acts[2] = mb_dummy_new(2, &logcnt, logs, word);
475 CU_ASSERT(acts[2] != NULL); 481 CU_ASSERT(acts[2] != NULL);
476 482
477 MB_TIMEVAL_SET(&now, 0, 0); 483 MB_TIMEVAL_SET(&now, 0, 0);
478 mb_progm_start(progm, tman, &now); 484 mb_progm_start(progm, timer_man, &now);
479 485
480 r = mb_tman_next_timeout(tman, &now, &tmo_after); 486 r = mb_tman_next_timeout(tman, &now, &tmo_after);
481 CU_ASSERT(r == 0); 487 CU_ASSERT(r == 0);
482 CU_ASSERT(MB_TIMEVAL_SEC(&tmo_after) == 1 && 488 CU_ASSERT(MB_TIMEVAL_SEC(&tmo_after) == 1 &&
483 MB_TIMEVAL_USEC(&tmo_after) == 0); 489 MB_TIMEVAL_USEC(&tmo_after) == 0);
539 545
540 r = mb_tman_next_timeout(tman, &now, &tmo_after); 546 r = mb_tman_next_timeout(tman, &now, &tmo_after);
541 CU_ASSERT(r == -1); 547 CU_ASSERT(r == -1);
542 548
543 mb_progm_free(progm); 549 mb_progm_free(progm);
544 mb_tman_free(tman); 550 mb_timer_man_free(&tman_timer_factory, timer_man);
545 } 551 }
546 552
547 CU_pSuite get_animate_suite(void) { 553 CU_pSuite get_animate_suite(void) {
548 CU_pSuite suite; 554 CU_pSuite suite;
549 555