Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2005:
[Freeciv-Dev] (PR#14263) loading data about saved games
Home

[Freeciv-Dev] (PR#14263) loading data about saved games

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#14263) loading data about saved games
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 10 Oct 2005 15:50:41 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=14263 >

Currently saved games just show the name of the file.  Not very helpful. 
  We can use a similar mechanism to what we use for scenarios to load 
descriptive data about the savegame.

This patch does that.  A new savedesc section is added *at the 
beginning* of the savegame.  The client loads the savedesc sections of 
*every* savegame present to determine info about the game.  I also fixed 
a rather obvious bug in the section_file_load_section function.  If no 
savedesc section is found then further load attempts do not attempt to 
load a description (failing to find a description is very expensive 
since it requires a full load, and it's likely further savegames won't 
have one since they're ordered chronologically).

The obvious issue here is speed.  With a full savegame directory, how 
long will it take?  Well, here are some numbers I have.  I have 650 
saves in my directory, 300 of which have the savedesc section at the start.

* If I load all files completely (section_file_load with no shortcut as 
described above) it takes 300 seconds.  Obviously unacceptable.
* With the section_file_load_section bugfix and the shortcut above, with 
all gzipped savegames it takes 0.8 seconds to load all the descriptions. 
  In this case the first section (~6 lines) of 300 different 
savegames-with-descriptions are loaded, plus the entirety of the first 
old-style savegame.  This is an acceptable amount of time I'd say.
* With the section_file_load_section bugfix and the shortcut above, with 
all *unzipped* savegames it takes 4 seconds to load all the 
descriptions.  This is likely to be a bug in the registry (or inf) code 
somewhere.

Another alternative would be to add the savedesc section to older 
savegames if it was not present.  Then the 300-second upgrade above 
would only happen once.

Another bug in this patch is that the display widget is not wide enough. 
  I guess it has a fixed pixel width...obviously a bad design.

-jason

Index: client/gui-gtk-2.0/pages.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/pages.c,v
retrieving revision 1.46
diff -p -u -r1.46 pages.c
--- client/gui-gtk-2.0/pages.c  10 Oct 2005 00:11:44 -0000      1.46
+++ client/gui-gtk-2.0/pages.c  10 Oct 2005 22:35:40 -0000
@@ -1359,22 +1359,58 @@ static void load_browse_callback(GtkWidg
 }
 
 /**************************************************************************
-  update the saved games list store.
+  Append saves from the prefix directory to the store.
 **************************************************************************/
-static void update_saves_store(GtkListStore *store)
+static void append_saves_store(const char *prefix, GtkListStore *store)
 {
   struct datafile_list *files;
+  bool failed = FALSE;
 
-  gtk_list_store_clear(store);
-
-  /* search for user saved games. */
-  files = datafilelist_infix("saves", ".sav", FALSE);
+  files = datafilelist_infix(prefix, ".sav", FALSE);
   datafile_list_iterate(files, pfile) {
     GtkTreeIter it;
+    struct section_file sf;
+    char desc_full[4096], *desc = pfile->name;
+
+    if (!failed) {
+      if (section_file_load_section(&sf, pfile->fullname, "savedesc")) {
+       if (section_file_lookup(&sf, "savedesc.year")) {
+       int year = secfile_lookup_int_default(&sf, 0, "savedesc.year");
+       char *player
+         = secfile_lookup_str_default(&sf, "unknown", "savedesc.player");
+       char *nation
+         = secfile_lookup_str_default(&sf, "unknown", "savedesc.nation");
+#if 0
+       char *savetime
+         = secfile_lookup_str_default(&sf, "unknown", "savedesc.savetime");
+#endif
+       char *reason
+         = secfile_lookup_str_default(&sf, "unknown", "savedesc.reason");
+       char *my_reason = "";
+
+       if (mystrcasecmp(reason, "Autosave") == 0) {
+         my_reason = _(" autosave");
+       } else if (mystrcasecmp(reason, "Game over") == 0) {
+         my_reason = _(" end of game");
+       } else if (mystrcasecmp(reason, "User request") == 0) {
+         my_reason = _(" manual");
+       } else {
+         my_reason = _(" unknown");
+       }
+
+       my_snprintf(desc_full, sizeof(desc_full), _("%s (%d - %s of the %s - 
%s"),
+                   pfile->name, year, player, nation, my_reason);
+       desc = desc_full;
+       section_file_free(&sf);
+       } else {
+         failed = TRUE;
+       }
+      }
+    }
 
     gtk_list_store_append(store, &it);
     gtk_list_store_set(store, &it,
-       0, pfile->name, 1, pfile->fullname, -1);
+       0, desc, 1, pfile->fullname, -1);
 
     free(pfile->name);
     free(pfile->fullname);
@@ -1383,22 +1419,22 @@ static void update_saves_store(GtkListSt
 
   datafile_list_unlink_all(files);
   datafile_list_free(files);
+}
 
-  files = datafilelist_infix(NULL, ".sav", FALSE);
-  datafile_list_iterate(files, pfile) {
-    GtkTreeIter it;
+/**************************************************************************
+  update the saved games list store.
+**************************************************************************/
+static void update_saves_store(GtkListStore *store)
+{
+  struct timer *t = new_timer_start(TIMER_USER, TIMER_ACTIVE);
 
-    gtk_list_store_append(store, &it);
-    gtk_list_store_set(store, &it,
-       0, pfile->name, 1, pfile->fullname, -1);
+  gtk_list_store_clear(store);
 
-    free(pfile->name);
-    free(pfile->fullname);
-    free(pfile);
-  } datafile_list_iterate_end;
+  /* search for user saved games. */
+  append_saves_store("saves", store);
+  append_saves_store(NULL, store);
 
-  datafile_list_unlink_all(files);
-  datafile_list_free(files);
+  freelog(LOG_NORMAL, "Time taken: %f", read_timer_seconds_free(t));
 }
 
 /**************************************************************************
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.282
diff -p -u -r1.282 savegame.c
--- server/savegame.c   8 Oct 2005 01:06:20 -0000       1.282
+++ server/savegame.c   10 Oct 2005 22:35:41 -0000
@@ -3722,6 +3722,28 @@ void game_load(struct section_file *file
   } players_iterate_end;
 }
 
+static void insert_save_description(struct section_file *file,
+                                   const char *save_reason)
+{
+  const char *player = "-", *nation = "-", *savetime = "-";
+
+  if (game.info.nplayers > 0) {
+    player = game.players[0].name;
+  }
+  if (game.info.nplayers > 0 && game.players[0].nation) {
+    nation = game.players[0].nation->name_orig;
+  }
+  if (1) {
+    /* ??? Set savetime.  It should be local time. */
+  }
+
+  secfile_insert_int(file, game.info.year, "savedesc.year");
+  secfile_insert_str(file, player, "savedesc.player");
+  secfile_insert_str(file, nation, "savedesc.nation");
+  secfile_insert_str(file, savetime, "savedesc.savetime");
+  secfile_insert_str(file, save_reason, "savedesc.reason");
+}
+
 /***************************************************************
 ...
 ***************************************************************/
@@ -3732,6 +3754,8 @@ void game_save(struct section_file *file
   char options[512];
   char temp[B_LAST+1];
 
+  insert_save_description(file, save_reason);
+
   version = MAJOR_VERSION *10000 + MINOR_VERSION *100 + PATCH_VERSION; 
   secfile_insert_int(file, version, "game.version");
 
Index: utility/registry.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/utility/registry.c,v
retrieving revision 1.71
diff -p -u -r1.71 registry.c
--- utility/registry.c  10 Oct 2005 00:11:45 -0000      1.71
+++ utility/registry.c  10 Oct 2005 22:35:42 -0000
@@ -648,7 +648,7 @@ bool section_file_load_section(struct se
   inf = inf_from_file(real_filename, datafilename);
 
   return section_file_read_dup(my_section_file, real_filename,
-                              inf, TRUE, NULL);
+                              inf, TRUE, part);
 }
 
 /**************************************************************************

[Prev in Thread] Current Thread [Next in Thread]