]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
Add recording and recalling of status event times to estimate progress
authorCharles Brej <cbrej@cs.man.ac.uk>
Thu, 23 Oct 2008 20:33:35 +0000 (21:33 +0100)
committerCharles Brej <cbrej@cs.man.ac.uk>
Thu, 23 Oct 2008 20:33:35 +0000 (21:33 +0100)
src/libply/ply-progress.c
src/libply/ply-progress.h
src/libply/tests/ply-progress-test.am
src/main.c
src/plugins/splash/solar/plugin.c

index 955fe28fba36daa8100392c8576c71170c31d2db..a98fe0ed79dae4ba83ee0ac1dcb345389855f2d9 100644 (file)
@@ -32,6 +32,7 @@
 #include <unistd.h>
 
 
+#include "ply-list.h"
 #include "ply-logger.h"
 #include "ply-progress.h"
 #include "ply-utils.h"
 
 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 <stdio.h>
@@ -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: */
+    
index a204356c2449eb5e2b3fe205a7ae3edaa7d3d6de..5e896db151e81337ee5861b6a9ffde55b8a4970a 100644 (file)
@@ -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: */
index cae8da19e18e4b91a7c08c989e75059e5a31f2c4..6279facfbfc8fb51206a2755e35a4fb1091dde59 100644 (file)
@@ -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              \
index f35178a3951b8072f10cc0265f324d9e3b3e4878..99db9e223abd6a4a7e80fd6dda2dc59eabc0e6f0 100644 (file)
@@ -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);
index 3c589ff80dec2de1e35ebe37a29873212a6211b5..4986d0b78ac78032c5f40a821b3fd634f9a0ffc5 100644 (file)
@@ -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;
 }