1 /***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 /***********************************************************************
15 idex = ident index: a lookup table for quick mapping of unit and city
16 id values to unit and city pointers.
18 Method: use separate hash tables for each type.
19 Means code duplication for city/unit cases, but simplicity advantages.
20 Don't have to manage memory at all: store pointers to unit and city
21 structs allocated elsewhere, and keys are pointers to id values inside
24 Note id values should probably be unsigned int: here leave as plain int
25 so can use pointers to pcity->id etc.
26 ***********************************************************************/
29 #include <fc_config.h>
42 /* struct city_hash. */
43 #define SPECHASH_TAG city
44 #define SPECHASH_INT_KEY_TYPE
45 #define SPECHASH_IDATA_TYPE struct city *
48 /* struct unit_hash. */
49 #define SPECHASH_TAG unit
50 #define SPECHASH_INT_KEY_TYPE
51 #define SPECHASH_IDATA_TYPE struct unit *
56 static struct city_hash
*idex_city_hash
= NULL
;
57 static struct unit_hash
*idex_unit_hash
= NULL
;
59 /**************************************************************************
60 Initialize. Should call this at the start before use.
61 ***************************************************************************/
64 fc_assert_ret(idex_city_hash
== NULL
);
65 fc_assert_ret(idex_unit_hash
== NULL
);
67 idex_city_hash
= city_hash_new();
68 idex_unit_hash
= unit_hash_new();
71 /**************************************************************************
73 ***************************************************************************/
76 city_hash_destroy(idex_city_hash
);
77 idex_city_hash
= NULL
;
79 unit_hash_destroy(idex_unit_hash
);
80 idex_unit_hash
= NULL
;
83 /**************************************************************************
84 Register a city into idex, with current pcity->id.
85 Call this when pcity created.
86 ***************************************************************************/
87 void idex_register_city(struct city
*pcity
)
91 city_hash_replace_full(idex_city_hash
, pcity
->id
, pcity
, NULL
, &old
);
92 fc_assert_ret_msg(NULL
== old
,
93 "IDEX: city collision: new %d %p %s, old %d %p %s",
94 pcity
->id
, (void *) pcity
, city_name_get(pcity
),
95 old
->id
, (void *) old
, city_name_get(old
));
98 /**************************************************************************
99 Register a unit into idex, with current punit->id.
100 Call this when punit created.
101 ***************************************************************************/
102 void idex_register_unit(struct unit
*punit
)
106 unit_hash_replace_full(idex_unit_hash
, punit
->id
, punit
, NULL
, &old
);
107 fc_assert_ret_msg(NULL
== old
,
108 "IDEX: unit collision: new %d %p %s, old %d %p %s",
109 punit
->id
, (void *) punit
, unit_rule_name(punit
),
110 old
->id
, (void *) old
, unit_rule_name(old
));
113 /**************************************************************************
114 Remove a city from idex, with current pcity->id.
115 Call this when pcity deleted.
116 ***************************************************************************/
117 void idex_unregister_city(struct city
*pcity
)
121 city_hash_remove_full(idex_city_hash
, pcity
->id
, NULL
, &old
);
122 fc_assert_ret_msg(NULL
!= old
,
123 "IDEX: city unreg missing: %d %p %s",
124 pcity
->id
, (void *) pcity
, city_name_get(pcity
));
125 fc_assert_ret_msg(old
== pcity
, "IDEX: city unreg mismatch: "
126 "unreg %d %p %s, old %d %p %s",
127 pcity
->id
, (void *) pcity
, city_name_get(pcity
),
128 old
->id
, (void *) old
, city_name_get(old
));
131 /**************************************************************************
132 Remove a unit from idex, with current punit->id.
133 Call this when punit deleted.
134 ***************************************************************************/
135 void idex_unregister_unit(struct unit
*punit
)
139 unit_hash_remove_full(idex_unit_hash
, punit
->id
, NULL
, &old
);
140 fc_assert_ret_msg(NULL
!= old
,
141 "IDEX: unit unreg missing: %d %p %s",
142 punit
->id
, (void *) punit
, unit_rule_name(punit
));
143 fc_assert_ret_msg(old
== punit
, "IDEX: unit unreg mismatch: "
144 "unreg %d %p %s, old %d %p %s",
145 punit
->id
, (void *) punit
, unit_rule_name(punit
),
146 old
->id
, (void*) old
, unit_rule_name(old
));
149 /**************************************************************************
150 Lookup city with given id.
151 Returns NULL if the city is not registered (which is not an error).
152 ***************************************************************************/
153 struct city
*idex_lookup_city(int id
)
157 city_hash_lookup(idex_city_hash
, id
, &pcity
);
161 /**************************************************************************
162 Lookup unit with given id.
163 Returns NULL if the unit is not registered (which is not an error).
164 ***************************************************************************/
165 struct unit
*idex_lookup_unit(int id
)
169 unit_hash_lookup(idex_unit_hash
, id
, &punit
);