Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2004:
[Freeciv-Dev] Re: (PR#7279) Inline/Macro optimizations
Home

[Freeciv-Dev] Re: (PR#7279) Inline/Macro optimizations

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] Re: (PR#7279) Inline/Macro optimizations
From: "Arnstein Lindgard" <a-l@xxxxxxx>
Date: Sun, 25 Jan 2004 02:56:08 -0800
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=7279 >

This patch speeds up the server by 15.6% on a loaded autogame,
skipping the map generator phase. Overhead is eliminated for most
functions with more than 50 million calls, using 18 inlines and 10
macros.

Fortunately, everything in map.c could be inlined. This has clear
advantages in addition to comeliness, as new exciting topologies may
require frequent change of these functions, and we can easily add
local variables etc.

Assembly output of the Freeciv source confirms that gcc 3.3.2 inlines
all instances.

Moving stuff over from the .c file to the header file causes problems
for many functions that access global vars or stuff that is defined
in the .c file. Adding more includes to that header file causes
recursive problems with the overall include order of things.
Fortunately, the macro tool is available for this problem.

Some findings:

When a candidate function is declared static in the .c file, it's
tempting to just stuff "inline" there instead of moving to header.
For some functions this cause inlining, for others not. Using
-Winline does not report failure then. So it seems safest to follow
the recommendation and put them only in header files.

Only a few non-void functions with loops and stuff accessing misc
variables, were I not able to do something about.

One candidate's address (pointer) was used as callback, so neither
inline nor macro made much sense.


Arnstein

diff -ruN -Xdiff_ignore freeciv/common/aicore/path_finding.c 
inline/common/aicore/path_finding.c
--- freeciv/common/aicore/path_finding.c        Mon Jan 19 16:58:41 2004
+++ inline/common/aicore/path_finding.c Sun Jan 25 11:20:05 2004
@@ -38,6 +38,10 @@
 typedef short mapindex_t;
 typedef unsigned char utiny_t;
 
+/* Obtain cost-of-path from pure cost and extra cost. */
+#define get_total_CC(pf_map, cost, extra)                              \
+( PF_TURN_FACTOR * (cost) + (extra) * (pf_map)->params->move_rate )
+
 /* ===================== Internal structures ====================== */
 /*
  * Some comments on implementation: 
@@ -233,15 +237,6 @@
 }
 
 
-/*****************************************************************
-  Obtain cost-of-path from pure cost and extra cost
-*****************************************************************/
-static int get_total_CC(struct pf_map *pf_map, int cost, int extra)
-{
-  return PF_TURN_FACTOR * cost + extra * pf_map->params->move_rate;
-}
-
-
 /*****************************************************************
   Primary method for iterative path-finding.
   Plan: 1. Process previous position
diff -ruN -Xdiff_ignore freeciv/common/city.c inline/common/city.c
--- freeciv/common/city.c       Wed Jan 14 19:31:46 2004
+++ inline/common/city.c        Sun Jan 25 11:20:05 2004
@@ -75,31 +75,6 @@
 struct citystyle *city_styles = NULL;
 
 /**************************************************************************
-...
-**************************************************************************/
-bool is_valid_city_coords(const int city_x, const int city_y)
-{
-  if ((city_x == 0 || city_x == CITY_MAP_SIZE-1)
-      && (city_y == 0 || city_y == CITY_MAP_SIZE-1))
-    return FALSE;
-  if (city_x < 0 || city_y < 0
-      || city_x >= CITY_MAP_SIZE
-      || city_y >= CITY_MAP_SIZE)
-    return FALSE;
-
-  return TRUE;
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-bool is_city_center(int city_x, int city_y)
-{
-  return (city_x == (CITY_MAP_SIZE / 2))
-      && (city_y == (CITY_MAP_SIZE / 2));
-}
-
-/**************************************************************************
 Finds the city map coordinate for a given map position and a city
 center. Returns whether the map position is inside of the city map.
 **************************************************************************/
@@ -130,25 +105,6 @@
 Finds the map position for a given city map coordinate of a certain
 city. Returns true if the map position found is real.
 **************************************************************************/
-bool base_city_map_to_map(int *map_x, int *map_y,
-                        int city_center_x, int city_center_y,
-                        int city_map_x, int city_map_y)
-{
-  assert(is_valid_city_coords(city_map_x, city_map_y));
-  *map_x = city_center_x + city_map_x - CITY_MAP_SIZE / 2;
-  *map_y = city_center_y + city_map_y - CITY_MAP_SIZE / 2;
-
-  /* We check the border first to avoid doing an unnecessary
-   * normalization; this is just an optimization. */
-  return (!IS_BORDER_MAP_POS(city_center_x, city_center_y,
-                            CITY_MAP_SIZE / 2)
-         || normalize_map_pos(map_x, map_y));
-}
-
-/**************************************************************************
-Finds the map position for a given city map coordinate of a certain
-city. Returns true if the map position found is real.
-**************************************************************************/
 bool city_map_to_map(int *map_x, int *map_y,
                    const struct city *const pcity,
                    int city_map_x, int city_map_y)
@@ -183,16 +139,6 @@
 /**************************************************************************
 ...
 **************************************************************************/
-enum city_tile_type get_worker_city(struct city *pcity, int city_x, int city_y)
-{
-  if (!is_valid_city_coords(city_x, city_y)) 
-    return C_TILE_UNAVAILABLE;
-  return pcity->city_map[city_x][city_y];
-}
-
-/**************************************************************************
-...
-**************************************************************************/
 bool is_worker_here(struct city *pcity, int city_x, int city_y) 
 {
   if (!is_valid_city_coords(city_x, city_y)) {
@@ -308,14 +254,6 @@
 }
 
 /**************************************************************************
-...
-**************************************************************************/
-struct player *city_owner(struct city *pcity)
-{
-  return (&game.players[pcity->owner]);
-}
-
-/**************************************************************************
  Returns 1 if the given city is next to or on one of the given building's
  terr_gate (terrain) or spec_gate (specials), or if the building has no
  terrain/special requirements.
diff -ruN -Xdiff_ignore freeciv/common/city.h inline/common/city.h
--- freeciv/common/city.h       Wed Jan 14 19:31:46 2004
+++ inline/common/city.h        Sun Jan 25 11:20:05 2004
@@ -330,6 +330,14 @@
   } players_iterate_end;                                                    \
 }
 
+/***********************************************************************/
+
+static inline bool is_city_center(int city_x, int city_y);
+static inline bool is_valid_city_coords(const int city_x, const int city_y);
+static inline enum city_tile_type get_worker_city(struct city *pcity,
+                                                 int city_x, int city_y);
+
+/***********************************************************************/
 
 /* properties */
 
@@ -375,14 +383,9 @@
 
 /* city map functions */
 
-bool is_valid_city_coords(const int city_x, const int city_y);
-bool is_city_center(int city_x, int city_y);
 bool map_to_city_map(int *city_map_x, int *city_map_y,
                    const struct city *const pcity, int map_x, int map_y);
 
-bool base_city_map_to_map(int *map_x, int *map_y, int city_center_x,
-                        int city_center_y, int city_map_x,
-                        int city_map_y);
 bool city_map_to_map(int *map_x, int *map_y, const struct city *const pcity,
                    int city_map_x, int city_map_y);
 
@@ -401,8 +404,6 @@
 
 void set_worker_city(struct city *pcity, int city_x, int city_y,
                     enum city_tile_type type); 
-enum city_tile_type get_worker_city(struct city *pcity, int city_x,
-                                   int city_y);
 void get_worker_on_map_position(int map_x, int map_y,
                                enum city_tile_type *result_city_tile_type,
                                struct city **result_pcity);
@@ -494,4 +495,62 @@
 #define built_impr_iterate_end                                                \
   } impr_type_iterate_end;
 
+/*
+ * Finds the map position for a given city map coordinate of a certain
+ * city. Returns true if the map position found is real.
+ */
+#define base_city_map_to_map(map_x, map_y,                             \
+                            city_center_x, city_center_y,              \
+                            city_map_x, city_map_y)                    \
+( assert(is_valid_city_coords((city_map_x), (city_map_y))),            \
+  *(map_x) = (city_center_x) + (city_map_x) - CITY_MAP_SIZE / 2,       \
+  *(map_y) = (city_center_y) + (city_map_y) - CITY_MAP_SIZE / 2,       \
+  (!IS_BORDER_MAP_POS((city_center_x), (city_center_y),                        
\
+                      CITY_MAP_SIZE / 2)                               \
+   || normalize_map_pos((map_x), (map_y))) )
+
+#define city_owner(pcity)                                              \
+  (&game.players[(pcity)->owner])
+
+/*
+ *  Inline function definitions.
+ */
+
+/**************************************************************************
+...
+**************************************************************************/
+static inline bool is_city_center(int city_x, int city_y)
+{
+  return (city_x == (CITY_MAP_SIZE / 2))
+      && (city_y == (CITY_MAP_SIZE / 2));
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static inline bool is_valid_city_coords(const int city_x, const int city_y)
+{
+  if ((city_x == 0 || city_x == CITY_MAP_SIZE-1)
+      && (city_y == 0 || city_y == CITY_MAP_SIZE-1))
+    return FALSE;
+  if (city_x < 0 || city_y < 0
+      || city_x >= CITY_MAP_SIZE
+      || city_y >= CITY_MAP_SIZE)
+    return FALSE;
+
+  return TRUE;
+}
+
+/**************************************************************************
+...
+**************************************************************************/
+static inline enum city_tile_type get_worker_city(struct city *pcity,
+                                                 int city_x, int city_y)
+{
+  if (!is_valid_city_coords(city_x, city_y)) {
+    return C_TILE_UNAVAILABLE;
+  }
+  return pcity->city_map[city_x][city_y];
+}
+
 #endif  /* FC__CITY_H */
diff -ruN -Xdiff_ignore freeciv/common/government.c inline/common/government.c
--- freeciv/common/government.c Mon Jun 30 22:53:24 2003
+++ inline/common/government.c  Sun Jan 25 11:20:05 2004
@@ -145,36 +145,6 @@
 /***************************************************************
 ...
 ***************************************************************/
-struct government *get_government(int gov)
-{
-  assert(game.government_count > 0 && gov >= 0
-        && gov < game.government_count);
-  assert(governments[gov].index == gov);
-  return &governments[gov];
-}
-
-/***************************************************************
-...
-***************************************************************/
-struct government *get_gov_pplayer(struct player *pplayer)
-{
-  assert(pplayer != NULL);
-  return get_government(pplayer->government);
-}
-
-/***************************************************************
-...
-***************************************************************/
-struct government *get_gov_pcity(struct city *pcity)
-{
-  assert(pcity != NULL);
-  return get_gov_pplayer(city_owner(pcity));
-}
-
-
-/***************************************************************
-...
-***************************************************************/
 const char *get_ruler_title(int gov, bool male, int nation)
 {
   struct government *g = get_government(gov);
diff -ruN -Xdiff_ignore freeciv/common/government.h inline/common/government.h
--- freeciv/common/government.h Mon Jun 30 22:53:24 2003
+++ inline/common/government.h  Sun Jan 25 11:20:05 2004
@@ -173,10 +173,6 @@
 /* like game.rtech lists, A_LAST terminated (for .tech)
    and techs before that are guaranteed to exist */
 
-struct government *get_government(int gov);
-struct government *get_gov_pplayer(struct player *pplayer);
-struct government *get_gov_pcity(struct city *pcity);
-
 struct government *find_government_by_name(const char *name);
 
 enum government_flag_id government_flag_from_str(const char *s);
@@ -211,4 +207,19 @@
   }                                                                         \
 }
 
+#define get_government(gov)                                    \
+( assert(game.government_count > 0 && (gov) >= 0               \
+        && (gov) < game.government_count),                     \
+  assert(governments[(gov)].index == (gov)),                   \
+  &governments[(gov)] )
+
+#define get_gov_pplayer(pplayer)                               \
+( assert((pplayer) != NULL),                                   \
+  get_government((pplayer)->government) )
+
+#define get_gov_pcity(pcity)                                   \
+( assert((pcity) != NULL),                                     \
+  get_gov_pplayer(city_owner((pcity))) )
+
+
 #endif  /* FC__GOVERNMENT_H */
diff -ruN -Xdiff_ignore freeciv/common/improvement.c inline/common/improvement.c
--- freeciv/common/improvement.c        Fri Nov 14 09:28:44 2003
+++ inline/common/improvement.c Sun Jan 25 11:20:05 2004
@@ -118,27 +118,6 @@
 }
 
 /**************************************************************************
-Returns 1 if the improvement_type "exists" in this game, 0 otherwise.
-An improvement_type doesn't exist if one of:
-- id is out of range;
-- the improvement_type has been flagged as removed by setting its
-  tech_req to A_LAST;
-- it is a space part, and the spacerace is not enabled.
-Arguably this should be called improvement_type_exists, but that's too long.
-**************************************************************************/
-bool improvement_exists(Impr_Type_id id)
-{
-  if (id<0 || id>=B_LAST || id>=game.num_impr_types)
-    return FALSE;
-
-  if ((id==B_SCOMP || id==B_SMODULE || id==B_SSTRUCTURAL)
-      && !game.spacerace)
-    return FALSE;
-
-  return (improvement_types[id].tech_req!=A_LAST);
-}
-
-/**************************************************************************
 ...
 **************************************************************************/
 struct impr_type *get_improvement_type(Impr_Type_id id)
diff -ruN -Xdiff_ignore freeciv/common/improvement.h inline/common/improvement.h
--- freeciv/common/improvement.h        Sun Aug 10 15:46:14 2003
+++ inline/common/improvement.h Sun Jan 25 11:20:05 2004
@@ -133,7 +133,6 @@
 /* improvement functions */
 void improvements_free(void);
 struct impr_type *get_improvement_type(Impr_Type_id id);
-bool improvement_exists(Impr_Type_id id);
 int improvement_value(Impr_Type_id id);
 bool is_wonder(Impr_Type_id id);
 const char *get_improvement_name(Impr_Type_id id);
@@ -172,4 +171,24 @@
   }                                                                           \
 }
 
+/*
+ *  Yields TRUE if the improvement_type "exists" in this game, FALSE
+ *  otherwise. An improvement_type doesn't exist if one of:
+ *  - id is out of range;
+ *  - the improvement_type has been flagged as removed by setting its
+ *    tech_req to A_LAST;
+ *  - it is a space part, and the spacerace is not enabled.
+ *  Arguably this should be called improvement_type_exists, but that's too
+ *  long.
+ */
+#define improvement_exists(Impr_Type_id)                               \
+( ( ((Impr_Type_id) < 0 || (Impr_Type_id) >= B_LAST ||                 \
+     (Impr_Type_id) >= game.num_impr_types) ||                         \
+   (((Impr_Type_id) == B_SCOMP || (Impr_Type_id) == B_SMODULE ||       \
+     (Impr_Type_id) == B_SSTRUCTURAL)                                  \
+      && !game.spacerace) )                                            \
+  ? FALSE                                                              \
+  : (improvement_types[(Impr_Type_id)].tech_req != A_LAST) )
+
+
 #endif  /* FC__IMPROVEMENT_H */
diff -ruN -Xdiff_ignore freeciv/common/map.c inline/common/map.c
--- freeciv/common/map.c        Sun Jan 25 11:18:53 2004
+++ inline/common/map.c Sun Jan 25 11:20:05 2004
@@ -66,7 +66,6 @@
   N_("Fallout")
 };
 
-#define MAP_TILE(x,y)  (map.tiles + map_pos_to_index(x, y))
 
 /****************************************************************************
   Return a bitfield of the specials on the tile that are infrastructure.
@@ -316,18 +315,6 @@
 /***************************************************************
 ...
 ***************************************************************/
-int real_map_distance(int x0, int y0, int x1, int y1)
-{
-  int dx, dy;
-
-  map_distance_vector(&dx, &dy, x0, y0, x1, y1);
-
-  return MAX(abs(dx), abs(dy));
-}
-
-/***************************************************************
-...
-***************************************************************/
 int sq_map_distance(int x0, int y0, int x1, int y1)
 {
   /* We assume map_distance_vector gives us the vector with the
@@ -1075,30 +1062,6 @@
 /***************************************************************
 ...
 ***************************************************************/
-bool is_tiles_adjacent(int x0, int y0, int x1, int y1)
-{
-  return real_map_distance(x0, y0, x1, y1) == 1;
-}
-
-/***************************************************************
-...
-***************************************************************/
-struct tile *map_get_tile(int x, int y)
-{
-  return MAP_TILE(x, y);
-}
-
-/***************************************************************
-...
-***************************************************************/
-unsigned short map_get_continent(int x, int y)
-{
-  return MAP_TILE(x, y)->continent;
-}
-
-/***************************************************************
-...
-***************************************************************/
 void map_set_continent(int x, int y, int val)
 {
   MAP_TILE(x, y)->continent = val;
@@ -1107,14 +1070,6 @@
 /***************************************************************
 ...
 ***************************************************************/
-enum tile_terrain_type map_get_terrain(int x, int y)
-{
-  return MAP_TILE(x, y)->terrain;
-}
-
-/***************************************************************
-...
-***************************************************************/
 enum tile_special_type map_get_special(int x, int y)
 {
   return MAP_TILE(x, y)->special;
@@ -1130,33 +1085,6 @@
 }
 
 /***************************************************************
- Returns TRUE iff the given tile has the given special.
-***************************************************************/
-bool tile_has_special(struct tile *ptile, enum tile_special_type special)
-{
-  return contains_special(ptile->special, special);
-}
-  
-/***************************************************************
- Returns TRUE iff the given special is found in the given set.
-***************************************************************/
-bool contains_special(enum tile_special_type set,
-                     enum tile_special_type to_test_for)
-{
-  enum tile_special_type masked = set & to_test_for;
-
-  assert(0 == (int) S_NO_SPECIAL);
-
-  /*
-   * contains_special should only be called with one S_* in
-   * to_test_for.
-   */
-  assert(masked == S_NO_SPECIAL || masked == to_test_for);
-
-  return masked == to_test_for;
-}
-
-/***************************************************************
 ...
 ***************************************************************/
 void map_set_terrain(int x, int y, enum tile_terrain_type ter)
@@ -1199,84 +1127,17 @@
 /***************************************************************
 ...
 ***************************************************************/
-struct city *map_get_city(int x, int y)
-{
-  return MAP_TILE(x, y)->city;
-}
-
-/***************************************************************
-...
-***************************************************************/
 void map_set_city(int x, int y, struct city *pcity)
 {
   MAP_TILE(x, y)->city = pcity;
 }
 
-/***************************************************************
-  Are (x1,y1) and (x2,y2) really the same when adjusted?
-  This function might be necessary ALOT of places...
-***************************************************************/
-bool same_pos(int x1, int y1, int x2, int y2)
-{
-  CHECK_MAP_POS(x1, y1);
-  CHECK_MAP_POS(x2, y2);
-  return (x1 == x2 && y1 == y2);
-}
-
 bool is_real_map_pos(int x, int y)
 {
   return normalize_map_pos(&x, &y);
 }
 
 /**************************************************************************
-Returns TRUE iff the map position is normal. "Normal" here means that
-it is both a real/valid coordinate set and that the coordinates are in
-their canonical/proper form. In plain English: the coordinates must be
-on the map.
-**************************************************************************/
-bool is_normal_map_pos(int x, int y)
-{
-  int x1 = x, y1 = y;
-
-  return (normalize_map_pos(&x1, &y1) && (x1 == x) && (y1 == y));
-}
-
-/**************************************************************************
-  If the position is real, it will be normalized and TRUE will be returned.
-  If the position is unreal, it will be left unchanged and FALSE will be
-  returned.
-
-  Note, we need to leave x and y with sane values even in the unreal case.
-  Some callers may for instance call nearest_real_pos on these values.
-**************************************************************************/
-bool normalize_map_pos(int *x, int *y)
-{
-  int nat_x, nat_y;
-
-  /* Normalization is best done in native coordinatees. */
-  map_to_native_pos(&nat_x, &nat_y, *x, *y);
-
-  /* If the position is out of range in a non-wrapping direction, it is
-   * unreal. */
-  if (!((topo_has_flag(TF_WRAPX) || (nat_x >= 0 && nat_x < map.xsize))
-       && (topo_has_flag(TF_WRAPY) || (nat_y >= 0 && nat_y < map.ysize)))) {
-    return FALSE;
-  }
-
-  /* Wrap in X and Y directions, as needed. */
-  if (topo_has_flag(TF_WRAPX)) {
-    nat_x = FC_WRAP(nat_x, map.xsize);
-  }
-  if (topo_has_flag(TF_WRAPY)) {
-    nat_y = FC_WRAP(nat_y, map.ysize);
-  }
-
-  /* Now transform things back to map coordinates. */
-  native_to_map_pos(x, y, nat_x, nat_y);
-  return TRUE;
-}
-
-/**************************************************************************
 Twiddle *x and *y to point the the nearest real tile, and ensure that the
 position is normalized.
 **************************************************************************/
@@ -1306,54 +1167,6 @@
   return map.xsize * map.ysize;
 }
 
-/****************************************************************************
-  Topology function to find the vector which has the minimum "real"
-  distance between the map positions (x0, y0) and (x1, y1).  If there is
-  more than one vector with equal distance, no guarantee is made about
-  which is found.
-
-  Real distance is defined as the larger of the distances in the x and y
-  direction; since units can travel diagonally this is the "real" distance
-  a unit has to travel to get from point to point.
-
-  (See also: real_map_distance, map_distance, and sq_map_distance.)
-
-  With the standard topology the ranges of the return value are:
-    -map.xsize/2 <= dx <= map.xsize/2
-    -map.ysize   <  dy <  map.ysize
-****************************************************************************/
-void map_distance_vector(int *dx, int *dy, int x0, int y0, int x1, int y1)
-{
-  if (topo_has_flag(TF_WRAPX) || topo_has_flag(TF_WRAPY)) {
-    /* Wrapping is done in native coordinates. */
-    map_to_native_pos(&x0, &y0, x0, y0);
-    map_to_native_pos(&x1, &y1, x1, y1);
-
-    /* Find the "native" distance vector. This corresponds closely to the
-     * map distance vector but is easier to wrap. */
-    *dx = x1 - x0;
-    *dy = y1 - y0;
-    if (topo_has_flag(TF_WRAPX)) {
-      /* Wrap dx to be in [-map.xsize/2, map.xsize/2). */
-      *dx = FC_WRAP(*dx + map.xsize / 2, map.xsize) - map.xsize / 2;
-    }
-    if (topo_has_flag(TF_WRAPY)) {
-      /* Wrap dy to be in [-map.ysize/2, map.ysize/2). */
-      *dy = FC_WRAP(*dy + map.ysize / 2, map.ysize) - map.ysize / 2;
-    }
-
-    /* Convert the native delta vector back to a pair of map positions. */
-    x1 = x0 + *dx;
-    y1 = y0 + *dy;
-    native_to_map_pos(&x0, &y0, x0, y0);
-    native_to_map_pos(&x1, &y1, x1, y1);
-  }
-
-  /* Find the final (map) vector. */
-  *dx = x1 - x0;
-  *dy = y1 - y0;
-}
-
 /**************************************************************************
 Random neighbouring square.
 **************************************************************************/
diff -ruN -Xdiff_ignore freeciv/common/map.h inline/common/map.h
--- freeciv/common/map.h        Sun Jan 25 11:18:53 2004
+++ inline/common/map.h Sun Jan 25 11:20:05 2004
@@ -163,6 +163,29 @@
 
 #define topo_has_flag(flag) ((CURRENT_TOPOLOGY & (flag)) != 0)
 
+#define MAP_TILE(x, y)         (map.tiles + map_pos_to_index((x), (y)))
+
+/***********************************************************************/
+
+static inline int map_pos_to_index(int map_x, int map_y);
+static inline bool normalize_map_pos(int *x, int *y);
+static inline bool is_normal_map_pos(int x, int y);
+static inline struct tile *map_get_tile(int x, int y);
+static inline enum tile_terrain_type map_get_terrain(int x, int y);
+static inline unsigned short map_get_continent(int x, int y);
+static inline struct city *map_get_city(int x, int y);
+static inline bool tile_has_special(struct tile *ptile,
+                                   enum tile_special_type to_test_for);
+static inline bool contains_special(enum tile_special_type all,
+                                   enum tile_special_type to_test_for);
+static inline void map_distance_vector(int *dx, int *dy, int x0,
+                                      int y0, int x1, int y1);
+static inline bool is_tiles_adjacent(int x0, int y0, int x1, int y1);
+static inline int real_map_distance(int x0, int y0, int x1, int y1);
+static inline bool same_pos(int x1, int y1, int x2, int y2);
+
+/***********************************************************************/
+
 bool map_is_empty(void);
 void map_init(void);
 void map_allocate(void);
@@ -170,12 +193,9 @@
 
 const char *map_get_tile_info_text(int x, int y);
 const char *map_get_tile_fpt_text(int x, int y);
-struct tile *map_get_tile(int x, int y);
 
 int map_distance(int x0, int y0, int x1, int y1);
-int real_map_distance(int x0, int y0, int x1, int y1);
 int sq_map_distance(int x0, int y0, int x1, int y1);
-bool same_pos(int x1, int y1, int x2, int y2);
 bool base_get_direction_for_step(int start_x, int start_y, int end_x,
                                int end_y, int *dir);
 int get_direction_for_step(int start_x, int start_y, int end_x, int end_y);
@@ -216,8 +236,6 @@
       *(pnat_x) = (2 * (map_x) - *(pnat_y) - (*(pnat_y) & 1)) / 2)          \
    : (*(pnat_x) = (map_x), *(pnat_y) = (map_y)))
 
-static inline int map_pos_to_index(int map_x, int map_y);
-
 /* index_to_map_pos(int *, int *, int) inverts map_pos_to_index */
 #define index_to_map_pos(pmap_x, pmap_y, index) \
   (CHECK_INDEX(index),                          \
@@ -244,26 +262,19 @@
 
 struct player *map_get_owner(int x, int y);
 void map_set_owner(int x, int y, struct player *pplayer);
-struct city *map_get_city(int x, int y);
 void map_set_city(int x, int y, struct city *pcity);
-enum tile_terrain_type map_get_terrain(int x, int y);
 enum tile_special_type map_get_special(int x, int y);
 void map_set_terrain(int x, int y, enum tile_terrain_type ter);
 void map_set_special(int x, int y, enum tile_special_type spe);
 void map_clear_special(int x, int y, enum tile_special_type spe);
 void map_clear_all_specials(int x, int y);
 bool is_real_map_pos(int x, int y);
-bool is_normal_map_pos(int x, int y);
 
 /* implemented in server/maphand.c and client/climisc.c */
 enum known_type map_get_known(int x, int y, struct player *pplayer);
 
 /* special testing */
 bool map_has_special(int x, int y, enum tile_special_type to_test_for);
-bool tile_has_special(struct tile *ptile,
-                     enum tile_special_type to_test_for);
-bool contains_special(enum tile_special_type all,
-                     enum tile_special_type to_test_for);
 
 /*
  * A "border position" is any one that _may have_ positions within
@@ -277,16 +288,13 @@
    || (x) < (dist) || (x) >= map.xsize - (dist)               \
    || (y) < (dist) || (y) >= map.ysize - (dist))
 
-bool normalize_map_pos(int *x, int *y);
 void nearest_real_pos(int *x, int *y);
-void map_distance_vector(int *dx, int *dy, int x0, int y0, int x1, int y1);
 int map_num_tiles(void);
 
 void rand_neighbour(int x0, int y0, int *x, int *y);
 void rand_map_pos(int *x, int *y);
 
 bool is_water_adjacent_to_tile(int x, int y);
-bool is_tiles_adjacent(int x0, int y0, int x1, int y1);
 bool is_move_cardinal(int start_x, int start_y, int end_x, int end_y);
 int map_move_cost(struct unit *punit, int x, int y);
 enum tile_special_type get_special_by_name(const char * name);
@@ -675,4 +683,192 @@
   return native_pos_to_index(nat_x, nat_y);
 }
 
+/**************************************************************************
+  If the position is real, it will be normalized and TRUE will be returned.
+  If the position is unreal, it will be left unchanged and FALSE will be
+  returned.
+
+  Note, we need to leave x and y with sane values even in the unreal case.
+  Some callers may for instance call nearest_real_pos on these values.
+**************************************************************************/
+static inline bool normalize_map_pos(int *x, int *y)
+{
+  int nat_x, nat_y;
+
+  /* Normalization is best done in native coordinatees. */
+  map_to_native_pos(&nat_x, &nat_y, *x, *y);
+
+  /* If the position is out of range in a non-wrapping direction, it is
+   * unreal. */
+  if (!((topo_has_flag(TF_WRAPX) || (nat_x >= 0 && nat_x < map.xsize))
+       && (topo_has_flag(TF_WRAPY) || (nat_y >= 0 && nat_y < map.ysize)))) {
+    return FALSE;
+  }
+
+  /* Wrap in X and Y directions, as needed. */
+  if (topo_has_flag(TF_WRAPX)) {
+    nat_x = FC_WRAP(nat_x, map.xsize);
+  }
+  if (topo_has_flag(TF_WRAPY)) {
+    nat_y = FC_WRAP(nat_y, map.ysize);
+  }
+
+  /* Now transform things back to map coordinates. */
+  native_to_map_pos(x, y, nat_x, nat_y);
+  return TRUE;
+}
+
+/**************************************************************************
+Returns TRUE iff the map position is normal. "Normal" here means that
+it is both a real/valid coordinate set and that the coordinates are in
+their canonical/proper form. In plain English: the coordinates must be
+on the map. Inlining this function is effective only in DEBUG mode.
+**************************************************************************/
+static inline bool is_normal_map_pos(int x, int y)
+{
+  int x1 = x, y1 = y;
+
+  return (normalize_map_pos(&x1, &y1) && (x1 == x) && (y1 == y));
+}
+
+/***************************************************************
+ Coordinates to tile pointer conversion.
+***************************************************************/
+static inline struct tile *map_get_tile(int x, int y)
+{
+  return MAP_TILE(x, y);
+}
+
+/***************************************************************
+...
+***************************************************************/
+static inline enum tile_terrain_type map_get_terrain(int x, int y)
+{
+  return MAP_TILE(x, y)->terrain;
+}
+
+/***************************************************************
+...
+***************************************************************/
+static inline unsigned short map_get_continent(int x, int y)
+{
+  return MAP_TILE(x, y)->continent;
+}
+
+/***************************************************************
+...
+***************************************************************/
+static inline struct city *map_get_city(int x, int y)
+{
+  return MAP_TILE(x, y)->city;
+}
+
+/***************************************************************
+ Returns TRUE if the given tile has the given special.
+***************************************************************/
+static inline bool tile_has_special(struct tile *ptile,
+                                   enum tile_special_type special)
+{
+  return contains_special(ptile->special, special);
+}
+
+/***************************************************************
+ Returns TRUE if the given special is found in the given set.
+***************************************************************/
+static inline bool contains_special(enum tile_special_type set,
+                                   enum tile_special_type to_test_for)
+{
+  enum tile_special_type masked = set & to_test_for;
+
+  assert(0 == (int) S_NO_SPECIAL);
+
+  /*
+   * contains_special should only be called with one S_* in
+   * to_test_for.
+   */
+  assert(masked == S_NO_SPECIAL || masked == to_test_for);
+
+  return masked == to_test_for;
+}
+
+/****************************************************************************
+  Topology function to find the vector which has the minimum "real"
+  distance between the map positions (x0, y0) and (x1, y1).  If there is
+  more than one vector with equal distance, no guarantee is made about
+  which is found.
+
+  Real distance is defined as the larger of the distances in the x and y
+  direction; since units can travel diagonally this is the "real" distance
+  a unit has to travel to get from point to point.
+
+  (See also: real_map_distance, map_distance, and sq_map_distance.)
+
+  With the standard topology the ranges of the return value are:
+    -map.xsize/2 <= dx <= map.xsize/2
+    -map.ysize   <  dy <  map.ysize
+****************************************************************************/
+static inline void map_distance_vector(int *dx, int *dy, int x0,
+                                      int y0, int x1, int y1)
+{
+  if (topo_has_flag(TF_WRAPX) || topo_has_flag(TF_WRAPY)) {
+    /* Wrapping is done in native coordinates. */
+    map_to_native_pos(&x0, &y0, x0, y0);
+    map_to_native_pos(&x1, &y1, x1, y1);
+
+    /* Find the "native" distance vector. This corresponds closely to the
+     * map distance vector but is easier to wrap. */
+    *dx = x1 - x0;
+    *dy = y1 - y0;
+    if (topo_has_flag(TF_WRAPX)) {
+      /* Wrap dx to be in [-map.xsize/2, map.xsize/2). */
+      *dx = FC_WRAP(*dx + map.xsize / 2, map.xsize) - map.xsize / 2;
+    }
+    if (topo_has_flag(TF_WRAPY)) {
+      /* Wrap dy to be in [-map.ysize/2, map.ysize/2). */
+      *dy = FC_WRAP(*dy + map.ysize / 2, map.ysize) - map.ysize / 2;
+    }
+
+    /* Convert the native delta vector back to a pair of map positions. */
+    x1 = x0 + *dx;
+    y1 = y0 + *dy;
+    native_to_map_pos(&x0, &y0, x0, y0);
+    native_to_map_pos(&x1, &y1, x1, y1);
+  }
+
+  /* Find the final (map) vector. */
+  *dx = x1 - x0;
+  *dy = y1 - y0;
+}
+
+/***************************************************************
+...
+***************************************************************/
+static inline bool is_tiles_adjacent(int x0, int y0, int x1, int y1)
+{
+  return real_map_distance(x0, y0, x1, y1) == 1;
+}
+
+/***************************************************************
+...
+***************************************************************/
+static inline int real_map_distance(int x0, int y0, int x1, int y1)
+{
+  int dx, dy;
+
+  map_distance_vector(&dx, &dy, x0, y0, x1, y1);
+
+  return MAX(abs(dx), abs(dy));
+}
+
+/***************************************************************
+  Are (x1,y1) and (x2,y2) really the same when adjusted?
+  This function might be necessary ALOT of places...
+***************************************************************/
+static inline bool same_pos(int x1, int y1, int x2, int y2)
+{
+  CHECK_MAP_POS(x1, y1);
+  CHECK_MAP_POS(x2, y2);
+  return (x1 == x2 && y1 == y2);
+}
+
 #endif  /* FC__MAP_H */
diff -ruN -Xdiff_ignore freeciv/common/terrain.c inline/common/terrain.c
--- freeciv/common/terrain.c    Sun Jan 25 11:18:53 2004
+++ inline/common/terrain.c     Sun Jan 25 11:20:05 2004
@@ -25,14 +25,6 @@
 /***************************************************************
 ...
 ***************************************************************/
-struct tile_type *get_tile_type(enum tile_terrain_type type)
-{
-  return &tile_types[type];
-}
-
-/***************************************************************
-...
-***************************************************************/
 enum tile_terrain_type get_terrain_by_name(const char * name)
 {
   enum tile_terrain_type tt;
diff -ruN -Xdiff_ignore freeciv/common/terrain.h inline/common/terrain.h
--- freeciv/common/terrain.h    Sun Jan 25 11:18:53 2004
+++ inline/common/terrain.h     Sun Jan 25 11:20:05 2004
@@ -91,7 +91,6 @@
 extern struct tile_type tile_types[T_LAST];
 
 /* General accessor functions. */
-struct tile_type *get_tile_type(enum tile_terrain_type type);
 enum tile_terrain_type get_terrain_by_name(const char * name);
 const char *get_terrain_name(enum tile_terrain_type type);
 enum terrain_flag_id terrain_flag_from_str(const char *s);
@@ -124,4 +123,7 @@
   }                                                                         \
 }
 
+#define get_tile_type(type)                                            \
+  (&tile_types[(type)])
+
 #endif  /* FC__TERRAIN_H */
diff -ruN -Xdiff_ignore freeciv/common/unittype.c inline/common/unittype.c
--- freeciv/common/unittype.c   Sun Jan 11 18:57:51 2004
+++ inline/common/unittype.c    Sun Jan 25 11:20:05 2004
@@ -82,23 +82,6 @@
 /**************************************************************************
 ...
 **************************************************************************/
-struct unit_type *get_unit_type(Unit_Type_id id)
-{
-  assert(id >= 0 && id < U_LAST && id < game.num_unit_types);
-  return &unit_types[id];
-}
-
-/**************************************************************************
-...
-**************************************************************************/
-struct unit_type *unit_type(struct unit *punit)
-{
-  return get_unit_type(punit->type);
-}
-
-/**************************************************************************
-...
-**************************************************************************/
 bool is_ground_unittype(Unit_Type_id id)
 {
   return (unit_types[id].move_type == LAND_MOVING);
@@ -165,15 +148,6 @@
 }
 
 /**************************************************************************
-...
-**************************************************************************/
-bool unit_type_flag(Unit_Type_id id, int flag)
-{
-  assert(flag>=0 && flag<F_LAST);
-  return BV_ISSET(unit_types[id].flags, flag);
-}
-
-/**************************************************************************
 ...
 **************************************************************************/
 bool unit_flag(struct unit *punit, enum unit_flag_id flag)
diff -ruN -Xdiff_ignore freeciv/common/unittype.h inline/common/unittype.h
--- freeciv/common/unittype.h   Sun Jan 11 18:57:51 2004
+++ inline/common/unittype.h    Sun Jan 25 11:20:05 2004
@@ -13,6 +13,7 @@
 #ifndef FC__UNITTYPE_H
 #define FC__UNITTYPE_H
 
+#include <assert.h>
 #include "shared.h"
 
 struct player;
@@ -214,11 +215,14 @@
 
 extern struct unit_type unit_types[U_LAST];
 
+/**************************************************************************/
+
+static inline bool unit_type_flag(Unit_Type_id id, int flag);
+
+/**************************************************************************/
+
 bool unit_type_exists(Unit_Type_id id);
-struct unit_type *get_unit_type(Unit_Type_id id);
-struct unit_type *unit_type(struct unit *punit);
 
-bool unit_type_flag(Unit_Type_id id, int flag);
 bool unit_flag(struct unit *punit, enum unit_flag_id flag);
 bool unit_has_role(Unit_Type_id id, int role);
 
@@ -273,4 +277,21 @@
   }                                                                           \
 }
 
+#define get_unit_type(Unit_Type_id)                            \
+( assert((Unit_Type_id) >= 0 && (Unit_Type_id) < U_LAST &&     \
+         (Unit_Type_id) < game.num_unit_types),                        \
+  &unit_types[(Unit_Type_id)] )
+
+#define unit_type(punit)                       \
+  get_unit_type((punit)->type)
+
+/**************************************************************************
+...
+**************************************************************************/
+static inline bool unit_type_flag(Unit_Type_id id, int flag)
+{
+  assert(flag>=0 && flag<F_LAST);
+  return BV_ISSET(unit_types[id].flags, flag);
+}
+
 #endif  /* FC__UNITTYPE_H */
diff -ruN -Xdiff_ignore freeciv/server/maphand.c inline/server/maphand.c
--- freeciv/server/maphand.c    Fri Nov 28 21:56:47 2003
+++ inline/server/maphand.c     Sun Jan 25 11:20:05 2004
@@ -788,14 +788,6 @@
 /***************************************************************
 ...
 ***************************************************************/
-bool map_is_known(int x, int y, struct player *pplayer)
-{
-  return TEST_BIT(map_get_tile(x, y)->known, pplayer->player_no);
-}
-
-/***************************************************************
-...
-***************************************************************/
 bool map_is_known_and_seen(int x, int y, struct player *pplayer)
 {
   int offset = map_pos_to_index(x, y);
diff -ruN -Xdiff_ignore freeciv/server/maphand.h inline/server/maphand.h
--- freeciv/server/maphand.h    Fri Nov 28 21:56:47 2003
+++ inline/server/maphand.h     Sun Jan 25 11:20:05 2004
@@ -49,6 +49,12 @@
   short last_updated;
 };
 
+/***********************************************************************/
+
+static inline bool map_is_known(int x, int y, struct player *pplayer);
+
+/***********************************************************************/
+
 void global_warming(int effect);
 void nuclear_winter(int effect);
 void give_map_from_player_to_player(struct player *pfrom, struct player 
*pdest);
@@ -71,7 +77,6 @@
 
 bool map_is_known_and_seen(int x, int y, struct player *pplayer);
 void map_change_seen(int x, int y, struct player *pplayer, int change);
-bool map_is_known(int x, int y, struct player *pplayer);
 void map_set_known(int x, int y, struct player *pplayer);
 void map_clear_known(int x, int y, struct player *pplayer);
 void map_know_all(struct player *pplayer);
@@ -98,4 +103,17 @@
 
 enum ocean_land_change check_terrain_ocean_land_change(int x, int y,
                                               enum tile_terrain_type oldter);
+
+/*
+ *  Inline function definitions.
+ */
+
+/***************************************************************
+...
+***************************************************************/
+static inline bool map_is_known(int x, int y, struct player *pplayer)
+{
+  return TEST_BIT(map_get_tile(x, y)->known, pplayer->player_no);
+}
+
 #endif  /* FC__MAPHAND_H */


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