Ticket #648: persistent_odometer.diff

File persistent_odometer.diff, 7.1 KB (added by tegzed, 11 years ago)

persistent odometer

  • attr_def.h

     
    401401ATTR(log_gpx)
    402402ATTR(log_textfile)
    403403ATTR(graphics_ready)
     404ATTR(destroy)
    404405ATTR2(0x000bffff,type_callback_end)
    405406ATTR2(0x000c0000,type_int64_begin)
    406407ATTR(osm_nodeid)
  • navit.c

     
    24142414void
    24152415navit_destroy(struct navit *this_)
    24162416{
     2417        callback_list_call_attr_1(this_->attr_cbl, attr_destroy, this_);
     2418
    24172419        /* TODO: destroy objects contained in this_ */
    24182420        if (this_->vehicle)
    24192421                vehicle_destroy(this_->vehicle->vehicle);
  • osd/core/osd_core.c

     
    171171        struct graphics_gc *white;
    172172        struct callback *click_cb;
    173173        char *text;                 //text of label attribute for this osd
     174        char *name;                 //unique name of the odometer (needed for handling multiple odometers persistently)
    174175        struct color idle_color;    //text color when counter is idle
    175176
    176177        int bActive;                //counting or not
    177178        double sum_dist;            //sum of distance ofprevious intervals in meters
    178179        int sum_time;               //sum of time of previous intervals in seconds (needed for avg spd calculation)
     180        int time_all;
    179181        time_t last_click_time;     //time of last click (for double click handling)
    180182        time_t last_start_time;     //time of last start of counting
    181183        struct coord last_coord;
    182184};
    183185
    184 char* str_replace(char*output, char*input, char*pattern, char*replacement)
     186static int odometers_saved=0;
     187static GList* odometer_list = NULL;
     188
     189static char*
     190str_replace(char*output, char*input, char*pattern, char*replacement)
    185191{
    186192  if (!output || !input || !pattern || !replacement) {
    187193    return NULL;
     
    202208  return NULL;
    203209}
    204210
     211/*
     212 * save current odometer state to string
     213 */
     214static char *osd_odometer_to_string(struct odometer* this_)
     215{
     216  return g_strdup_printf("odometer %s %lf %d %d\n",this_->name,this_->sum_dist,this_->time_all,this_->bActive);
     217}
     218
     219/*
     220 * load current odometer state from string
     221 */
     222static void osd_odometer_from_string(struct odometer* this_, char*str)
     223{
     224  char* saveptr;
     225  char*  tok;
     226  char*  name_str;
     227  char*  sum_dist_str;
     228  char*  sum_time_str;
     229  char*  active_str;
     230  tok = strtok_r(str, " ", &saveptr);
     231  if( !tok || strcmp("odometer",tok)) {
     232    return;
     233  }
     234  name_str = g_strdup(strtok_r(NULL, " ", &saveptr));
     235  if(!name_str) {
     236    return;
     237  }
     238  sum_dist_str = g_strdup(strtok_r(NULL, " ", &saveptr));
     239  if(!sum_dist_str) {
     240    return;
     241  }
     242  sum_time_str = g_strdup(strtok_r(NULL, " ", &saveptr));
     243  if(!sum_time_str) {
     244    return;
     245  }
     246  active_str = g_strdup(strtok_r(NULL, " ", &saveptr));
     247  if(!active_str) {
     248    return;
     249  }
     250  this_->name = name_str;
     251  this_->sum_dist = atof(sum_dist_str);
     252  this_->sum_time = atoi(sum_time_str);
     253  this_->bActive = atoi(active_str);
     254  this_->last_coord.x = -1;
     255}
     256
    205257static void
    206258osd_odometer_draw(struct odometer *this, struct navit *nav,
    207259                 struct vehicle *v)
     
    236288        //we have valid previous position
    237289        double dCurrDist = 0;
    238290        dCurrDist = transform_distance(pro, &curr_coord, &this->last_coord);
    239         this->sum_dist += dCurrDist;
    240         int time_all = time(0)-this->last_click_time+this->sum_time;
    241         spd = 3.6*(double)this->sum_dist/(double)time_all;
     291        if(0<curr_coord.x && 0<this->last_coord.x) {
     292                this->sum_dist += dCurrDist;
     293        }
     294        this->time_all = time(0)-this->last_click_time+this->sum_time;
     295        spd = 3.6*(double)this->sum_dist/(double)this->time_all;
    242296    }
    243297    this->last_coord = curr_coord;
    244298  }
     
    315369
    316370        graphics_gc_set_linewidth(this->osd_item.graphic_fg_white, this->width);
    317371
    318     this->last_coord.x = -1;
    319     this->last_coord.y = -1;
    320     this->sum_dist = 0.0;
    321 
    322372        navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_odometer_draw), attr_position_coord_geo, this));
    323373
    324374        navit_add_callback(nav, this->click_cb = callback_new_attr_1(callback_cast (osd_odometer_click), attr_button, this));
     
    326376        osd_odometer_draw(this, nav, NULL);
    327377}
    328378
     379/*
     380 * osd_get_user_data_directory
     381 *
     382 * returns the directory used to store user data files (center.txt,
     383 * destination.txt, bookmark.txt, ...)
     384 *
     385 * arg: gboolean create: create the directory if it does not exist
     386 */
     387char*
     388osd_get_user_data_directory(gboolean create) {
     389        char *dir;
     390        dir = getenv("NAVIT_USER_DATADIR");
     391        if (create && !file_exists(dir)) {
     392                dbg(0,"creating dir %s\n", dir);
     393                if (file_mkdir(dir,0)) {
     394                        dbg(0,"failed creating dir %s\n", dir);
     395                        return NULL;
     396                }
     397        }
     398
     399        return dir;
     400}
     401
     402
     403static void
     404osd_odometer_destroy(struct navit* nav)
     405{
     406        FILE*f;
     407        if(!odometers_saved) {
     408                odometers_saved = 1;
     409                //save odometers that are persistent(ie have name)
     410                GList* list = odometer_list;
     411                char* fn = g_strdup_printf("%s/odometer.txt",osd_get_user_data_directory(TRUE));
     412                f = fopen(fn,"w+");
     413                g_free(fn);
     414                if(!f) {
     415                        return;
     416                }
     417                while (list) {
     418                        if( ((struct odometer*)(list->data))->name) {
     419                                char*odo_str = osd_odometer_to_string(list->data);
     420                                fprintf(f,"%s",odo_str);
     421                               
     422                        }
     423                        list = g_list_next(list);
     424                }
     425                fclose(f);
     426        }
     427}
     428
    329429static struct osd_priv *
    330430osd_odometer_new(struct navit *nav, struct osd_methods *meth,
    331431                struct attr **attrs)
     
    346446        this->last_coord.x = -1;
    347447        this->last_coord.y = -1;
    348448
    349 
    350449        attr = attr_search(attrs, NULL, attr_label);
    351450        //FIXME find some way to free text!!!!
    352451        if (attr) {
     
    355454        else
    356455                this->text = NULL;
    357456
     457        attr = attr_search(attrs, NULL, attr_name);
     458        //FIXME find some way to free text!!!!
     459        if (attr) {
     460                this->name = g_strdup(attr->u.str);
     461        }
     462        else
     463                this->name = NULL;
    358464
    359465        osd_set_std_attr(attrs, &this->osd_item, 2);
    360466        attr = attr_search(attrs, NULL, attr_width);
    361467        this->width=attr ? attr->u.num : 2;
    362468        attr = attr_search(attrs, NULL, attr_idle_color);
    363469        this->idle_color=attr ? *attr->u.color : ((struct color) {0xffff,0xa5a5,0x0000,0xffff}); // text idle_color defaults to orange
     470
     471        this->last_coord.x = -1;
     472        this->last_coord.y = -1;
     473        this->sum_dist = 0.0;
     474
     475        //load state from file
     476        FILE* f;
     477        char* fn = g_strdup_printf("%s/odometer.txt",osd_get_user_data_directory(FALSE));
     478        f = fopen(fn,"r+");
     479
     480        if(f) {
     481                g_free(fn);
     482
     483                while(!feof(f)) {
     484                        char str[128];
     485                        char *line;
     486                        if(fgets(str,128,f))
     487                        {
     488                                line = g_strdup(str);
     489                                char* saveptr;
     490                                char*tok;
     491                                tok = strtok_r(str," ",&saveptr);
     492                                if(!strcmp(tok,"odometer")) {
     493                                        tok = strtok_r(NULL," ",&saveptr);
     494                                        if(!strcmp(this->name,tok)) {
     495                                                osd_odometer_from_string(this,line);
     496                                        }
     497                                }
     498                                g_free(line);
     499                        }
     500                }
     501                fclose(f);
     502        }
     503
    364504        navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_odometer_init), attr_graphics_ready, this));
     505        navit_add_callback(nav, callback_new_attr_1(callback_cast(osd_odometer_destroy), attr_destroy, nav));
     506        odometer_list = g_list_append(odometer_list, this);
     507
    365508        return (struct osd_priv *) this;
    366509}
    367510