summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2007-07-16 22:25:39 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2007-07-16 22:25:39 +0000
commit3b584eb8d1585a1f21c116d06c1dc4388ec37ee4 (patch)
tree1e3e33c0f73c0371289fb56823baca62308210b5
parent25fe8f00e4496e270e2a58c823581b9676e172bb (diff)
downloadnavit-svn-3b584eb8d1585a1f21c116d06c1dc4388ec37ee4.tar.gz
Improved vehicle handling
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit/src@353 ffa7fe5e-494d-0410-b361-a75ebd5db220
-rw-r--r--callback.c9
-rw-r--r--callback.h25
-rw-r--r--cursor.c42
-rw-r--r--cursor.h5
-rw-r--r--navit.c111
-rw-r--r--navit.h4
-rw-r--r--vehicle.c52
-rw-r--r--vehicle.h7
-rw-r--r--xmlconfig.c6
9 files changed, 155 insertions, 106 deletions
diff --git a/callback.c b/callback.c
index cd45c74d..49d2cd04 100644
--- a/callback.c
+++ b/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/callback.h b/callback.h
index 1976a11e..769ef7dd 100644
--- a/callback.h
+++ b/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/cursor.c b/cursor.c
index 2cc36d42..ee54cb32 100644
--- a/cursor.c
+++ b/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/cursor.h b/cursor.h
index f6d5a5ea..dcd21e65 100644
--- a/cursor.h
+++ b/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.c b/navit.c
index a8d134ed..95459a25 100644
--- a/navit.c
+++ b/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.h b/navit.h
index da527ff6..6b905af2 100644
--- a/navit.h
+++ b/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/vehicle.c b/vehicle.c
index 103d548e..cf3ff248 100644
--- a/vehicle.c
+++ b/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/vehicle.h b/vehicle.h
index cb045a9b..ccd673a9 100644
--- a/vehicle.h
+++ b/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/xmlconfig.c b/xmlconfig.c
index 944dd868..5513eac8 100644
--- a/xmlconfig.c
+++ b/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;
}