[Freeciv-Dev] (PR#14263) loading data about saved games
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<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);
}
/**************************************************************************
- [Freeciv-Dev] (PR#14263) loading data about saved games,
Jason Short <=
|
|