From 6b1d12c04b0d871635c5b3d45a69c7812d894edc Mon Sep 17 00:00:00 2001 From: martin-s Date: Mon, 16 Jul 2007 22:25:39 +0000 Subject: [PATCH] Improved vehicle handling git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@353 ffa7fe5e-494d-0410-b361-a75ebd5db220 --- navit/src/callback.c | 9 +++- navit/src/callback.h | 25 ++++++++++++ navit/src/cursor.c | 42 ++++++++----------- navit/src/cursor.h | 5 ++- navit/src/navit.c | 111 +++++++++++++++++++++++++++++++++----------------- navit/src/navit.h | 4 +- navit/src/vehicle.c | 52 ++++++++++------------- navit/src/vehicle.h | 7 ++-- navit/src/xmlconfig.c | 6 ++- 9 files changed, 155 insertions(+), 106 deletions(-) diff --git a/navit/src/callback.c b/navit/src/callback.c index cd45c74..49d2cd0 100644 --- a/navit/src/callback.c +++ b/navit/src/callback.c @@ -54,12 +54,17 @@ callback_list_add_new(struct callback_list *l, void (*func)(), int pcount, void } void -callback_list_remove_destroy(struct callback_list *l, struct callback *cb) +callback_list_remove(struct callback_list *l, struct callback *cb) { l->list=g_list_remove(l->list, cb); - g_free(cb); } +void +callback_list_remove_destroy(struct callback_list *l, struct callback *cb) +{ + callback_list_remove(l, cb); + g_free(cb); +} void callback_list_call(struct callback_list *l, int pcount, void **p) diff --git a/navit/src/callback.h b/navit/src/callback.h index 1976a11..769ef7d 100644 --- a/navit/src/callback.h +++ b/navit/src/callback.h @@ -8,9 +8,34 @@ struct callback_list *callback_list_new(void); struct callback *callback_new(void (*func)(void), int pcount, void **p); void callback_list_add(struct callback_list *l, struct callback *cb); struct callback *callback_list_add_new(struct callback_list *l, void (*func)(void), int pcount, void **p); +void callback_list_remove(struct callback_list *l, struct callback *cb); void callback_list_remove_destroy(struct callback_list *l, struct callback *cb); void callback_list_call(struct callback_list *l, int pcount, void **p); void callback_list_destroy(struct callback_list *l); + +static inline struct callback *callback_new_1(void (*func)(void), void *p1) +{ + void *p[1]; + p[0]=p1; + return callback_new(func, 1, p); +} + +static inline void callback_list_call_1(struct callback_list *l, void *p1) +{ + void *p[1]; + p[0]=p; + callback_list_call(l, 1, p); +} + +static inline void callback_list_call_2(struct callback_list *l, void *p1, void *p2) +{ + void *p[2]; + p[0]=p1; + p[1]=p2; + callback_list_call(l, 2, p); +} + +#define callback_cast(x) (void (*)(void))(x) /* end of prototypes */ #ifdef __cplusplus } diff --git a/navit/src/cursor.c b/navit/src/cursor.c index 2cc36d4..ee54cb3 100644 --- a/navit/src/cursor.c +++ b/navit/src/cursor.c @@ -15,15 +15,12 @@ #include "menu.h" #include "vehicle.h" #include "navit.h" +#include "callback.h" #include "color.h" #include "cursor.h" #include "compass.h" /* #include "track.h" */ -struct callback { - void (*func)(struct cursor *, void *data); - void *data; -}; struct cursor { @@ -31,13 +28,13 @@ struct cursor { struct graphics_gc *cursor_gc; struct transformation *trans; struct point cursor_pnt; - struct callback offscreen_callback; - struct callback update_callback; + struct callback_list *offscreen_cbl; + struct callback_list *update_cbl; struct vehicle *v; + struct callback *vehicle_cb; int dir; int speed; struct coord pos; - void *vehicle_callback; }; struct coord * @@ -198,9 +195,8 @@ cursor_get_speed(struct cursor *this) } static void -cursor_update(struct vehicle *v, void *data) +cursor_update(struct cursor *this, struct vehicle *v) { - struct cursor *this=data; struct point pnt; struct coord *pos; double *dir; @@ -216,11 +212,9 @@ cursor_update(struct vehicle *v, void *data) this->dir=*dir; this->speed=*speed; this->pos=*pos; - if (this->update_callback.func) - (*this->update_callback.func)(this, this->update_callback.data); + callback_list_call_1(this->update_cbl, this); if (!transform(this->trans, pro, &this->pos, &pnt) || !transform_within_border(this->trans, &pnt, border)) { - if (this->offscreen_callback.func) - (*this->offscreen_callback.func)(this, this->offscreen_callback.data); + callback_list_call_1(this->offscreen_cbl, this); transform(this->trans, pro, &this->pos, &pnt); } cursor_draw(this, &pnt, *dir-transform_get_angle(this->trans, 0), *speed > 2.5); @@ -235,29 +229,25 @@ cursor_new(struct graphics *gra, struct vehicle *v, struct color *c, struct tran { dbg(2,"enter gra=%p v=%p c=%p t=%p\n", gra, v, c, t); struct cursor *this=g_new(struct cursor,1); + this->offscreen_cbl=callback_list_new(); + this->update_cbl=callback_list_new(); this->gra=gra; this->trans=t; this->cursor_gc=graphics_gc_new(gra); this->v=v; graphics_gc_set_foreground(this->cursor_gc, c); graphics_gc_set_linewidth(this->cursor_gc, 2); - this->vehicle_callback=vehicle_callback_register(v, cursor_update, this); + this->vehicle_cb=callback_new_1(callback_cast(cursor_update), this); + vehicle_callback_add(v, this->vehicle_cb); dbg(2,"ret=%p\n", this); return this; } void -cursor_register_offscreen_callback(struct cursor *this, void (*func)(struct cursor *cursor, void *data), void *data) -{ - this->offscreen_callback.func=func; - this->offscreen_callback.data=data; -} - - -void -cursor_register_update_callback(struct cursor *this, void (*func)(struct cursor *cursor, void *data), void *data) +cursor_add_callback(struct cursor *this, int offscreen, struct callback *cb) { - this->update_callback.func=func; - this->update_callback.data=data; + if (offscreen) + callback_list_add(this->offscreen_cbl, cb); + else + callback_list_add(this->update_cbl, cb); } - diff --git a/navit/src/cursor.h b/navit/src/cursor.h index f6d5a5e..dcd21e6 100644 --- a/navit/src/cursor.h +++ b/navit/src/cursor.h @@ -1,4 +1,5 @@ /* prototypes */ +struct callback; struct color; struct coord; struct cursor; @@ -10,5 +11,5 @@ void cursor_pos_set(struct cursor *this, struct coord *pos); int cursor_get_dir(struct cursor *this); int cursor_get_speed(struct cursor *this); struct cursor *cursor_new(struct graphics *gra, struct vehicle *v, struct color *c, struct transformation *t); -void cursor_register_offscreen_callback(struct cursor *this, void (*func)(struct cursor *cursor, void *data), void *data); -void cursor_register_update_callback(struct cursor *this, void (*func)(struct cursor *cursor, void *data), void *data); +void cursor_add_callback(struct cursor *this, int offscreen, struct callback *cb); +/* end of prototypes */ diff --git a/navit/src/navit.c b/navit/src/navit.c index a8d134e..95459a2 100644 --- a/navit/src/navit.c +++ b/navit/src/navit.c @@ -30,6 +30,17 @@ #define _(STRING) gettext(STRING) +struct navit_vehicle { + int update; + int update_curr; + int follow; + int follow_curr; + struct cursor *cursor; + struct vehicle *vehicle; + struct callback *offscreen_cb; + struct callback *update_cb; +}; + struct navit { GList *mapsets; GList *layouts; @@ -46,19 +57,16 @@ struct navit { struct menu *menubar; struct route *route; struct navigation *navigation; - struct cursor *cursor; struct speech *speech; - struct vehicle *vehicle; struct tracking *tracking; struct map_flags *flags; int ready; struct window *win; struct displaylist *displaylist; int cursor_flag; - int update; - int follow; - int update_curr; - int follow_curr; + GList *vehicles; + struct navit_vehicle *vehicle; + struct callback_list *vehicle_cbl; int pid; struct callback *nav_speech_cb; struct callback *roadbook_callback; @@ -453,7 +461,7 @@ navit_window_roadbook_update(struct navit *this_) static void navit_window_roadbook_new(struct navit *this_) { - this_->roadbook_callback=callback_new(navit_window_roadbook_update, 1, &this_); + this_->roadbook_callback=callback_new_1(callback_cast(navit_window_roadbook_update), this_); navigation_register_callback(this_->navigation, navigation_mode_long, this_->roadbook_callback); this_->roadbook_window=gui_datawindow_new(this_->gui, "Roadbook", NULL, NULL); } @@ -490,11 +498,11 @@ navit_window_items_new(struct navit *this_) sel.rect.rl.y=center->y-dist; hash=g_hash_table_new(g_int_hash, g_int_equal); type1=type_bookmark; - g_hash_table_insert(hash, &type1, 1); + g_hash_table_insert(hash, &type1, (void *)1); type2=type_poi_camping; - g_hash_table_insert(hash, &type2, 1); + g_hash_table_insert(hash, &type2, (void *)1); type3=type_roadbook; - g_hash_table_insert(hash, &type3, 1); + g_hash_table_insert(hash, &type3, (void *)1); dbg(2,"0x%x,0x%x - 0x%x,0x%x\n", sel.rect.lu.x, sel.rect.lu.y, sel.rect.rl.x, sel.rect.rl.y); win=gui_datawindow_new(this_->gui, "Itemlist", NULL, NULL); h=mapset_open(navit_get_mapset(this_)); @@ -557,7 +565,7 @@ navit_init(struct navit *this_) navit_add_menu_former_destinations(this_, NULL, this_->route); } if (this_->navigation && this_->speech) { - this_->nav_speech_cb=callback_new(navit_speak, 1, &this_); + this_->nav_speech_cb=callback_new_1(callback_cast(navit_speak), this_); navigation_register_callback(this_->navigation, navigation_mode_speech, this_->nav_speech_cb); #if 0 #endif @@ -615,53 +623,56 @@ navit_toggle_cursor(struct navit *this_) } static void -navit_cursor_offscreen(struct cursor *cursor, void *this__p) +navit_cursor_offscreen(struct navit *this_, struct cursor *cursor) { - struct navit *this_=this__p; - - if (this_->cursor_flag) - navit_set_center(this_, cursor_pos_get(cursor)); + if (!this_->cursor_flag || !this_->vehicle || this_->vehicle->cursor != cursor) + return; + navit_set_center(this_, cursor_pos_get(cursor)); } static void -navit_cursor_update(struct cursor *cursor, void *this__p) +navit_cursor_update(struct navit *this_, struct cursor *cursor) { - struct navit *this_=this__p; struct coord *cursor_c=cursor_pos_get(cursor); int dir=cursor_get_dir(cursor); int speed=cursor_get_speed(cursor); + if (!this_->vehicle || this_->vehicle->cursor != cursor) + return; + + cursor_c=cursor_pos_get(cursor); + dir=cursor_get_dir(cursor); + speed=cursor_get_speed(cursor); if (this_->pid && speed > 2) kill(this_->pid, SIGWINCH); - - if (this_->tracking) { struct coord c=*cursor_c; if (tracking_update(this_->tracking, &c, dir)) { cursor_c=&c; cursor_pos_set(cursor, cursor_c); - if (this_->route && this_->update_curr == 1) + if (this_->route && this_->vehicle->update_curr == 1) route_set_position_from_tracking(this_->route, this_->tracking); } } else { - if (this_->route && this_->update_curr == 1) + if (this_->route && this_->vehicle->update_curr == 1) route_set_position(this_->route, cursor_c); } - if (this_->route && this_->update_curr == 1) + if (this_->route && this_->vehicle->update_curr == 1) navigation_update(this_->navigation, this_->route); if (this_->cursor_flag) { - if (this_->follow_curr == 1) + if (this_->vehicle->follow_curr == 1) navit_set_center_cursor(this_, cursor_c, dir, 50, 80); } - if (this_->follow_curr > 1) - this_->follow_curr--; + if (this_->vehicle->follow_curr > 1) + this_->vehicle->follow_curr--; else - this_->follow_curr=this_->follow; - if (this_->update_curr > 1) - this_->update_curr--; + this_->vehicle->follow_curr=this_->vehicle->follow; + if (this_->vehicle->update_curr > 1) + this_->vehicle->update_curr--; else - this_->update_curr=this_->update; + this_->vehicle->update_curr=this_->vehicle->update; + callback_list_call_2(this_->vehicle_cbl, this_, this_->vehicle->vehicle); } void @@ -676,15 +687,39 @@ navit_set_position(struct navit *this_, struct coord *c) navit_draw(this_); } +struct navit_vehicle * +navit_add_vehicle(struct navit *this_, struct vehicle *v, struct color *c, int update, int follow) +{ + struct navit_vehicle *nv=g_new0(struct navit_vehicle, 1); + nv->vehicle=v; + nv->update_curr=nv->update=update; + nv->follow_curr=nv->follow=follow; + nv->cursor=cursor_new(this_->gra, v, c, this_->trans); + nv->offscreen_cb=callback_new_1(callback_cast(navit_cursor_offscreen), this_); + cursor_add_callback(nv->cursor, 1, nv->offscreen_cb); + nv->update_cb=callback_new_1(callback_cast(navit_cursor_update), this_); + cursor_add_callback(nv->cursor, 0, nv->update_cb); + + this_->vehicles=g_list_append(this_->vehicles, nv); + return nv; +} + +void +navit_add_vehicle_cb(struct navit *this_, struct callback *cb) +{ + callback_list_add(this_->vehicle_cbl, cb); +} + +void +navit_remove_vehicle_cb(struct navit *this_, struct callback *cb) +{ + callback_list_remove(this_->vehicle_cbl, cb); +} + void -navit_vehicle_add(struct navit *this_, struct vehicle *v, struct color *c, int update, int follow, int active) -{ - this_->vehicle=v; - this_->update_curr=this_->update=update; - this_->follow_curr=this_->follow=follow; - this_->cursor=cursor_new(this_->gra, v, c, this_->trans); - cursor_register_offscreen_callback(this_->cursor, navit_cursor_offscreen, this_); - cursor_register_update_callback(this_->cursor, navit_cursor_update, this_); +navit_set_vehicle(struct navit *this_, struct navit_vehicle *nv) +{ + this_->vehicle=nv; } void diff --git a/navit/src/navit.h b/navit/src/navit.h index da527ff..6b905af 100644 --- a/navit/src/navit.h +++ b/navit/src/navit.h @@ -13,6 +13,7 @@ struct mapset; struct menu; struct navigation; struct navit; +struct navit_vehicle; struct point; struct route; struct speech; @@ -43,7 +44,8 @@ void navit_set_center(struct navit *this_, struct coord *center); void navit_set_center_screen(struct navit *this_, struct point *p); void navit_toggle_cursor(struct navit *this_); void navit_set_position(struct navit *this_, struct coord *c); -void navit_vehicle_add(struct navit *this_, struct vehicle *v, struct color *c, int update, int follow, int active); +struct navit_vehicle *navit_add_vehicle(struct navit *this_, struct vehicle *v, struct color *c, int update, int follow); +void navit_set_vehicle(struct navit *this_, struct navit_vehicle *nv); void navit_tracking_add(struct navit *this_, struct tracking *tracking); void navit_route_add(struct navit *this_, struct route *route); void navit_navigation_add(struct navit *this_, struct navigation *navigation); diff --git a/navit/src/vehicle.c b/navit/src/vehicle.c index 103d548..cf3ff24 100644 --- a/navit/src/vehicle.c +++ b/navit/src/vehicle.c @@ -17,6 +17,7 @@ #endif #include "debug.h" #include "coord.h" +#include "callback.h" #include "transform.h" #include "projection.h" #include "statusbar.h" @@ -60,8 +61,10 @@ struct vehicle { #define BUFFER_SIZE 256 char buffer[BUFFER_SIZE]; int buffer_pos; + + struct callback_list *cbl; struct vehicle *child; - GList *callbacks; + struct callback *child_cb; int magic; int is_udp; @@ -96,17 +99,6 @@ vehicle_projection(struct vehicle *this) return projection_mg; } -static void -vehicle_call_callbacks(struct vehicle *this) -{ - GList *item=g_list_first(this->callbacks); - while (item) { - struct callback *cb=item->data; - (*cb->func)(this, cb->data); - item=g_list_next(item); - } -} - struct coord * vehicle_pos_get(struct vehicle *this) { @@ -133,7 +125,7 @@ vehicle_set_position(struct vehicle *this, struct coord *pos) this->curr.y=this->current_pos.y; this->delta.x=0; this->delta.y=0; - vehicle_call_callbacks(this); + callback_list_call_1(this->cbl, this); } static int @@ -220,7 +212,7 @@ vehicle_parse_gps(struct vehicle *this, char *buffer) this->curr.x=this->current_pos.x; this->curr.y=this->current_pos.y; this->timer_count=0; - vehicle_call_callbacks(this); + callback_list_call_1(this->cbl, this); if (this->is_file) { disable_watch(this); g_timeout_add(1000, enable_watch_timer, this); @@ -318,7 +310,7 @@ vehicle_gps_callback(struct gps_data_t *data, char *buf, size_t len, int level) this->curr.x=this->current_pos.x; this->curr.y=this->current_pos.y; this->timer_count=0; - vehicle_call_callbacks(this); + callback_list_call_1(this->cbl, this); data->set &= ~LATLON_SET; } if (data->set & ALTITUDE_SET) { @@ -363,7 +355,7 @@ struct packet { int y __attribute__ ((packed)); unsigned char speed; unsigned char dir; - } pos __attribute__ ((packed)) ; + } pos; } u; } __attribute__ ((packed)) ; @@ -381,14 +373,13 @@ vehicle_udp_recv(struct vehicle *this) this->current_pos.y=pkt.u.pos.y; this->speed=pkt.u.pos.speed; this->dir=pkt.u.pos.dir*2; - vehicle_call_callbacks(this); + callback_list_call_1(this->cbl, this); } } static void -vehicle_udp_update(struct vehicle *child, void *data) +vehicle_udp_update(struct vehicle *this, struct vehicle *child) { - struct vehicle *this=(struct vehicle *)data; struct coord *pos=&child->current_pos; struct packet pkt; int speed=child->speed; @@ -405,7 +396,7 @@ vehicle_udp_update(struct vehicle *child, void *data) this->current_pos=child->current_pos; this->speed=child->speed; this->dir=child->dir; - vehicle_call_callbacks(this); + callback_list_call_1(this->cbl, this); } static int @@ -452,7 +443,8 @@ vehicle_udp_open(struct vehicle *this) if (!this->child) { dbg(3,"child=%s\n", child); this->child=vehicle_new(child); - vehicle_callback_register(this->child, vehicle_udp_update, this); + this->child_cb=callback_new_1(callback_cast(vehicle_udp_update), this); + vehicle_callback_add(this->child, this->child_cb); } } else { vehicle_udp_query(this); @@ -603,6 +595,8 @@ vehicle_new(const char *url) { struct vehicle *this; this=g_new0(struct vehicle,1); + + this->cbl=callback_list_new(); this->url=g_strdup(url); this->fd=-1; @@ -623,21 +617,16 @@ vehicle_new(const char *url) return this; } -void * -vehicle_callback_register(struct vehicle *this, void (*func)(struct vehicle *, void *data), void *data) +void +vehicle_callback_add(struct vehicle *this, struct callback *cb) { - struct callback *cb; - cb=g_new(struct callback, 1); - cb->func=func; - cb->data=data; - this->callbacks=g_list_prepend(this->callbacks, cb); - return cb; + callback_list_add(this->cbl, cb); } void -vehicle_callback_unregister(struct vehicle *this, void *handle) +vehicle_callback_remove(struct vehicle *this, struct callback *cb) { - this->callbacks=g_list_remove(this->callbacks, handle); + callback_list_remove(this->cbl, cb); } @@ -645,6 +634,7 @@ void vehicle_destroy(struct vehicle *this) { vehicle_close(this); + callback_list_destroy(this->cbl); g_free(this->url); g_free(this); } diff --git a/navit/src/vehicle.h b/navit/src/vehicle.h index cb045a9..ccd673a 100644 --- a/navit/src/vehicle.h +++ b/navit/src/vehicle.h @@ -1,5 +1,6 @@ /* prototypes */ enum projection; +struct callback; struct coord; struct vehicle; enum projection vehicle_projection(struct vehicle *this); @@ -8,9 +9,7 @@ double *vehicle_speed_get(struct vehicle *this); double *vehicle_dir_get(struct vehicle *this); void vehicle_set_position(struct vehicle *this, struct coord *pos); struct vehicle *vehicle_new(const char *url); -int vehicle_get_active(struct vehicle *this); -void vehicle_set_active(struct vehicle *this, int active); -void *vehicle_callback_register(struct vehicle *this, void (*func)(struct vehicle *, void *data), void *data); -void vehicle_callback_unregister(struct vehicle *this, void *handle); +void vehicle_callback_add(struct vehicle *this, struct callback *cb); +void vehicle_callback_remove(struct vehicle *this, struct callback *cb); void vehicle_destroy(struct vehicle *this); /* end of prototypes */ diff --git a/navit/src/xmlconfig.c b/navit/src/xmlconfig.c index 944dd86..5513eac 100644 --- a/navit/src/xmlconfig.c +++ b/navit/src/xmlconfig.c @@ -193,6 +193,7 @@ xmlconfig_vehicle(struct xmlstate *state) const char *value; struct color color; int update=1, follow=0, active; + struct navit_vehicle *nv; if (! s) return 0; @@ -206,8 +207,9 @@ xmlconfig_vehicle(struct xmlstate *state) if ((value=find_attribute(state, "follow", 0))) follow=convert_number(value); active=find_boolean(state, "active", 1, 0); - - navit_vehicle_add(state->parent->element_object, state->element_object, &color, update, follow, active); + nv=navit_add_vehicle(state->parent->element_object, state->element_object, &color, update, follow); + if (active) + navit_set_vehicle(state->parent->element_object, nv); return 1; } -- 2.7.4