# HG changeset patch # User Thinker K.F. Li # Date 1222843568 -28800 # Node ID 6749f6639924b81279ba9cf91b9c2720982a6adf # Parent 6ce68c1f740525674095991b4677e0894cf27b05 Fix bug for STAILQ that fail to remove a node. The previous one should be re-linked to next of removed one. But, it is linked to the removed one. Fix it! diff -r 6ce68c1f7405 -r 6749f6639924 examples/tank/Makefile --- a/examples/tank/Makefile Tue Sep 30 02:44:06 2008 +0800 +++ b/examples/tank/Makefile Wed Oct 01 14:46:08 2008 +0800 @@ -1,5 +1,5 @@ SVGS = brick.svg bullet.svg bush.svg mud.svg rock.svg \ - tank1.svg tank2.svg tank_en.svg + tank1.svg tank2.svg tank_en.svg bang.svg SVGHS = $(SVGS:C/\.svg/.h/) SVGCS = $(SVGS:C/\.svg/.c/) SVGOS = $(SVGS:C/\.svg/.o/) diff -r 6ce68c1f7405 -r 6749f6639924 examples/tank/tank_main.c --- a/examples/tank/tank_main.c Tue Sep 30 02:44:06 2008 +0800 +++ b/examples/tank/tank_main.c Wed Oct 01 14:46:08 2008 +0800 @@ -1,3 +1,4 @@ +#include #include #include #include @@ -50,6 +51,8 @@ mb_progm_t *progm; mb_timeval_t start_time; observer_t *ob_redraw; + mb_timer_t *hit_tmr; + mb_tman_t *tman; }; typedef struct _tank_bullet tank_bullet_t; enum { BU_UP = 0, BU_RIGHT, BU_DOWN, BU_LEFT }; @@ -336,10 +339,14 @@ redraw_man_t *rdman; subject_t *redraw; ob_factory_t *factory; + + bullet = tank->bullet; + rdman = bullet->rdman; + + if(bullet->hit_tmr != NULL) + mb_tman_remove(bullet->tman, bullet->hit_tmr); /*! \todo Simplify the procdure of using observer pattern. */ - bullet = tank->bullet; - rdman = bullet->rdman; factory = rdman_get_ob_factory(rdman); redraw = rdman_get_redraw_subject(rdman); bullet->ob_redraw = @@ -347,6 +354,45 @@ bullet_go_out_map_and_redraw, tank); } +static void bullet_bang(tank_bullet_t *bullet, int map_x, int map_y) { +} + +static void bullet_hit_chk(const mb_timeval_t *tmo, + const mb_timeval_t *now, + void *arg) { + tank_t *tank = (tank_t *)arg; + tank_bullet_t *bullet; + mb_timeval_t diff, next; + mb_timeval_t unit_tm; + float move_units_f; + int move_units; + int x, y; + int dir; + static int move_adj[][2] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}}; + + bullet = tank->bullet; + MB_TIMEVAL_CP(&diff, now); + MB_TIMEVAL_DIFF(&diff, &bullet->start_time); + MB_TIMEVAL_SET(&unit_tm, 0, 250000); + move_units_f = MB_TIMEVAL_DIV(&diff, &unit_tm); + move_units = floorl(move_units_f); + dir = bullet->direction; + x = bullet->start_map_x + move_adj[dir][0] * move_units; + y = bullet->start_map_y + move_adj[dir][1] * move_units; + + if(map[y][x] != MUD) { + bullet->hit_tmr = NULL; + mb_progm_abort(bullet->progm); + bullet_go_out_map(NULL, arg); + bullet_bang(bullet, x, y); + } else { + MB_TIMEVAL_SET(&next, 0, 100000); + MB_TIMEVAL_ADD(&next, now); + bullet->hit_tmr = mb_tman_timeout(bullet->tman, &next, + bullet_hit_chk, arg); + } +} + static void tank_fire_bullet(tank_rt_t *tank_rt, tank_t *tank) { X_MB_runtime_t *xmb_rt; redraw_man_t *rdman; @@ -359,7 +405,7 @@ mb_word_t *word; mb_action_t *act; mb_timeval_t start, playing; - mb_timeval_t now; + mb_timeval_t now, next; ob_factory_t *factory; mb_tman_t *tman; subject_t *subject; @@ -377,6 +423,7 @@ map_y = tank->map_y + map_xy_adj[dir][1]; tank->bullet = tank_bullet_new(rdman, map_x, map_y, dir); bullet = tank->bullet; + bullet->tman = tman; switch(dir) { case TD_UP: @@ -415,6 +462,10 @@ get_now(&now); MB_TIMEVAL_CP(&bullet->start_time, &now); mb_progm_start(progm, tman, &now); + + MB_TIMEVAL_SET(&next, 0, 100000); + MB_TIMEVAL_ADD(&next, &now); + bullet->hit_tmr = mb_tman_timeout(tman, &next, bullet_hit_chk, tank); } #define CHANGE_POS(g, x, y) do { \ diff -r 6ce68c1f7405 -r 6749f6639924 src/animate.c --- a/src/animate.c Tue Sep 30 02:44:06 2008 +0800 +++ b/src/animate.c Wed Oct 01 14:46:08 2008 +0800 @@ -290,6 +290,7 @@ MB_TIMEVAL_CP(&next_tmo, &word->abs_start); timer = mb_tman_timeout(progm->tman, &next_tmo, mb_progm_step, progm); + progm->cur_timer = timer; } else { /* Make program to complete. */ #ifndef UNITTEST diff -r 6ce68c1f7405 -r 6749f6639924 src/mb_timer.h --- a/src/mb_timer.h Tue Sep 30 02:44:06 2008 +0800 +++ b/src/mb_timer.h Wed Oct 01 14:46:08 2008 +0800 @@ -67,6 +67,9 @@ (a)->tv_usec -= 1000000; \ } \ } while(0) +#define MB_TIMEVAL_DIV(a, b) \ + (((a)->tv_sec * 1000000.0 + (a)->tv_usec) / \ + ((b)->tv_sec * 1000000.0 + (b)->tv_usec)) extern void get_now(mb_timeval_t *tmo); diff -r 6ce68c1f7405 -r 6749f6639924 src/timer.c --- a/src/timer.c Tue Sep 30 02:44:06 2008 +0800 +++ b/src/timer.c Wed Oct 01 14:46:08 2008 +0800 @@ -61,7 +61,8 @@ for(visit = STAILQ_HEAD(tman->timers); visit != NULL; visit = STAILQ_NEXT(mb_timer_t, next, visit)) { - if(MB_TIMEVAL_LATER(&visit->tmo, tmo)) + if(MB_TIMEVAL_LATER(&visit->tmo, tmo) || + MB_TIMEVAL_EQ(&visit->tmo, tmo)) break; last = visit; } diff -r 6ce68c1f7405 -r 6749f6639924 src/tools.h --- a/src/tools.h Tue Sep 30 02:44:06 2008 +0800 +++ b/src/tools.h Wed Oct 01 14:46:08 2008 +0800 @@ -55,7 +55,7 @@ _stailq_cur->field != (elm)) \ _stailq_cur = _stailq_cur->field; \ if(_stailq_cur != NULL) { \ - _stailq_cur->field = elm; \ + _stailq_cur->field = (elm)->field; \ if((q).tail == (elm)) \ (q).tail = _stailq_cur; \ } \