From f34cdf4116c30e1662b55021066b22d1e445fecf Mon Sep 17 00:00:00 2001 From: martin-s Date: Sun, 10 Mar 2013 21:48:13 +0000 Subject: Add:Core:Further work on vehicleprofile_options git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@5407 ffa7fe5e-494d-0410-b361-a75ebd5db220 --- navit/profile_option.c | 5 ++- navit/roadprofile.c | 41 ++++++++++++++++- navit/roadprofile.h | 2 +- navit/vehicleprofile.c | 120 ++++++++++++++++++++++++++++++++++++++++++------- navit/xmlconfig.c | 4 +- navit/xmlconfig.h | 4 +- 6 files changed, 151 insertions(+), 25 deletions(-) (limited to 'navit') diff --git a/navit/profile_option.c b/navit/profile_option.c index c155ef6a..0f76cda1 100644 --- a/navit/profile_option.c +++ b/navit/profile_option.c @@ -34,6 +34,7 @@ profile_option_new(struct attr *parent, struct attr **attrs) po->func=&profile_option_func; navit_object_ref((struct navit_object *)po); po->attrs=attr_list_dup(attrs); + dbg(0,"return %p\n",po); return po; } @@ -48,8 +49,8 @@ struct object_func profile_option_func = { attr_profile_option, (object_func_new)profile_option_new, (object_func_get_attr)navit_object_get_attr, - (object_func_iter_new)NULL, - (object_func_iter_destroy)NULL, + (object_func_iter_new)navit_object_attr_iter_new, + (object_func_iter_destroy)navit_object_attr_iter_destroy, (object_func_set_attr)navit_object_set_attr, (object_func_add_attr)navit_object_add_attr, (object_func_remove_attr)navit_object_remove_attr, diff --git a/navit/roadprofile.c b/navit/roadprofile.c index 99037728..0c70eb48 100644 --- a/navit/roadprofile.c +++ b/navit/roadprofile.c @@ -20,6 +20,7 @@ #include #include "debug.h" #include "item.h" +#include "xmlconfig.h" #include "roadprofile.h" static void @@ -46,8 +47,10 @@ roadprofile_new(struct attr *parent, struct attr **attrs) struct roadprofile *this_; struct attr **attr; this_=g_new0(struct roadprofile, 1); + this_->func=&roadprofile_func; + navit_object_ref((struct navit_object *)this_); + this_->attrs=attr_list_dup(attrs); - this_->maxspeed=0; for (attr=attrs;*attr; attr++) roadprofile_set_attr_do(this_, *attr); return this_; @@ -84,7 +87,7 @@ roadprofile_remove_attr(struct roadprofile *this_, struct attr *attr) struct attr_iter * roadprofile_attr_iter_new(void) { - return g_new0(void *,1); + return (struct attr_iter *)g_new0(void *,1); } void @@ -92,3 +95,37 @@ roadprofile_attr_iter_destroy(struct attr_iter *iter) { g_free(iter); } + +struct roadprofile * +roadprofile_dup(struct roadprofile *this_) +{ + struct roadprofile *ret=g_new(struct roadprofile, 1); + *ret=*this_; + ret->refcount=1; + ret->attrs=attr_list_dup(this_->attrs); + return ret; +} + +void +roadprofile_destroy(struct roadprofile *this_) +{ + attr_list_free(this_->attrs); + g_free(this_); +} + + +struct object_func roadprofile_func = { + attr_roadprofile, + (object_func_new)roadprofile_new, + (object_func_get_attr)roadprofile_get_attr, + (object_func_iter_new)roadprofile_attr_iter_new, + (object_func_iter_destroy)roadprofile_attr_iter_destroy, + (object_func_set_attr)roadprofile_set_attr, + (object_func_add_attr)roadprofile_add_attr, + (object_func_remove_attr)roadprofile_remove_attr, + (object_func_init)NULL, + (object_func_destroy)roadprofile_destroy, + (object_func_dup)roadprofile_dup, + (object_func_ref)navit_object_ref, + (object_func_unref)navit_object_unref, +}; diff --git a/navit/roadprofile.h b/navit/roadprofile.h index e9734722..a4ff6507 100644 --- a/navit/roadprofile.h +++ b/navit/roadprofile.h @@ -22,7 +22,7 @@ extern "C" { #endif struct roadprofile { - struct attr **attrs; + NAVIT_OBJECT int speed; int route_weight; int maxspeed; diff --git a/navit/vehicleprofile.c b/navit/vehicleprofile.c index 6bfbfbbf..b7cc4b05 100644 --- a/navit/vehicleprofile.c +++ b/navit/vehicleprofile.c @@ -86,23 +86,122 @@ vehicleprofile_set_attr_do(struct vehicleprofile *this_, struct attr *attr) } static void -vehicleprofile_clear(struct vehicleprofile *this_) +vehicleprofile_free_hash_item(gpointer key, gpointer value, gpointer user_data) +{ + struct navit_object *obj=value; + obj->func->unref(obj); +} + +static void +vehicleprofile_free_hash(struct vehicleprofile *this_) { - if (this_->roadprofile_hash) + if (this_->roadprofile_hash) { + g_hash_table_foreach(this_->roadprofile_hash, vehicleprofile_free_hash_item, NULL); g_hash_table_destroy(this_->roadprofile_hash); - this_->roadprofile_hash=g_hash_table_new(NULL, NULL); + } +} + +static void +vehicleprofile_clear(struct vehicleprofile *this_) +{ + this_->mode=0; + this_->flags_forward_mask=0; + this_->flags_reverse_mask=0; + this_->flags=0; + this_->maxspeed_handling=0; + this_->static_speed=0; + this_->static_distance=0; + g_free(this_->name); + this_->name=NULL; + this_->dangerous_goods=0; this_->length=-1; this_->width=-1; this_->height=-1; this_->weight=-1; this_->axle_weight=-1; this_->through_traffic_penalty=9000; + vehicleprofile_free_hash(this_); + this_->roadprofile_hash=g_hash_table_new(NULL, NULL); +} + +static void +vehicleprofile_apply_roadprofile(struct vehicleprofile *this_, struct navit_object *rp, int is_option) +{ + struct attr item_types_attr; + if (rp->func->get_attr(rp, attr_item_types, &item_types_attr, NULL)) { + enum item_type *types=item_types_attr.u.item_types; + while (*types != type_none) { + struct navit_object *oldrp; + /* Maptool won't place any access flags for roads which don't have default access flags set. Warn user. */ + if(!item_get_default_flags(*types)) + dbg(0,"On '%s' roads used in '%s' vehicleprofile access restrictions are ignored. You might even be directed to drive in wrong direction on a one-way road. " + "Please define default access flags for above road type to item.c and rebuild the map.\n", item_to_name(*types), this_->name); + oldrp=g_hash_table_lookup(this_->roadprofile_hash, (void *)(long)(*types)); + if (is_option && oldrp) { + struct navit_object *newrp; + struct attr_iter *iter=rp->func->iter_new(NULL); + struct attr attr; + dbg(1,"patching roadprofile\n"); + newrp=oldrp->func->dup(oldrp); + while (rp->func->get_attr(rp, attr_any, &attr, iter)) + newrp->func->set_attr(newrp, &attr); + oldrp->func->iter_destroy(iter); + oldrp->func->unref(oldrp); + g_hash_table_insert(this_->roadprofile_hash, (void *)(long)(*types), newrp); + } else { + if (oldrp) + oldrp->func->unref(oldrp); + g_hash_table_insert(this_->roadprofile_hash, (void *)(long)(*types), rp->func->ref(rp)); + } + types++; + } + } +} + +static void +vehicleprofile_apply_attrs(struct vehicleprofile *this_, struct navit_object *obj, int is_option) +{ + struct attr attr; + struct attr_iter *iter=obj->func->iter_new(NULL); + while (obj->func->get_attr(obj, attr_any, &attr, iter)) { + dbg(1,"%s\n",attr_to_name(attr.type)); + if (attr.type == attr_roadprofile) + vehicleprofile_apply_roadprofile(this_, attr.u.navit_object, is_option); + else if (attr.type != attr_profile_option) + vehicleprofile_set_attr_do(this_, &attr); + } + obj->func->iter_destroy(iter); +} + +static void +vehicleprofile_debug_roadprofile(gpointer key, gpointer value, gpointer user_data) +{ + struct roadprofile *rp=value; + dbg(0,"type %s avg %d weight %d max %d\n",item_to_name((int)(long)key),rp->speed,rp->route_weight,rp->maxspeed); } static void vehicleprofile_update(struct vehicleprofile *this_) { + struct attr_iter *iter=vehicleprofile_attr_iter_new(); + struct attr profile_option; dbg(0,"enter\n"); + vehicleprofile_clear(this_); + vehicleprofile_apply_attrs(this_, (struct navit_object *)this_, 0); + while (vehicleprofile_get_attr(this_, attr_profile_option, &profile_option, iter)) { + struct attr active, name; + if (!profile_option.u.navit_object->func->get_attr(profile_option.u.navit_object, attr_active, &active, NULL)) + active.u.num=0; + if (profile_option.u.navit_object->func->get_attr(profile_option.u.navit_object, attr_name, &name, NULL)) + dbg(0,"%p %s %d\n",profile_option.u.navit_object,name.u.str,active.u.num); + if (active.u.num) + vehicleprofile_apply_attrs(this_, profile_option.u.navit_object, 1); + } + vehicleprofile_attr_iter_destroy(iter); + dbg(0,"result l %d w %d h %d wg %d awg %d pen %d\n",this_->length,this_->width,this_->height,this_->weight,this_->axle_weight,this_->through_traffic_penalty); + dbg(0,"m %d fwd 0x%x rev 0x%x flags 0x%x max %d stsp %d stdst %d dg %d\n",this_->mode,this_->flags_forward_mask,this_->flags_reverse_mask, this_->flags, this_->maxspeed_handling, this_->static_speed, this_->static_distance, this_->dangerous_goods); + g_hash_table_foreach(this_->roadprofile_hash, vehicleprofile_debug_roadprofile, NULL); + } @@ -156,21 +255,10 @@ vehicleprofile_set_attr(struct vehicleprofile *this_, struct attr *attr) int vehicleprofile_add_attr(struct vehicleprofile *this_, struct attr *attr) { - struct attr item_types_attr; this_->attrs=attr_generic_add_attr(this_->attrs, attr); switch (attr->type) { case attr_roadprofile: - if (roadprofile_get_attr(attr->u.roadprofile, attr_item_types, &item_types_attr, NULL)) { - enum item_type *types=item_types_attr.u.item_types; - while (*types != type_none) { - /* Maptool won't place any access flags for roads which don't have default access flags set. Warn user. */ - if(!item_get_default_flags(*types)) - dbg(0,"On '%s' roads used in '%s' vehicleprofile access restrictions are ignored. You might even be directed to drive in wrong direction on a one-way road. " - "Please define default access flags for above road type to item.c and rebuild the map.\n", item_to_name(*types), this_->name); - g_hash_table_insert(this_->roadprofile_hash, (void *)(long)(*types), attr->u.roadprofile); - types++; - } - } + vehicleprofile_apply_roadprofile(this_, attr->u.navit_object, 0); break; case attr_profile_option: attr->u.navit_object->func->add_attr(attr->u.navit_object, &this_->active_callback); @@ -197,7 +285,7 @@ vehicleprofile_get_roadprofile(struct vehicleprofile *this_, enum item_type type char * vehicleprofile_get_name(struct vehicleprofile *this_) { - return this_->name; + return this_->name; } struct object_func vehicleprofile_func = { diff --git a/navit/xmlconfig.c b/navit/xmlconfig.c index 27d91a99..4e81054f 100644 --- a/navit/xmlconfig.c +++ b/navit/xmlconfig.c @@ -50,7 +50,6 @@ #include "log.h" #include "announcement.h" #include "vehicleprofile.h" -#include "roadprofile.h" #include "callback.h" #include "config_.h" @@ -261,7 +260,6 @@ static struct object_func object_funcs[] = { { attr_plugin, NEW(plugin_new)}, { attr_polygon, NEW(polygon_new), NULL, NULL, NULL, NULL, ADD(element_add_attr)}, { attr_polyline, NEW(polyline_new), NULL, NULL, NULL, NULL, ADD(element_add_attr)}, - { attr_roadprofile,NEW(roadprofile_new), GET(roadprofile_get_attr), NULL, NULL, SET(roadprofile_set_attr), ADD(roadprofile_add_attr) }, { attr_route, NEW(route_new), GET(route_get_attr), NULL, NULL, SET(route_set_attr), ADD(route_add_attr), REMOVE(route_remove_attr)}, { attr_speech, NEW(speech_new), GET(speech_get_attr), NULL, NULL, SET(speech_set_attr)}, { attr_text, NEW(text_new)}, @@ -288,6 +286,8 @@ object_func_lookup(enum attr_type type) return &navit_func; case attr_profile_option: return &profile_option_func; + case attr_roadprofile: + return &roadprofile_func; case attr_osd: return &osd_func; case attr_trackingo: diff --git a/navit/xmlconfig.h b/navit/xmlconfig.h index f946fef3..7bcdbf76 100644 --- a/navit/xmlconfig.h +++ b/navit/xmlconfig.h @@ -54,9 +54,9 @@ struct object_func { void *(*unref)(void *); }; -extern struct object_func map_func, mapset_func, navit_func, osd_func, tracking_func, vehicle_func, maps_func, layout_func, vehicleprofile_func, layer_func, config_func, profile_option_func; +extern struct object_func map_func, mapset_func, navit_func, osd_func, tracking_func, vehicle_func, maps_func, layout_func, roadprofile_func, vehicleprofile_func, layer_func, config_func, profile_option_func; -#define HAS_OBJECT_FUNC(x) ((x) == attr_map || (x) == attr_mapset || (x) == attr_navit || (x) == attr_osd || (x) == attr_trackingo || (x) == attr_vehicle || (x) == attr_maps || (x) == attr_layout || (x) == attr_vehicleprofile || (x) == attr_layer || (x) == attr_config || (x) == attr_profile_option) +#define HAS_OBJECT_FUNC(x) ((x) == attr_map || (x) == attr_mapset || (x) == attr_navit || (x) == attr_osd || (x) == attr_trackingo || (x) == attr_vehicle || (x) == attr_maps || (x) == attr_layout || (x) == attr_roadprofile || (x) == attr_vehicleprofile || (x) == attr_layer || (x) == attr_config || (x) == attr_profile_option) #define NAVIT_OBJECT struct object_func *func; int refcount; struct attr **attrs; struct navit_object { -- cgit v1.2.1