Complete.Org: Mailing Lists: Archives: freeciv-dev: July 2005:
[Freeciv-Dev] (PR#13550) use city_production struct in worklist code
Home

[Freeciv-Dev] (PR#13550) use city_production struct in worklist code

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#13550) use city_production struct in worklist code
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 26 Jul 2005 20:10:25 -0700
Reply-to: bugs@xxxxxxxxxxx

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

This patch changes the worklist code to use the city_production struct
internally.  The interface still uses (is_unit,id) tuples (changing
these is the next goal, but this means API changes which will require
more widespread changes).

There are a large number of changes resulting in simpler code.

- The WEF_END,WEF_UNIT,WEF_IMPR enumeration is removed.  Now the city
production struct stores the production type.  A worklist->length value
is stored so no terminator is needed.  This also means some operations
are now O(1) instead of O(n).

- The registry code is basically rewritten.  Both of the old savegame
formats (the 1.14/2.0 version and the really old version) are dropped;
loading old savegames will lose your city worklists.  Similarly the
client worklist registry code is dropped; upgrading will lose your
client (global) worklists.  In place is one single much simpler set of
functions worklist_load and worklist_save.  These are in the common code
and used by both registry users.  (Adding code to upgrade old versions
wouldn't be too hard, but I'm not going to do it.  Worklists are a
luxury and aren't an integral part of the savegame - in fact for many
months now worklists have been broken in the savegame, and apparently
nobody but me has noticed.)

- Also the city_production struct is moved into fc_types.  I don't know
if this is the best place but it can't stay in city.h because worklist.h
(#included from city.h) requires it.

-jason

Index: client/citydlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/citydlg_common.c,v
retrieving revision 1.83
diff -p -u -r1.83 citydlg_common.c
--- client/citydlg_common.c     26 Jul 2005 16:35:56 -0000      1.83
+++ client/citydlg_common.c     27 Jul 2005 03:06:55 -0000
@@ -706,12 +706,7 @@ bool city_queue_insert(struct city *pcit
 **************************************************************************/
 bool city_queue_clear(struct city *pcity)
 {
-  int i;
-
-  for (i = 0; i < MAX_LEN_WORKLIST; i++) {
-    pcity->worklist.wlefs[i] = WEF_END;
-    pcity->worklist.wlids[i] = 0;
-  }
+  init_worklist(&pcity->worklist);
 
   return TRUE;
 }
Index: client/options.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/options.c,v
retrieving revision 1.133
diff -p -u -r1.133 options.c
--- client/options.c    13 Jul 2005 15:41:32 -0000      1.133
+++ client/options.c    27 Jul 2005 03:06:55 -0000
@@ -350,13 +350,6 @@ static void save_cma_preset(struct secti
                            int inx);
 static void load_cma_preset(struct section_file *file, int inx);
 
-static void save_global_worklist(struct section_file *file, const char *path, 
-                                 int wlinx, struct worklist *pwl);
-
-static void load_global_worklist(struct section_file *file, const char *path,
-                                int wlinx, struct worklist *pwl);
-
-
 /****************************************************************
  The "options" file handles actual "options", and also view options,
  message options, city report settings, cma settings, and 
@@ -506,14 +499,8 @@ void load_ruleset_specific_options(void)
 
   /* load global worklists */
   for (i = 0; i < MAX_NUM_WORKLISTS; i++) {
-    game.player_ptr->worklists[i].is_valid =
-       secfile_lookup_bool_default(&sf, FALSE,
-                                   "worklists.worklist%d.is_valid", i);
-    strcpy(game.player_ptr->worklists[i].name,
-           secfile_lookup_str_default(&sf, "",
-                                      "worklists.worklist%d.name", i));
-    load_global_worklist(&sf, "worklists.worklist%d", i, 
-                         &(game.player_ptr->worklists[i]));
+    worklist_load(&sf, &(game.player_ptr->worklists[i]),
+                 "worklists.worklist%d", i);
   }
 
   /* Load city report columns (which include some ruleset data). */
@@ -587,12 +574,8 @@ void save_options(void)
   /* insert global worklists */
   for(i = 0; i < MAX_NUM_WORKLISTS; i++){
     if (game.player_ptr->worklists[i].is_valid) {
-      secfile_insert_bool(&sf, game.player_ptr->worklists[i].is_valid,
-                         "worklists.worklist%d.is_valid", i);
-      secfile_insert_str(&sf, game.player_ptr->worklists[i].name,
-                         "worklists.worklist%d.name", i);
-      save_global_worklist(&sf, "worklists.worklist%d", i, 
-                           &(game.player_ptr->worklists[i]));
+      worklist_save(&sf, &(game.player_ptr->worklists[i]),
+                   "worklists.worklist%d", i);
     }
   }
 
@@ -666,68 +649,6 @@ static void save_cma_preset(struct secti
                     "cma.preset%d.happyfactor", inx);
 }
 
-/****************************************************************
- loads global worklist from rc file
-*****************************************************************/
-static void load_global_worklist(struct section_file *file, const char *path,
-                                int wlinx, struct worklist *pwl)
-{
-  char efpath[64];
-  char idpath[64];
-  int i;
-  bool end = FALSE;
-
-  sz_strlcpy(efpath, path);
-  sz_strlcat(efpath, ".wlef%d");
-  sz_strlcpy(idpath, path);
-  sz_strlcat(idpath, ".wlid%d");
-
-  for (i = 0; i < MAX_LEN_WORKLIST; i++) {
-    if (end) {
-      pwl->wlefs[i] = WEF_END;
-      pwl->wlids[i] = 0;
-      section_file_lookup(file, efpath, wlinx, i);
-      section_file_lookup(file, idpath, wlinx, i);
-    } else {
-      pwl->wlefs[i] =
-        secfile_lookup_int_default(file, WEF_END, efpath, wlinx, i);
-      pwl->wlids[i] =
-        secfile_lookup_int_default(file, 0, idpath,wlinx, i);
-
-      if ((pwl->wlefs[i] <= WEF_END) || (pwl->wlefs[i] >= WEF_LAST) ||
-          (pwl->wlefs[i] == WEF_UNIT
-          && (pwl->wlids[i] < 0 || pwl->wlids[i] >= 
game.control.num_unit_types))
-          || ((pwl->wlefs[i] == WEF_IMPR)
-              && !improvement_exists(pwl->wlids[i]))) {
-        pwl->wlefs[i] = WEF_END;
-        pwl->wlids[i] = 0;
-        end = TRUE;
-      }
-    }
-  }
-}
-
-/****************************************************************
- saves global worklist to rc file
-*****************************************************************/
-static void save_global_worklist(struct section_file *file, const char *path,
-                                int wlinx, struct worklist *pwl)
-{
-  char efpath[64];
-  char idpath[64];
-  int i;
-
-  sz_strlcpy(efpath, path);
-  sz_strlcat(efpath, ".wlef%d");
-  sz_strlcpy(idpath, path);
-  sz_strlcat(idpath, ".wlid%d");
-
-  for (i = 0; i < MAX_LEN_WORKLIST; i++) {
-    secfile_insert_int(file, pwl->wlefs[i], efpath, wlinx, i);
-    secfile_insert_int(file, pwl->wlids[i], idpath, wlinx, i);
-  }
-}
-
 /****************************************************************************
   Callback when a mapview graphics option is changed (redraws the canvas).
 ****************************************************************************/
Index: client/gui-gtk-2.0/wldlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/wldlg.c,v
retrieving revision 1.46
diff -p -u -r1.46 wldlg.c
--- client/gui-gtk-2.0/wldlg.c  22 Jul 2005 16:18:05 -0000      1.46
+++ client/gui-gtk-2.0/wldlg.c  27 Jul 2005 03:06:55 -0000
@@ -481,15 +481,11 @@ static void menu_item_callback(GtkMenuIt
   if (pwl->is_valid) {
     int i;
 
-    for (i = 0; i < MAX_LEN_WORKLIST; i++) {
+    for (i = 0; i < worklist_length(pwl); i++) {
       GtkTreeIter it;
       cid cid;
 
-      if (pwl->wlefs[i] == WEF_END) {
-       break;
-      }
-
-      cid = cid_encode(pwl->wlefs[i] == WEF_UNIT, pwl->wlids[i]);
+      cid = cid_encode(pwl->entries[i].is_unit, pwl->entries[i].value);
 
       gtk_list_store_append(ptr->dst, &it);
       gtk_list_store_set(ptr->dst, &it, 0, (gint) cid, -1);
@@ -1397,14 +1393,10 @@ void refresh_worklist(GtkWidget *editor)
     copy_worklist(&queue, pwl);
   }
 
-  for (i = 0; i < MAX_LEN_WORKLIST; i++) {
+  for (i = 0; i < worklist_length(&queue); i++) {
     cid cid;
 
-    if (queue.wlefs[i] == WEF_END) {
-      break;
-    }
-
-    cid = cid_encode(queue.wlefs[i] == WEF_UNIT, queue.wlids[i]);
+    cid = cid_encode(queue.entries[i].is_unit, queue.entries[i].value);
 
     if (!exists) {
       gtk_list_store_append(ptr->dst, &it);
@@ -1478,8 +1470,8 @@ static void commit_worklist(struct workl
       }
 
       gtk_tree_model_get(model, &it, 0, &cid, -1);
-      queue.wlefs[i] = cid_is_unit(cid) ? WEF_UNIT : WEF_IMPR;
-      queue.wlids[i] = cid_id(cid);
+
+      worklist_append(&queue, cid_id(cid), cid_is_unit(cid));
 
       i++;
     } while (gtk_tree_model_iter_next(model, &it));
Index: common/capstr.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v
retrieving revision 1.261
diff -p -u -r1.261 capstr.c
--- common/capstr.c     22 Jul 2005 15:37:35 -0000      1.261
+++ common/capstr.c     27 Jul 2005 03:06:55 -0000
@@ -82,7 +82,7 @@ const char * const our_capability = our_
  *     as long as possible.  We want to maintain network compatibility with
  *     the stable branch for as long as possible.
  */
-#define CAPABILITY "+Freeciv.Devel.2005.Jul.20"
+#define CAPABILITY "+Freeciv.Devel.2005.Jul.26"
 
 void init_our_capability(void)
 {
Index: common/city.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.h,v
retrieving revision 1.220
diff -p -u -r1.220 city.h
--- common/city.h       26 Jul 2005 17:21:54 -0000      1.220
+++ common/city.h       27 Jul 2005 03:06:55 -0000
@@ -131,11 +131,6 @@ struct output_type {
   enum output_unhappy_penalty unhappy_penalty;
 };
 
-struct city_production {
-  bool is_unit;
-  int value; /* Unit_type_id or Impr_type_id */
-};
-
 enum choice_type { CT_NONE = 0, CT_BUILDING = 0, CT_NONMIL, CT_ATTACKER,
                    CT_DEFENDER, CT_LAST };
 
Index: common/dataio.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/dataio.c,v
retrieving revision 1.20
diff -p -u -r1.20 dataio.c
--- common/dataio.c     15 Jul 2005 16:09:05 -0000      1.20
+++ common/dataio.c     27 Jul 2005 03:06:55 -0000
@@ -395,8 +395,8 @@ void dio_put_worklist(struct data_out *d
 
     dio_put_uint8(dout, length);
     for (i = 0; i < length; i++) {
-      dio_put_uint8(dout, pwl->wlefs[i]);
-      dio_put_uint8(dout, pwl->wlids[i]);
+      dio_put_bool8(dout, pwl->entries[i].is_unit);
+      dio_put_uint8(dout, pwl->entries[i].value);
     }
   }
 }
@@ -646,22 +646,16 @@ void dio_get_worklist(struct data_in *di
   if (pwl->is_valid) {
     int i, length;
 
-    strcpy(pwl->name,"xyz");
+    init_worklist(pwl);
 
     dio_get_uint8(din, &length);
-
-    if (length < MAX_LEN_WORKLIST) {
-      pwl->wlefs[length] = WEF_END;
-      pwl->wlids[length] = 0;
-    }
-
-    if (length > MAX_LEN_WORKLIST) {
-      length = MAX_LEN_WORKLIST;
-    }
-
     for (i = 0; i < length; i++) {
-      dio_get_uint8(din, (int *) &pwl->wlefs[i]);
-      dio_get_uint8(din, &pwl->wlids[i]);
+      bool is_unit;
+      int value;
+
+      dio_get_bool8(din, &is_unit);
+      dio_get_uint8(din, &value);
+      worklist_append(pwl, value, is_unit);
     }
   }
 }
Index: common/fc_types.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/fc_types.h,v
retrieving revision 1.29
diff -p -u -r1.29 fc_types.h
--- common/fc_types.h   22 Jul 2005 16:18:05 -0000      1.29
+++ common/fc_types.h   27 Jul 2005 03:06:55 -0000
@@ -14,6 +14,8 @@
 #ifndef FC__FC_TYPES_H
 #define FC__FC_TYPES_H
 
+#include "shared.h"
+
 /* This file serves to reduce the cross-inclusion of header files which
  * occurs when a type which is defined in one file is needed for a fuction
  * definition in another file.
@@ -54,6 +56,11 @@ enum output_type_id {
 #define O_COUNT num_output_types
 #define O_MAX O_LAST /* Changing this breaks network compatibility. */
 
+struct city_production {
+  bool is_unit;
+  int value; /* Unit_type_id or Impr_type_id */
+};
+
 /* Some integers here could be uint8 values perhaps, but this is probably
  * not worth it.  Storage space is not an issue for these types. */
 typedef signed short Continent_id;
Index: common/worklist.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/worklist.c,v
retrieving revision 1.18
diff -p -u -r1.18 worklist.c
--- common/worklist.c   25 Jun 2004 23:43:01 -0000      1.18
+++ common/worklist.c   27 Jul 2005 03:06:56 -0000
@@ -15,12 +15,14 @@
 #include <config.h>
 #endif
 
+#include <stdarg.h>
 #include <string.h>
 
-#include "city.h"
 #include "mem.h"
-#include "unit.h"
+#include "support.h"
 
+#include "city.h"
+#include "unit.h"
 #include "worklist.h"
 
 /****************************************************************
@@ -33,11 +35,12 @@ void init_worklist(struct worklist *pwl)
   int i;
 
   pwl->is_valid = TRUE;
+  pwl->length = 0;
   strcpy(pwl->name, "a worklist");
 
   for (i = 0; i < MAX_LEN_WORKLIST; i++) {
-    pwl->wlefs[i] = WEF_END;
-    pwl->wlids[i] = 0;
+    pwl->entries[i].is_unit = FALSE;
+    pwl->entries[i].value = -1;
   }
 }
 
@@ -48,15 +51,8 @@ void init_worklist(struct worklist *pwl)
 ****************************************************************************/
 int worklist_length(const struct worklist *pwl)
 {
-  int len = 0;
-
-  if (pwl) {
-    while (len < MAX_LEN_WORKLIST && pwl->wlefs[len] != WEF_END) {
-      len++;
-    }
-  }
-
-  return len;
+  assert(pwl->length >= 0 && pwl->length < MAX_LEN_WORKLIST);
+  return pwl->length;
 }
 
 /****************************************************************
@@ -64,7 +60,7 @@ int worklist_length(const struct worklis
 ****************************************************************/
 bool worklist_is_empty(const struct worklist *pwl)
 {
-  return !pwl || pwl->wlefs[0] == WEF_END;
+  return !pwl || pwl->length == 0;
 }
 
 /****************************************************************
@@ -87,19 +83,15 @@ bool worklist_peek(const struct worklist
 bool worklist_peek_ith(const struct worklist *pwl, int *id, bool *is_unit,
                      int idx)
 {
-  int i;
-
   /* Out of possible bounds. */
-  if (idx < 0 || MAX_LEN_WORKLIST <= idx)
+  if (idx < 0 || pwl->length <= idx) {
+    *is_unit = FALSE;
+    *id = -1;
     return FALSE;
+  }
 
-  /* Worklist isn't long enough. */
-  for (i = 0; i <= idx; i++)
-    if (pwl->wlefs[i] == WEF_END)
-      return FALSE;
-
-  *is_unit = (pwl->wlefs[idx] == WEF_UNIT);
-  *id = pwl->wlids[idx];
+  *is_unit = pwl->entries[idx].is_unit;
+  *id = pwl->entries[idx].value;
 
   return TRUE;
 }
@@ -125,20 +117,20 @@ void copy_worklist(struct worklist *dst,
 ****************************************************************/
 void worklist_remove(struct worklist *pwl, int idx)
 {
+  int i;
+
   /* Don't try to remove something way outside of the worklist. */
-  if (idx < 0 || MAX_LEN_WORKLIST <= idx)
+  if (idx < 0 || pwl->length <= idx) {
     return;
+  }
 
   /* Slide everything up one spot. */
-  if (idx < MAX_LEN_WORKLIST-1) {
-    memmove(&pwl->wlefs[idx], &pwl->wlefs[idx+1],
-           sizeof(enum worklist_elem_flag) * (MAX_LEN_WORKLIST-1-idx));
-    memmove(&pwl->wlids[idx], &pwl->wlids[idx+1],
-           sizeof(int) * (MAX_LEN_WORKLIST-1-idx));
+  for (i = idx; i < pwl->length - 1; i++) {
+    pwl->entries[i] = pwl->entries[i + 1];
   }
-
-  pwl->wlefs[MAX_LEN_WORKLIST-1] = WEF_END;
-  pwl->wlids[MAX_LEN_WORKLIST-1] = 0;
+  pwl->entries[pwl->length - 1].is_unit = FALSE;
+  pwl->entries[pwl->length - 1].value = -1;
+  pwl->length--;
 }
 
 /****************************************************************************
@@ -153,14 +145,10 @@ bool worklist_append(struct worklist *pw
   if (next_index >= MAX_LEN_WORKLIST) {
     return FALSE;
   }
-  
-  pwl->wlefs[next_index] = (is_unit ? WEF_UNIT : WEF_IMPR);
-  pwl->wlids[next_index] = id;
-  
-  if (next_index + 1 < MAX_LEN_WORKLIST) {
-    pwl->wlefs[next_index + 1] = WEF_END;
-    pwl->wlids[next_index + 1] = 0;
-  }
+
+  pwl->entries[next_index].is_unit = is_unit;
+  pwl->entries[next_index].value = id;
+  pwl->length++;
 
   return TRUE;
 }
@@ -173,32 +161,24 @@ bool worklist_append(struct worklist *pw
 ****************************************************************************/
 bool worklist_insert(struct worklist *pwl, int id, bool is_unit, int idx)
 {
-  int len = worklist_length(pwl);
+  int new_len = MIN(pwl->length + 1, MAX_LEN_WORKLIST), i;
 
-  if (len >= MAX_LEN_WORKLIST || idx > len) {
-    /* NOTE: the insert will fail rather than just dropping the last item. */
+  if (idx < 0 || idx > pwl->length) {
     return FALSE;
   }
 
   /* move all active values down an index to get room for new id
-   * move from [idx .. len - 1] to [idx + 1 .. len].
-   * Don't copy WEF_END (the terminator) because that might end up outside of
-   * the list. */
-  memmove(&pwl->wlefs[idx + 1], &pwl->wlefs[idx],
-         sizeof(pwl->wlefs[0]) * (len - idx));
-  memmove(&pwl->wlids[idx + 1], &pwl->wlids[idx],
-         sizeof(pwl->wlids[0]) * (len - idx));
-  
-  pwl->wlefs[idx] = (is_unit ? WEF_UNIT : WEF_IMPR);
-  pwl->wlids[idx] = id;
-  
-  /* Since we don't copy the WEF_END, need to reinsert it at the end
-   * if there is room. */
-  if (len + 1 < MAX_LEN_WORKLIST) {
-    pwl->wlefs[len + 1] = WEF_END;
-    pwl->wlids[len + 1] = 0;
+   * move from [idx .. len - 1] to [idx + 1 .. len].  Any entries at the
+   * end are simply lost. */
+  for (i = new_len - 1; i >= idx; i--) {
+    pwl->entries[i + 1] = pwl->entries[i];
   }
   
+  pwl->entries[idx].is_unit = is_unit;
+  pwl->entries[idx].value = id;
+
+  pwl->length = new_len;
+
   return TRUE;
 }
 
@@ -208,21 +188,119 @@ bool worklist_insert(struct worklist *pw
 bool are_worklists_equal(const struct worklist *wlist1,
                         const struct worklist *wlist2)
 {
-  int i, len = worklist_length(wlist1);
+  int i;
 
   if (wlist1->is_valid != wlist2->is_valid) {
     return FALSE;
   }
-  if (worklist_length(wlist2) != len) {
+  if (wlist1->length != wlist2->length) {
     return FALSE;
   }
 
-  for (i = 0; i < len; i++) {
-    if (wlist1->wlefs[i] != wlist2->wlefs[i] ||
-       wlist1->wlids[i] != wlist2->wlids[i]) {
+  for (i = 0; i < wlist1->length; i++) {
+    if (wlist1->entries[i].is_unit != wlist2->entries[i].is_unit ||
+       wlist1->entries[i].value != wlist2->entries[i].value) {
       return FALSE;
     }
   }
 
   return TRUE;
 }
+
+/****************************************************************************
+  Load the worklist elements specified by path to the worklist pointed to
+  by pwl.
+
+  pwl should be a pointer to an existing worklist.
+
+  path and ... give the prefix to load from, printf-style.
+****************************************************************************/
+void worklist_load(struct section_file *file, struct worklist *pwl,
+                  const char *path, ...)
+{
+  int i;
+  const char* name;
+  char path_str[1024];
+  va_list ap;
+
+  /* The first part of the registry path is taken from the varargs to the
+   * function. */
+  va_start(ap, path);
+  vsnprintf(path_str, sizeof(path_str), path, ap);
+  va_end(ap);
+
+  init_worklist(pwl);
+  pwl->length = secfile_lookup_int_default(file, 0,
+                                          "%s.wl_length", path_str);
+  name = secfile_lookup_str_default(file, "a worklist",
+                                   "%s.wl_name", path_str);
+  sz_strlcpy(pwl->name, name);
+  pwl->is_valid = secfile_lookup_bool_default(file, FALSE,
+                                             "%s.wl_is_valid", path_str);
+
+  for (i = 0; i < pwl->length; i++) {
+    bool is_unit = secfile_lookup_bool_default(file, FALSE, "%s.wl_is_unit%d",
+                                              path_str, i);
+
+    /* We lookup the production value by name.  An invalid entry isn't a
+     * fatal error; we just drop the worklist. */
+    name = secfile_lookup_str_default(file, "-", "%s.wl_value%d",
+                                     path_str, i);
+    if (is_unit) {
+      struct unit_type *punittype = find_unit_type_by_name_orig(name);
+
+      if (!punittype) {
+       pwl->length = i;
+       break;
+      }
+      pwl->entries[i].value = punittype->index;
+    } else {
+      Impr_type_id building = find_improvement_by_name_orig(name);
+
+      if (building == B_LAST) {
+       pwl->length = i;
+       break;
+      }
+      pwl->entries[i].value = building;
+    }
+    pwl->entries[i].is_unit = is_unit;
+  }
+}
+
+/****************************************************************************
+  Save the worklist elements specified by path from the worklist pointed to
+  by pwl.
+
+  pwl should be a pointer to an existing worklist.
+
+  path and ... give the prefix to load from, printf-style.
+****************************************************************************/
+void worklist_save(struct section_file *file, struct worklist *pwl,
+                  const char *path, ...)
+{
+  char path_str[1024];
+  int i;
+  va_list ap;
+
+  /* The first part of the registry path is taken from the varargs to the
+   * function. */
+  va_start(ap, path);
+  vsnprintf(path_str, sizeof(path_str), path, ap);
+  va_end(ap);
+
+  secfile_insert_int(file, pwl->length, "%s.wl_length", path_str);
+  secfile_insert_str(file, pwl->name, "%s.wl_name", path_str);
+  secfile_insert_bool(file, pwl->is_valid, "%s.wl_is_valid", path_str);
+
+  for (i = 0; i < pwl->length; i++) {
+    struct city_production *entry = pwl->entries + i;
+    const char *name = (entry->is_unit
+                       ? get_unit_type(entry->value)->name
+                       : get_improvement_type(entry->value)->name);
+
+    secfile_insert_bool(file, entry->is_unit,
+                       "%s.wl_is_unit%d", path_str, i);
+    secfile_insert_str(file, name,
+                      "%s.wl_value%d", path_str, i);
+  }
+}
Index: common/worklist.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/worklist.h,v
retrieving revision 1.10
diff -p -u -r1.10 worklist.h
--- common/worklist.h   10 Apr 2005 19:27:34 -0000      1.10
+++ common/worklist.h   27 Jul 2005 03:06:56 -0000
@@ -13,25 +13,20 @@
 #ifndef FC__WORKLIST_H
 #define FC__WORKLIST_H
 
+#include "registry.h"
 #include "shared.h"            /* MAX_LEN_NAME */
 
+#include "fc_types.h"
+
 #define MAX_LEN_WORKLIST 16
 #define MAX_NUM_WORKLISTS 16
 
-/* worklist element flags */
-enum worklist_elem_flag {
-  WEF_END,     /* element is past end of list */
-  WEF_UNIT,    /* element specifies a unit to be built */
-  WEF_IMPR,    /* element specifies an improvement to be built */
-  WEF_LAST     /* leave this last */
-};
-
 /* a worklist */
 struct worklist {
   bool is_valid;
+  int length;
   char name[MAX_LEN_NAME];
-  enum worklist_elem_flag wlefs[MAX_LEN_WORKLIST];
-  int wlids[MAX_LEN_WORKLIST];
+  struct city_production entries[MAX_LEN_WORKLIST];
 };
 
 void init_worklist(struct worklist *pwl);
@@ -50,6 +45,16 @@ bool worklist_insert(struct worklist *pw
 bool are_worklists_equal(const struct worklist *wlist1,
                         const struct worklist *wlist2);
 
+/* Functions to load and save a worklist from a registry file.  The path
+ * is a printf-style string giving the registry prefix (which must be
+ * the same for saving and loading). */
+void worklist_load(struct section_file *file, struct worklist *pwl,
+                  const char *path, ...)
+  fc__attribute((format (printf, 3, 4)));
+void worklist_save(struct section_file *file, struct worklist *pwl,
+                  const char *path, ...)
+  fc__attribute((format (printf, 3, 4)));
+
 /* Iterate over all entries in the worklist.  Note the 'id' parameter
  * comes before the 'is_unit' one. */
 #define worklist_iterate(worklist, id, is_unit)                                
    \
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.269
diff -p -u -r1.269 savegame.c
--- server/savegame.c   26 Jul 2005 16:36:00 -0000      1.269
+++ server/savegame.c   27 Jul 2005 03:06:57 -0000
@@ -183,7 +183,7 @@
    pre-1.13.0 savegames is broken: startoptions, spacerace2
    and rulesets */
 #define SAVEFILE_OPTIONS "startoptions spacerace2 rulesets" \
-" diplchance_percent worklists2 map_editor known32fix turn " \
+" diplchance_percent map_editor known32fix turn " \
 "attributes watchtower rulesetdir client_worklists orders " \
 "startunits turn_last_built improvement_order technology_order embassies " \
 "owner_player_map"
@@ -1373,124 +1373,6 @@ static const char* old_government_name(i
   }
 }
 
-
-/***************************************************************
-Load the worklist elements specified by path, given the arguments
-plrno and wlinx, into the worklist pointed to by pwl.
-***************************************************************/
-static void worklist_load(struct section_file *file,
-                         const char *path, int plrno, int wlinx,
-                         struct worklist *pwl)
-{
-  char efpath[64];
-  char idpath[64];
-  char namepath[64];
-  int i;
-  bool end = FALSE;
-  const char* name;
-
-  sz_strlcpy(efpath, path);
-  sz_strlcat(efpath, ".wlef%d");
-  sz_strlcpy(idpath, path);
-  sz_strlcat(idpath, ".wlid%d");
-  sz_strlcpy(namepath, path);
-  sz_strlcat(namepath, ".wlname%d");
-
-  for (i = 0; i < MAX_LEN_WORKLIST; i++) {
-    if (end) {
-      pwl->wlefs[i] = WEF_END;
-      pwl->wlids[i] = 0;
-      (void) section_file_lookup(file, efpath, plrno, wlinx, i);
-      (void) section_file_lookup(file, idpath, plrno, wlinx, i);
-    } else {
-      pwl->wlefs[i] =
-       secfile_lookup_int_default(file, WEF_END, efpath, plrno, wlinx, i);
-      name = secfile_lookup_str_default(file, NULL, namepath, plrno, wlinx, i);
-
-      if (pwl->wlefs[i] == WEF_UNIT) {
-       struct unit_type *type;
-
-       if (!name) {
-           /* before 1.15.0 unit types used to be saved by id */
-           name = old_unit_type_name(secfile_lookup_int(file, idpath,
-                                                        plrno, wlinx, i));
-       }
-
-       type = find_unit_type_by_name_orig(name);
-       if (!type) {
-         freelog(LOG_ERROR, _("Unknown unit type '%s' in worklist"),
-                 name);
-         exit(EXIT_FAILURE);
-       }
-       pwl->wlids[i] = type->index;
-      } else if (pwl->wlefs[i] == WEF_IMPR) {
-       Impr_type_id type;
-
-       if (!name) {
-         name = old_impr_type_name(secfile_lookup_int(file, idpath,
-                                                      plrno, wlinx, i));
-       }
-
-       type = find_improvement_by_name_orig(name);
-       if (type == B_LAST) {
-         freelog(LOG_ERROR, _("Unknown improvement type '%s' in worklist"),
-                  name);
-       }
-       pwl->wlids[i] = type;
-      }
-
-      if ((pwl->wlefs[i] <= WEF_END) || (pwl->wlefs[i] >= WEF_LAST) ||
-         pwl->wlefs[i] == WEF_UNIT ||
-         ((pwl->wlefs[i] == WEF_IMPR) && !improvement_exists(pwl->wlids[i]))) {
-       pwl->wlefs[i] = WEF_END;
-       pwl->wlids[i] = 0;
-       end = TRUE;
-      }
-    }
-  }
-}
-
-/***************************************************************
-Load the worklist elements specified by path, given the arguments
-plrno and wlinx, into the worklist pointed to by pwl.
-Assumes original save-file format.  Use for backward compatibility.
-***************************************************************/
-static void worklist_load_old(struct section_file *file,
-                             const char *path, int plrno, int wlinx,
-                             struct worklist *pwl)
-{
-  int i, id;
-  bool end = FALSE;
-  const char* name;
-
-  for (i = 0; i < MAX_LEN_WORKLIST; i++) {
-    if (end) {
-      pwl->wlefs[i] = WEF_END;
-      pwl->wlids[i] = 0;
-      (void) section_file_lookup(file, path, plrno, wlinx, i);
-    } else {
-      id = secfile_lookup_int_default(file, -1, path, plrno, wlinx, i);
-
-      if ((id < 0) || (id >= 284)) { /* 284 was flag value for end of list */
-       pwl->wlefs[i] = WEF_END;
-       pwl->wlids[i] = 0;
-       end = TRUE;
-      } else if (id >= 68) {           /* 68 was offset to unit ids */
-       name = old_unit_type_name(id-68);
-       pwl->wlefs[i] = WEF_UNIT;
-       pwl->wlids[i] = find_unit_type_by_name_orig(name)->index;
-       end = (pwl->wlids[i] < 0 || pwl->wlids[i] >= 
game.control.num_unit_types);
-      } else {                         /* must be an improvement id */
-       name = old_impr_type_name(id);
-       pwl->wlefs[i] = WEF_IMPR;
-       pwl->wlids[i] = find_improvement_by_name_orig(name);
-       end = !improvement_exists(pwl->wlids[i]);
-      }
-    }
-  }
-
-}
-
 /****************************************************************************
   Loads the units for the given player.
 ****************************************************************************/
@@ -2337,12 +2219,7 @@ static void player_load(struct player *p
     }
 
     init_worklist(&pcity->worklist);
-    if (has_capability("worklists2", savefile_options)) {
-      worklist_load(file, "player%d.c%d", plrno, i, &pcity->worklist);
-    } else {
-      worklist_load_old(file, "player%d.c%d.worklist%d",
-                       plrno, i, &pcity->worklist);
-    }
+    worklist_load(file, &pcity->worklist, "player%d.c%d", plrno, i);
 
     /* FIXME: remove this when the urgency is properly recalculated. */
     pcity->ai.urgency = secfile_lookup_int_default(file, 0, 
@@ -2578,59 +2455,6 @@ static void player_map_load(struct playe
 }
 
 /***************************************************************
-Save the worklist elements specified by path, given the arguments
-plrno and wlinx, from the worklist pointed to by pwl.
-***************************************************************/
-static void worklist_save(struct section_file *file,
-                         const char *path, int plrno, int wlinx,
-                         struct worklist *pwl)
-{
-  char efpath[64];
-  char idpath[64];
-  char namepath[64];
-  int i;
-
-  sz_strlcpy(efpath, path);
-  sz_strlcat(efpath, ".wlef%d");
-  sz_strlcpy(idpath, path);
-  sz_strlcat(idpath, ".wlid%d");
-  sz_strlcpy(namepath, path);
-  sz_strlcat(namepath, ".wlname%d");
-
-  for (i = 0; i < MAX_LEN_WORKLIST; i++) {
-    secfile_insert_int(file, pwl->wlefs[i], efpath, plrno, wlinx, i);
-    if (pwl->wlefs[i] == WEF_UNIT) {
-      secfile_insert_int(file,
-                        old_unit_type_id(get_unit_type(pwl->wlids[i])),
-                        idpath,
-                        plrno, wlinx, i);
-      secfile_insert_str(file,
-                        unit_name_orig(get_unit_type(pwl->wlids[i])),
-                        namepath, plrno,
-                        wlinx, i);
-    } else if (pwl->wlefs[i] == WEF_IMPR) {
-      secfile_insert_int(file, pwl->wlids[i], idpath, plrno, wlinx, i);
-      secfile_insert_str(file, get_improvement_name_orig(pwl->wlids[i]),
-                        namepath, plrno, wlinx, i);
-    } else {
-      secfile_insert_int(file, 0, idpath, plrno, wlinx, i);
-      secfile_insert_str(file, "", namepath, plrno, wlinx, i);
-    }
-    if (pwl->wlefs[i] == WEF_END) {
-      break;
-    }
-  }
-
-  /* Fill out remaining worklist entries. */
-  for (i++; i < MAX_LEN_WORKLIST; i++) {
-    /* These values match what worklist_load fills in for unused entries. */
-    secfile_insert_int(file, WEF_END, efpath, plrno, wlinx, i);
-    secfile_insert_int(file, 0, idpath, plrno, wlinx, i);
-    secfile_insert_str(file, "", namepath, plrno, wlinx, i);
-  }
-}
-
-/***************************************************************
 ...
 ***************************************************************/
 static void player_save(struct player *plr, int plrno,
@@ -3087,7 +2911,7 @@ static void player_save(struct player *p
     secfile_insert_str(file, impr_buf,
                       "player%d.c%d.improvements_new", plrno, i);    
 
-    worklist_save(file, "player%d.c%d", plrno, i, &pcity->worklist);
+    worklist_save(file, &pcity->worklist, "player%d.c%d", plrno, i);
 
     /* FIXME: remove this when the urgency is properly recalculated. */
     secfile_insert_int(file, pcity->ai.urgency,

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#13550) use city_production struct in worklist code, Jason Short <=