Complete.Org: Mailing Lists: Archives: freeciv-dev: August 2005:
[Freeciv-Dev] (PR#13586) change CID api to use city_productions
Home

[Freeciv-Dev] (PR#13586) change CID api to use city_productions

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#13586) change CID api to use city_productions
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 1 Aug 2005 17:09:18 -0700
Reply-to: bugs@xxxxxxxxxxx

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

This is a partial patch to change most functions that currently take 
CIDs to instead take city_production structs.  The cid encoding/decoding 
functions also take city_productions.

The only reason cids are needed is because the GUI libraries (esp GTK) 
can more easily encode an integer than an arbitrary block of memory. 
However the use of integers here should be restricted only to the 
libraries I think - they should be encoded and decoded directly on 
library access.  This is just a couple places so it should make encoding 
and decoding easier.  But for now I haven't changed the GUI code much, 
just the client-common interface.

This patch is incomplete and obviously not ready for inclusion.  I 
noticed a few other things that should be cleaned up first so I will 
just leave the patch here for now.

-jason

Index: client/climisc.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/climisc.c,v
retrieving revision 1.174
diff -p -u -r1.174 climisc.c
--- client/climisc.c    1 Aug 2005 23:09:35 -0000       1.174
+++ client/climisc.c    1 Aug 2005 23:58:40 -0000
@@ -436,59 +436,55 @@ void center_on_something(void)
   can_slide = TRUE;
 }
 
-/**************************************************************************
-...
-**************************************************************************/
-cid cid_encode(bool is_unit, int id)
+/****************************************************************************
+  Encode a CID for the target production.
+****************************************************************************/
+cid cid_encode(struct city_production target)
 {
-  return id + (is_unit ? B_LAST : 0);
+  return target.value + (target.is_unit ? B_LAST : 0);
 }
 
-/**************************************************************************
-...
-**************************************************************************/
-cid cid_encode_from_city(struct city * pcity)
+/****************************************************************************
+  Encode a CID for the target unit type.
+****************************************************************************/
+cid cid_encode_unit(const struct unit_type *punittype)
 {
-  return cid_encode(pcity->production.is_unit, pcity->production.value);
+  struct city_production target
+    = {.is_unit = TRUE, .value = punittype->index};
+
+  return cid_encode(target);
 }
 
-/**************************************************************************
-...
-**************************************************************************/
-void cid_decode(cid cid, bool *is_unit, int *id)
+/****************************************************************************
+  Encode a CID for the target building.
+****************************************************************************/
+cid cid_encode_building(Impr_type_id building)
 {
-  *is_unit = cid_is_unit(cid);
-  *id = cid_id(cid);
+  struct city_production target
+    = {.is_unit = FALSE, .value = building};
+
+  return cid_encode(target);
 }
 
-/**************************************************************************
-...
-**************************************************************************/
-bool cid_is_unit(cid cid)
+/****************************************************************************
+  Encode a CID for the target city's production.
+****************************************************************************/
+cid cid_encode_from_city(const struct city *pcity)
 {
-  return (cid >= B_LAST);
+  return cid_encode(pcity->production);
 }
 
 /**************************************************************************
-...
+  Decode the CID into a city_production structure.
 **************************************************************************/
-int cid_id(cid cid)
-{
-  return (cid >= B_LAST) ? (cid - B_LAST) : cid;
-}
-
-/****************************************************************************
-  Return a city_production struct for the given cid.
-
-  This is a temporary sort of measure since hopefully the city_production
-  will someday replace the cid entirely.
-****************************************************************************/
-struct city_production cid_production(cid cid)
+struct city_production cid_decode(cid cid)
 {
-  struct city_production prod = {.is_unit = cid_is_unit(cid),
-                                .value = cid_id(cid)};
+  struct city_production target = {
+    .value = (cid >= B_LAST) ? (cid - B_LAST) : cid,
+    .is_unit = (cid >= B_LAST)
+  };
 
-  return prod;
+  return target;
 }
 
 /**************************************************************************
@@ -542,21 +538,24 @@ int wid_id(wid wid)
 /****************************************************************
 ...
 *****************************************************************/
-bool city_can_build_impr_or_unit(struct city *pcity, cid cid)
+bool city_can_build_impr_or_unit(const struct city *pcity,
+                                struct city_production target)
 {
-  if (cid_is_unit(cid))
-    return can_build_unit(pcity, get_unit_type(cid_id(cid)));
-  else
-    return can_build_improvement(pcity, cid_id(cid));
+  if (target.is_unit) {
+    return can_build_unit(pcity, get_unit_type(target.value));
+  } else {
+    return can_build_improvement(pcity, target.value);
+  }
 }
 
 /****************************************************************
 ...
 *****************************************************************/
-bool city_unit_supported(struct city *pcity, cid cid)
+bool city_unit_supported(const struct city *pcity,
+                        struct city_production target)
 {
-  if (cid_is_unit(cid)) {
-    struct unit_type *unit_type = get_unit_type(cid_id(cid));
+  if (target.is_unit) {
+    struct unit_type *unit_type = get_unit_type(target.value);
 
     unit_list_iterate(pcity->units_supported, punit) {
       if (punit->type == unit_type)
@@ -569,10 +568,11 @@ bool city_unit_supported(struct city *pc
 /****************************************************************
 ...
 *****************************************************************/
-bool city_unit_present(struct city *pcity, cid cid)
+bool city_unit_present(const struct city *pcity,
+                      struct city_production target)
 {
-  if (cid_is_unit(cid)) {
-    struct unit_type *unit_type = get_unit_type(cid_id(cid));
+  if (target.is_unit) {
+    struct unit_type *unit_type = get_unit_type(target.value);
 
     unit_list_iterate(pcity->tile->units, punit) {
       if (punit->type == unit_type)
@@ -586,14 +586,10 @@ bool city_unit_present(struct city *pcit
 /****************************************************************************
   A TestCityFunc to tell whether the item is a building and is present.
 ****************************************************************************/
-bool city_building_present(struct city *pcity, cid cid)
+bool city_building_present(const struct city *pcity,
+                          struct city_production target)
 {
-  if (!cid_is_unit(cid)) {
-    int impr_type = cid_id(cid);
-
-    return city_got_building(pcity, impr_type);
-  }
-  return FALSE;
+  return !target.is_unit && city_got_building(pcity, target.value);
 }
 
 /**************************************************************************
@@ -601,19 +597,18 @@ bool city_building_present(struct city *
 **************************************************************************/
 static int cid_get_section(cid cid)
 {
-  bool is_unit = cid_is_unit(cid);
-  int id = cid_id(cid);
+  struct city_production target = cid_decode(cid);
 
-  if (is_unit) {
-    if (unit_type_flag(get_unit_type(id), F_NONMIL)) {
+  if (target.is_unit) {
+    if (unit_type_flag(get_unit_type(target.value), F_NONMIL)) {
       return 2;
     } else {
       return 3;
     }
   } else {
-    if (building_has_effect(id, EFT_PROD_TO_GOLD)) {
+    if (building_has_effect(target.value, EFT_PROD_TO_GOLD)) {
       return 1;
-    } else if (is_great_wonder(id)) {
+    } else if (is_great_wonder(target.value)) {
       return 4;
     } else {
       return 0;
@@ -651,22 +646,22 @@ void name_and_sort_items(int *pcids, int
   int i;
 
   for (i = 0; i < num_cids; i++) {
-    bool is_unit = cid_is_unit(pcids[i]);
-    int id = cid_id(pcids[i]), cost;
+    struct city_production target = cid_decode(pcids[i]);
+    int cost;
     struct item *pitem = &items[i];
     const char *name;
 
     pitem->cid = pcids[i];
 
-    if (is_unit) {
-      name = get_unit_name(get_unit_type(id));
-      cost = unit_build_shield_cost(get_unit_type(id));
+    if (target.is_unit) {
+      name = get_unit_name(get_unit_type(target.value));
+      cost = unit_build_shield_cost(get_unit_type(target.value));
     } else {
-      name = get_impr_name_ex(pcity, id);
-      if (building_has_effect(id, EFT_PROD_TO_GOLD)) {
+      name = get_impr_name_ex(pcity, target.value);
+      if (building_has_effect(target.value, EFT_PROD_TO_GOLD)) {
        cost = -1;
       } else {
-       cost = impr_build_shield_cost(id);
+       cost = impr_build_shield_cost(target.value);
       }
     }
 
@@ -690,7 +685,7 @@ void name_and_sort_items(int *pcids, int
 int collect_cids1(cid * dest_cids, struct city **selected_cities,
                  int num_selected_cities, bool append_units,
                  bool append_wonders, bool change_prod,
-                 bool (*test_func) (struct city *, int))
+                 TestCityFunc test_func)
 {
   cid first = append_units ? B_LAST : 0;
   cid last = (append_units
@@ -701,21 +696,21 @@ int collect_cids1(cid * dest_cids, struc
 
   for (cid = first; cid < last; cid++) {
     bool append = FALSE;
-    int id = cid_id(cid);
+    struct city_production target = cid_decode(cid);
 
-    if (!append_units && (append_wonders != is_wonder(id)))
+    if (!append_units && (append_wonders != is_wonder(target.value)))
       continue;
 
     if (!change_prod) {
       city_list_iterate(game.player_ptr->cities, pcity) {
-       append |= test_func(pcity, cid);
+       append |= test_func(pcity, cid_decode(cid));
       }
       city_list_iterate_end;
     } else {
       int i;
 
       for (i = 0; i < num_selected_cities; i++) {
-       append |= test_func(selected_cities[i], cid);
+       append |= test_func(selected_cities[i], cid_decode(cid));
       }
     }
 
@@ -763,16 +758,14 @@ int collect_cids3(cid * dest_cids)
 
   impr_type_iterate(id) {
     if (can_player_build_improvement(game.player_ptr, id)) {
-      dest_cids[cids_used] = cid_encode(FALSE, id);
+      dest_cids[cids_used] = cid_encode_building(id);
       cids_used++;
     }
   } impr_type_iterate_end;
 
   unit_type_iterate(punittype) {
-    const int id = punittype->index;
-
     if (can_player_build_unit(game.player_ptr, punittype)) {
-      dest_cids[cids_used] = cid_encode(TRUE, id);
+      dest_cids[cids_used] = cid_encode_unit(punittype);
       cids_used++;
     }
   } unit_type_iterate_end
@@ -802,7 +795,7 @@ int collect_cids4(cid * dest_cids, struc
 
     if ((advanced_tech && can_eventually_build) ||
        (!advanced_tech && can_build)) {
-      dest_cids[cids_used] = cid_encode(FALSE, id);
+      dest_cids[cids_used] = cid_encode_building(id);
       cids_used++;
     }
   } impr_type_iterate_end;
@@ -811,7 +804,6 @@ int collect_cids4(cid * dest_cids, struc
     bool can_build = can_player_build_unit(game.player_ptr, punittype);
     bool can_eventually_build =
        can_player_eventually_build_unit(game.player_ptr, punittype);
-    const int id = punittype->index;
 
     /* If there's a city, can the city build the unit? */
     if (pcity) {
@@ -822,7 +814,7 @@ int collect_cids4(cid * dest_cids, struc
 
     if ((advanced_tech && can_eventually_build) ||
        (!advanced_tech && can_build)) {
-      dest_cids[cids_used] = cid_encode(TRUE, id);
+      dest_cids[cids_used] = cid_encode_unit(punittype);
       cids_used++;
     }
   } unit_type_iterate_end;
@@ -840,7 +832,7 @@ int collect_cids5(cid * dest_cids, struc
   assert(pcity != NULL);
 
   built_impr_iterate(pcity, id) {
-    dest_cids[cids_used] = cid_encode(FALSE, id);
+    dest_cids[cids_used] = cid_encode_building(id);
     cids_used++;
   } built_impr_iterate_end;
 
@@ -874,8 +866,9 @@ int collect_wids1(wid * dest_wids, struc
   name_and_sort_items(cids, cids_used, items, FALSE, pcity);
 
   for (item = 0; item < cids_used; item++) {
-    cid cid = items[item].cid;
-    dest_wids[wids_used] = wid_encode(cid_is_unit(cid), FALSE, cid_id(cid));
+    struct city_production target = cid_decode(items[item].cid);
+
+    dest_wids[wids_used] = wid_encode(target.is_unit, FALSE, target.value);
     wids_used++;
   }
 
Index: client/climisc.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/climisc.h,v
retrieving revision 1.57
diff -p -u -r1.57 climisc.h
--- client/climisc.h    1 Aug 2005 23:09:35 -0000       1.57
+++ client/climisc.h    1 Aug 2005 23:58:40 -0000
@@ -51,12 +51,13 @@ void center_on_something(void);
  * unit_type_id of (cid - B_LAST).
  */
 
-cid cid_encode(bool is_unit, int id);
-cid cid_encode_from_city(struct city *pcity);
-void cid_decode(cid cid, bool *is_unit, int *id);
-bool cid_is_unit(cid cid);
-int cid_id(cid cid);
-struct city_production cid_production(cid cid);
+cid cid_encode(struct city_production target);
+cid cid_encode_unit(const struct unit_type *punittype);
+cid cid_encode_building(Impr_type_id building);
+cid cid_encode_from_city(const struct city *pcity);
+
+struct city_production cid_decode(cid cid);
+#define cid_production cid_decode
 
 /* 
  * A worklist id (wid) can hold all objects which can be part of a
@@ -76,22 +77,28 @@ bool wid_is_unit(wid wid);
 bool wid_is_worklist(wid wid);
 int wid_id(wid wid);
 
-bool city_can_build_impr_or_unit(struct city *pcity, cid cid);
-bool city_unit_supported(struct city *pcity, cid cid);
-bool city_unit_present(struct city *pcity, cid cid);
-bool city_building_present(struct city *pcity, cid cid);
+bool city_can_build_impr_or_unit(const struct city *pcity,
+                                struct city_production target);
+bool city_unit_supported(const struct city *pcity,
+                        struct city_production target);
+bool city_unit_present(const struct city *pcity,
+                      struct city_production target);
+bool city_building_present(const struct city *pcity,
+                          struct city_production target);
 
 struct item {
   cid cid;
   char descr[MAX_LEN_NAME + 40];
 };
 
+typedef bool (*TestCityFunc)(const struct city *, struct city_production);
+
 void name_and_sort_items(int *pcids, int num_cids, struct item *items,
                         bool show_cost, struct city *pcity);
 int collect_cids1(cid * dest_cids, struct city **selected_cities,
                 int num_selected_cities, bool append_units,
                 bool append_wonders, bool change_prod,
-                bool (*test_func) (struct city *, int));
+                 TestCityFunc test_func);
 int collect_cids2(cid * dest_cids);
 int collect_cids3(cid * dest_cids);
 int collect_cids4(cid * dest_cids, struct city *pcity, bool advanced_tech);
Index: client/gui-gtk-2.0/citydlg.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/citydlg.c,v
retrieving revision 1.137
diff -p -u -r1.137 citydlg.c
--- client/gui-gtk-2.0/citydlg.c        1 Aug 2005 23:09:35 -0000       1.137
+++ client/gui-gtk-2.0/citydlg.c        1 Aug 2005 23:58:42 -0000
@@ -1555,19 +1555,17 @@ static void city_dialog_update_building(
   name_and_sort_items(cids, cids_used, items, FALSE, pcity);
 
   for (item = 0; item < cids_used; item++) {
-    if (city_can_build_impr_or_unit(pcity, items[item].cid)) {
-      bool is_unit;
-      int id;
+    if (city_can_build_impr_or_unit(pcity, cid_decode(items[item].cid))) {
       const char* name;
       struct sprite* sprite;
+      struct city_production target = cid_decode(items[item].cid);
 
-      cid_decode(items[item].cid, &is_unit, &id);
-      if (is_unit) {
-       name = unit_name(get_unit_type(id));
-       sprite = get_unittype_sprite(tileset, get_unit_type(id));
+      if (target.is_unit) {
+       name = unit_name(get_unit_type(target.value));
+       sprite = get_unittype_sprite(tileset, get_unit_type(target.value));
       } else {
-       name = get_improvement_name(id);
-       sprite = get_building_sprite(tileset, id);
+       name = get_improvement_name(target.value);
+       sprite = get_building_sprite(tileset, target.value);
       }
       gtk_list_store_append(store, &iter);
       gtk_list_store_set(store, &iter, 0, sprite_get_pixbuf(sprite),
@@ -1603,17 +1601,18 @@ static void city_dialog_update_improveme
   total = 0;
   for (item = 0; item < cids_used; item++) {
     GtkTreeIter it;
-    int id, upkeep;
+    int upkeep;
     struct sprite *sprite;
-   
-    id = cid_id(items[item].cid);
+    struct city_production target = cid_decode(items[item].cid);
+
+    assert(!target.is_unit);
     /* This takes effects (like Adam Smith's) into account. */
-    upkeep = improvement_upkeep(pdialog->pcity, id);
-    sprite = get_building_sprite(tileset, id);
+    upkeep = improvement_upkeep(pdialog->pcity, target.value);
+    sprite = get_building_sprite(tileset, target.value);
 
     gtk_list_store_append(store, &it);
     gtk_list_store_set(store, &it,
-       0, id,
+                      0, target.value,
                       1, sprite_get_pixbuf(sprite),
        2, items[item].descr,
        3, upkeep,
Index: client/gui-gtk-2.0/cityrep.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk-2.0/cityrep.c,v
retrieving revision 1.76
diff -p -u -r1.76 cityrep.c
--- client/gui-gtk-2.0/cityrep.c        1 Aug 2005 23:09:36 -0000       1.76
+++ client/gui-gtk-2.0/cityrep.c        1 Aug 2005 23:58:42 -0000
@@ -186,12 +186,6 @@ void popdown_city_report_dialog(void)
   }
 }
 
-
-/****************************************************************
-...
-*****************************************************************/
-typedef bool (*TestCityFunc)(struct city *, gint);
-
 /****************************************************************
 ...
 *****************************************************************/
@@ -419,7 +413,7 @@ static void select_impr_or_unit_callback
       itree_get(&it, 0, &res, -1);
       pcity = res;
 
-      if (test_func(pcity, cid)) {
+      if (test_func(pcity, cid_decode(cid))) {
        itree_select(city_selection, &it);
       }
     }
@@ -1491,9 +1485,12 @@ static void create_select_menu(GtkWidget
 /****************************************************************
 ...
 *****************************************************************/
-static bool city_building_impr_or_unit(struct city *pcity, cid cid)
+static bool city_building_impr_or_unit(const struct city *pcity,
+                                      struct city_production target)
 {
-  return (cid == cid_encode_from_city(pcity));
+  struct city_production target2 = pcity->production;
+
+  return target.is_unit == target2.is_unit && target.value == target2.value;
 }
 
 /****************************************************************
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.48
diff -p -u -r1.48 wldlg.c
--- client/gui-gtk-2.0/wldlg.c  1 Aug 2005 23:09:36 -0000       1.48
+++ client/gui-gtk-2.0/wldlg.c  1 Aug 2005 23:58:42 -0000
@@ -485,7 +485,7 @@ static void menu_item_callback(GtkMenuIt
       GtkTreeIter it;
       cid cid;
 
-      cid = cid_encode(pwl->entries[i].is_unit, pwl->entries[i].value);
+      cid = cid_encode(pwl->entries[i]);
 
       gtk_list_store_append(ptr->dst, &it);
       gtk_list_store_set(ptr->dst, &it, 0, (gint) cid, -1);
@@ -548,19 +548,18 @@ static void help_callback(GtkWidget *w, 
 
   if (gtk_tree_selection_get_selected(selection, &model, &it)) {
     gint cid;
-    int id;
-    bool is_unit;
+    struct city_production target = cid_decode(cid);
 
     gtk_tree_model_get(model, &it, 0, &cid, -1);
-    is_unit = cid_is_unit(cid);
-    id = cid_id(cid);
 
-    if (is_unit) {
-      popup_help_dialog_typed(get_unit_type(id)->name, HELP_UNIT);
-    } else if (is_great_wonder(id)) {
-      popup_help_dialog_typed(get_improvement_name(id), HELP_WONDER);
+    if (target.is_unit) {
+      popup_help_dialog_typed(get_unit_type(target.value)->name, HELP_UNIT);
+    } else if (is_great_wonder(target.value)) {
+      popup_help_dialog_typed(get_improvement_name(target.value),
+                             HELP_WONDER);
     } else {
-      popup_help_dialog_typed(get_improvement_name(id), HELP_IMPROVEMENT);
+      popup_help_dialog_typed(get_improvement_name(target.value),
+                             HELP_IMPROVEMENT);
     }
   } else {
     popup_help_dialog_string(HELP_WORKLIST_EDITOR_ITEM);
@@ -1391,9 +1390,7 @@ void refresh_worklist(GtkWidget *editor)
   }
 
   for (i = 0; i < worklist_length(&queue); i++) {
-    cid cid;
-
-    cid = cid_encode(queue.entries[i].is_unit, queue.entries[i].value);
+    cid cid = cid_encode(queue.entries[i]);
 
     if (!exists) {
       gtk_list_store_append(ptr->dst, &it);

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