From: Charles Brej Date: Thu, 23 Oct 2008 20:33:35 +0000 (+0100) Subject: Add recording and recalling of status event times to estimate progress X-Git-Tag: 0.6.0~61 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=335764227afbfc3a6ea40f7e6743cef638fdc86a;p=thirdparty%2Fplymouth.git Add recording and recalling of status event times to estimate progress --- diff --git a/src/libply/ply-progress.c b/src/libply/ply-progress.c index 955fe28f..a98fe0ed 100644 --- a/src/libply/ply-progress.c +++ b/src/libply/ply-progress.c @@ -32,6 +32,7 @@ #include +#include "ply-list.h" #include "ply-logger.h" #include "ply-progress.h" #include "ply-utils.h" @@ -49,20 +50,37 @@ struct _ply_progress { - double boot_duration; double start_time; - double wait_time; + double pause_time; + double scalar; + double last_percentage; + double last_percentage_time; + ply_list_t *current_message_list; + ply_list_t *previous_message_list; + uint32_t paused : 1; }; +typedef struct +{ + double time; + char* string; + uint32_t disabled : 1; +} ply_progress_message_t; + ply_progress_t* ply_progress_new (void) { ply_progress_t *progress = calloc (1, sizeof (ply_progress_t)); - progress->boot_duration = DEFAULT_BOOT_DURATION; - progress->start_time = ply_get_timestamp (); - progress->wait_time=0; - + progress->start_time = ply_get_timestamp(); + progress->pause_time=0; + progress->scalar=1.0/DEFAULT_BOOT_DURATION; + progress->pause_time=0.0; + progress->last_percentage=0.0; + progress->last_percentage_time=0.0; + progress->current_message_list = ply_list_new (); + progress->previous_message_list = ply_list_new (); + progress->paused = false; return progress; } @@ -74,56 +92,130 @@ ply_progress_free (ply_progress_t* progress) } +static ply_progress_message_t* +ply_progress_message_search (ply_list_t *message_list, const char* string) +{ + ply_list_node_t *node; + node = ply_list_get_first_node (message_list); + + while (node) + { + ply_progress_message_t *message = ply_list_node_get_data (node); + if (strcmp(string, message->string)==0) + return message; + node = ply_list_get_next_node (message_list, node); + } + return NULL; +} + void ply_progress_load_cache (ply_progress_t* progress) { FILE *fp; - int items_matched; - + fp = fopen (BOOT_DURATION_FILE,"r"); - if (fp == NULL) return; - items_matched = fscanf (fp, "%lf", &progress->boot_duration); - + while (1) + { + int items_matched; + double time; + int string_size=81; + char *string; + char colon; + int i=0; + + items_matched = fscanf (fp, "%lf", &time); + if (items_matched<1) break; + items_matched = fscanf (fp, "%c", &colon); + if (items_matched<1 || colon != ':') break; + + string = malloc(sizeof(char)*string_size); + while (1) + { + if (i>=string_size) + { + string_size*=2; + string = realloc(string, sizeof(char)*string_size); + } + items_matched = fscanf (fp, "%c", &string[i]); + if (items_matched<1 || string[i] == '\n') + { + string[i] = '\0'; + break; + } + i++; + } + ply_progress_message_t* message = malloc(sizeof(ply_progress_message_t)); + message->time = time; + message->string = string; + ply_list_append_data(progress->previous_message_list, message); + } fclose (fp); - - if (items_matched != 1) - progress->boot_duration = DEFAULT_BOOT_DURATION; } void ply_progress_save_cache (ply_progress_t* progress) { FILE *fp; + ply_list_node_t *node; + double cur_time = ply_progress_get_time(progress); + fp = fopen (BOOT_DURATION_FILE,"w"); - if (fp != NULL) + if (fp == NULL) + return; + + node = ply_list_get_first_node (progress->current_message_list); + + while (node) { - fprintf (fp, "%.1lf\n", (ply_get_timestamp () - progress->start_time)); - fclose (fp); + ply_progress_message_t *message = ply_list_node_get_data (node); + if (!message->disabled) + fprintf (fp, "%.3lf:%s\n", message->time/cur_time, message->string); + node = ply_list_get_next_node (progress->current_message_list, node); } + fclose (fp); } double ply_progress_get_percentage (ply_progress_t* progress) { - return CLAMP((ply_get_timestamp() - progress->start_time)/progress->boot_duration, 0, 1); + char* string; + double percentage; + double cur_time = ply_progress_get_time (progress); + + if (progress->last_percentage_time*progress->scalar<0.999) + percentage = progress->last_percentage + + (((cur_time - progress->last_percentage_time)*progress->scalar) + / (1 - progress->last_percentage_time*progress->scalar)) + * (1 - progress->last_percentage); + else + percentage = 1.0; + percentage = CLAMP(percentage, 0.0, 1.0); + progress->last_percentage_time = cur_time; + progress->last_percentage = percentage; + return percentage; } double ply_progress_get_time (ply_progress_t* progress) { + if (progress->paused) + { + return progress->pause_time - progress->start_time; + } return ply_get_timestamp() - progress->start_time; } void ply_progress_pause (ply_progress_t* progress) { - progress->wait_time = ply_get_timestamp (); + progress->pause_time = ply_get_timestamp (); + progress->paused = true; return; } @@ -131,20 +223,37 @@ ply_progress_pause (ply_progress_t* progress) void ply_progress_unpause (ply_progress_t* progress) { - progress->start_time += ply_get_timestamp() - progress->wait_time; + progress->start_time += ply_get_timestamp() - progress->pause_time; + progress->paused = false; return; } void -ply_progress_session_output (ply_progress_t* progress, - const char *output, - size_t size) +ply_progress_status_update (ply_progress_t* progress, + const char *status) { - return; + ply_progress_message_t* message; + message = ply_progress_message_search(progress->current_message_list, status); + if (message) + { + message->disabled = true; + } /* Remove duplicates as they confuse things*/ + else + { + message = ply_progress_message_search(progress->previous_message_list, status); + if (message) + { + progress->scalar += message->time / ply_progress_get_time(progress); + progress->scalar /= 2; + } + message = malloc(sizeof(ply_progress_message_t)); + message->time = ply_progress_get_time (progress); + message->string = strdup(status); + message->disabled = false; + ply_list_append_data(progress->current_message_list, message); + } } - - #ifdef PLY_PROGRESS_ENABLE_TEST #include @@ -154,45 +263,45 @@ main (int argc, char **argv) { double percent; + int slowness; double time; int i; + char* strings[10]={"foobar", "barfoo", "barbar", "foo", "foo", "bar", "foo", "more", "even more", "even even more"}; ply_progress_t* progress = ply_progress_new (); + + progress->scalar = 1.0/5; /* Original time estimate is 5 sec*/ percent = ply_progress_get_percentage (progress); time = ply_progress_get_time (progress); - printf("Time:%f \t Percentage: %f%%\n", time, percent); + printf("Time:%f \t Percentage: %f%%\n", time, percent*100); srand ((int) ply_get_timestamp ()); + + slowness = rand () % 500000 + 50000; - for (i=0; i<10; i++) + for (i=0; i<2; i++) { - usleep ((rand () % 500000)); + usleep ((rand () % slowness+slowness)); percent = ply_progress_get_percentage (progress); time = ply_progress_get_time (progress); - printf("Time:%f \t Percentage: %f%%\n", time, percent); + printf("Time:%f \t Percentage: %f%%\n", time, percent*100); } printf("Load cache\n"); ply_progress_load_cache (progress); for (i=0; i<10; i++) { - usleep ((rand () % 500000)); + ply_progress_status_update (progress, strings[i]); + usleep ((rand () % slowness+slowness)); percent = ply_progress_get_percentage (progress); time = ply_progress_get_time (progress); - printf("Time:%f \t Percentage: %f%%\n", time, percent); + printf("Time:%f \t Percentage: %f%% \tScalar:%f\n", time, percent*100, progress->scalar); } - - printf("Save and reload cache\n"); + printf("Save and free cache\n"); ply_progress_save_cache (progress); - - ply_progress_load_cache (progress); - - percent = ply_progress_get_percentage (progress); - time = ply_progress_get_time (progress); - printf("Time:%f \t Percentage: %f%%\n", time, percent); - ply_progress_free(progress); return 0; } #endif /* PLY_PROGRESS_ENABLE_TEST */ /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ + diff --git a/src/libply/ply-progress.h b/src/libply/ply-progress.h index a204356c..5e896db1 100644 --- a/src/libply/ply-progress.h +++ b/src/libply/ply-progress.h @@ -34,6 +34,7 @@ void ply_progress_load_cache (ply_progress_t* progress); double ply_progress_get_percentage (ply_progress_t* progress); double ply_progress_get_time (ply_progress_t* progress); void ply_progress_save_cache (ply_progress_t* progress); +void ply_progress_status_update (ply_progress_t* progress, const char *status); #endif /* PLY_PROGRESS_H */ /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ diff --git a/src/libply/tests/ply-progress-test.am b/src/libply/tests/ply-progress-test.am index cae8da19..6279facf 100644 --- a/src/libply/tests/ply-progress-test.am +++ b/src/libply/tests/ply-progress-test.am @@ -7,6 +7,8 @@ ply_progress_test_LDADD = $(PLYMOUTH_LIBS) ply_progress_test_SOURCES = \ $(srcdir)/../ply-progress.h \ $(srcdir)/../ply-progress.c \ + $(srcdir)/../ply-list.h \ + $(srcdir)/../ply-list.c \ $(srcdir)/../ply-logger.h \ $(srcdir)/../ply-logger.c \ $(srcdir)/../ply-utils.h \ diff --git a/src/main.c b/src/main.c index f35178a3..99db9e22 100644 --- a/src/main.c +++ b/src/main.c @@ -81,9 +81,6 @@ on_session_output (state_t *state, size_t size) { ply_buffer_append_bytes (state->boot_buffer, output, size); - ply_progress_session_output (state->progress, - output, size); - if (state->boot_splash != NULL) ply_boot_splash_update_output (state->boot_splash, output, size); @@ -103,6 +100,8 @@ on_update (state_t *state, const char *status) { ply_trace ("updating status to '%s'", status); + ply_progress_status_update (state->progress, + status); if (state->boot_splash != NULL) ply_boot_splash_update_status (state->boot_splash, status); diff --git a/src/plugins/splash/solar/plugin.c b/src/plugins/splash/solar/plugin.c index 3c589ff8..4986d0b7 100644 --- a/src/plugins/splash/solar/plugin.c +++ b/src/plugins/splash/solar/plugin.c @@ -223,7 +223,7 @@ create_plugin (void) plugin->label = ply_label_new (); plugin->sprites = ply_list_new(); plugin->progress = 0; - plugin->progress_target = 0; + plugin->progress_target = -1; return plugin; } @@ -668,8 +668,10 @@ animate_attime (ply_boot_splash_plugin_t *plugin, double time) { ply_list_node_t *node; long width, height; - - plugin->progress = (plugin->progress*10 + plugin->progress_target) /11; + + if (plugin->progress_target>=0) + plugin->progress = (plugin->progress*10 + plugin->progress_target) /11; + node = ply_list_get_first_node (plugin->sprites); while(node) { @@ -738,6 +740,8 @@ on_boot_progress (ply_boot_splash_plugin_t *plugin, double duration, double percent_done) { + if (plugin->progress_target<0) + plugin->progress = percent_done; plugin->progress_target = percent_done; }