[Freeciv-Dev] (PR#11828) patch: partial city update for what-if scenario
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=11828 >
Here's a new version of the patch with the unreal-tile crash fixed.
-jason
? gprof
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.305
diff -u -r1.305 city.c
--- common/city.c 16 Jan 2005 11:11:01 -0000 1.305
+++ common/city.c 19 Jan 2005 04:44:22 -0000
@@ -1656,15 +1656,12 @@
static inline void get_worked_tile_output(const struct city *pcity,
int *output)
{
- bool is_celebrating = base_city_celebrating(pcity);
-
memset(output, 0, O_COUNT * sizeof(*output));
city_map_iterate(x, y) {
- if (get_worker_city(pcity, x, y) == C_TILE_WORKER) {
+ if (pcity->city_map[x][y] == C_TILE_WORKER) {
output_type_iterate(o) {
- output[o] += base_city_get_output_tile(x, y, pcity,
- is_celebrating, o);
+ output[o] += pcity->tile_output[x][y][o];
} output_type_iterate_end;
}
} city_map_iterate_end;
@@ -1712,6 +1709,24 @@
} output_type_iterate_end;
}
+/****************************************************************************
+ This function sets all the values in the pcity->tile_output[] array. This
+ should be called near the beginning of generic_city_refresh. It doesn't
+ depend on anything else in the refresh and doesn't change when workers are
+ moved around (but does change when buildings are built, etc.).
+****************************************************************************/
+static inline void set_city_tile_output(struct city *pcity)
+{
+ bool is_celebrating = base_city_celebrating(pcity);
+
+ city_map_checked_iterate(pcity->tile, x, y, ptile) {
+ output_type_iterate(o) {
+ pcity->tile_output[x][y][o]
+ = base_city_get_output_tile(x, y, pcity, is_celebrating, o);
+ } output_type_iterate_end;
+ } city_map_checked_iterate_end;
+}
+
/**************************************************************************
Set the final surplus[] array from the prod[] and usage[] values.
**************************************************************************/
@@ -2172,16 +2187,34 @@
}
/**************************************************************************
-...
+ Refreshes the internal cached data in the city structure.
+
+ There are two possible levels of refresh: a partial refresh and a full
+ refresh. A partial refresh is faster but can only be used in a few
+ places.
+
+ A full refresh updates all cached data: including but not limited to
+ ppl_happy[], surplus[], waste[], citizen_base[], usage[], trade[],
+ bonus[], and tile_output[].
+
+ A partial refresh will not update tile_output[] or bonus[]. These two
+ values do not need to be recalculated when moving workers around or when
+ a trade route has changed. A partial refresh will also not refresh any
+ cities that have trade routes with us. Any time a partial refresh is
+ done it should be considered temporary: when finished, the city should
+ be reverted to its original state.
**************************************************************************/
void generic_city_refresh(struct city *pcity,
- bool refresh_trade_route_cities,
+ bool full_refresh,
void (*send_unit_info) (struct player * pplayer,
struct unit * punit))
{
int prev_tile_trade = pcity->citizen_base[O_TRADE];
- set_city_bonuses(pcity); /* Calculate the bonus[] array values. */
+ if (full_refresh) {
+ set_city_bonuses(pcity); /* Calculate the bonus[] array values. */
+ set_city_tile_output(pcity); /* Calculate the tile_output[] values. */
+ }
get_citizen_output(pcity, pcity->citizen_base); /* Calculate output from
citizens. */
set_city_production(pcity);
citizen_happy_size(pcity);
@@ -2194,7 +2227,7 @@
unhappy_city_check(pcity);
set_surpluses(pcity);
- if (refresh_trade_route_cities
+ if (full_refresh
&& pcity->citizen_base[O_TRADE] != prev_tile_trade) {
int i;
@@ -2431,6 +2464,7 @@
pcity->tile = ptile;
sz_strlcpy(pcity->name, name);
pcity->size = 1;
+ memset(pcity->tile_output, 0, sizeof(pcity->tile_output));
specialist_type_iterate(sp) {
pcity->specialists[sp] = 0;
} specialist_type_iterate_end;
Index: common/city.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.h,v
retrieving revision 1.195
diff -u -r1.195 city.h
--- common/city.h 16 Jan 2005 11:11:01 -0000 1.195
+++ common/city.h 19 Jan 2005 04:44:22 -0000
@@ -212,6 +212,8 @@
/* the people */
int size;
+ unsigned char tile_output[CITY_MAP_SIZE][CITY_MAP_SIZE][O_MAX];
+
/* How the citizens feel:
ppl_*[0] is distribution before any of the modifiers below.
ppl_*[1] is distribution after luxury.
@@ -487,7 +489,7 @@
/* city update functions */
void generic_city_refresh(struct city *pcity,
- bool refresh_trade_route_cities,
+ bool full_refresh,
void (*send_unit_info) (struct player * pplayer,
struct unit * punit));
void adjust_city_free_cost(int *num_free, int *this_cost);
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.216
diff -u -r1.216 savegame.c
--- server/savegame.c 1 Jan 2005 22:01:57 -0000 1.216
+++ server/savegame.c 19 Jan 2005 04:44:23 -0000
@@ -3464,10 +3464,7 @@
* trade routes: the first refresh initializes all cities tile_trade
* values; the second correctly updates all trade routes. */
cities_iterate(pcity) {
- generic_city_refresh(pcity, FALSE, NULL);
- } cities_iterate_end;
- cities_iterate(pcity) {
- generic_city_refresh(pcity, FALSE, NULL);
+ generic_city_refresh(pcity, TRUE, NULL);
} cities_iterate_end;
/* Since the cities must be placed on the map to put them on the
|
|