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: Tue, 2 Aug 2005 11:51:31 -0700
Reply-to: bugs@xxxxxxxxxxx

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

And here's a working/final version of the patch.  I plan to commit this
patch but there's a lot more work to be done here.

-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    2 Aug 2005 18:50:54 -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)
+struct city_production cid_decode(cid cid)
 {
-  return (cid >= B_LAST) ? (cid - B_LAST) : cid;
-}
+  struct city_production target = {
+    .value = (cid >= B_LAST) ? (cid - B_LAST) : cid,
+    .is_unit = (cid >= B_LAST)
+  };
 
-/****************************************************************************
-  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 prod = {.is_unit = cid_is_unit(cid),
-                                .value = cid_id(cid)};
-
-  return prod;
+  return target;
 }
 
 /**************************************************************************
@@ -542,21 +538,25 @@ 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)
+/****************************************************************************
+  Return TRUE if the city supports at least one unit of the given
+  production type (returns FALSE if the production is a building).
+****************************************************************************/
+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)
@@ -566,13 +566,15 @@ bool city_unit_supported(struct city *pc
   return FALSE;
 }
 
-/****************************************************************
-...
-*****************************************************************/
-bool city_unit_present(struct city *pcity, cid cid)
+/****************************************************************************
+  Return TRUE if the city has present at least one unit of the given
+  production type (returns FALSE if the production is a building).
+****************************************************************************/
+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 +588,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 +599,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 +648,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 +687,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 +698,22 @@ 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 +761,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 +798,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 +807,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 +817,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 +835,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 +869,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    2 Aug 2005 18:50:54 -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/mapctrl_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/mapctrl_common.c,v
retrieving revision 1.60
diff -p -u -r1.60 mapctrl_common.c
--- client/mapctrl_common.c     2 Aug 2005 18:37:01 -0000       1.60
+++ client/mapctrl_common.c     2 Aug 2005 18:50:54 -0000
@@ -389,10 +389,9 @@ void clipboard_paste_production(struct c
 **************************************************************************/
 static void clipboard_send_production_packet(struct city *pcity)
 {
-  cid mycid = cid_encode(clipboard.is_unit, clipboard.value);
-
-  if (mycid == cid_encode_from_city(pcity)
-      || !city_can_build_impr_or_unit(pcity, mycid)) {
+  if ((clipboard.is_unit == pcity->production.is_unit
+       && clipboard.value == pcity->production.value)
+      || !city_can_build_impr_or_unit(pcity, clipboard)) {
     return;
   }
 
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        2 Aug 2005 18:50:55 -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        2 Aug 2005 18:50:55 -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  2 Aug 2005 18:50:55 -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]