1 /****************************************************************************
2 Freeciv - Copyright (C) 2004 - The Freeciv Team
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 ****************************************************************************/
15 #include <fc_config.h>
22 #include "log.h" /* fc_assert */
30 static struct ai_type ai_types
[FREECIV_AI_MOD_LAST
];
32 static int ai_type_count
= 0;
40 static struct ai_timer
*ai_timer_get(const struct ai_type
*ai
);
41 static struct ai_timer
*ai_timer_player_get(const struct player
*pplayer
);
43 static struct ai_timer
*aitimers
= NULL
;
44 static struct ai_timer
*aitimer_plrs
= NULL
;
46 /*****************************************************************************
47 Allocate memory for Start the timer for the AI of a player.
48 *****************************************************************************/
49 void ai_timer_init(void)
53 fc_assert_ret(aitimers
== NULL
);
54 fc_assert_ret(aitimer_plrs
== NULL
);
56 aitimers
= fc_calloc(FREECIV_AI_MOD_LAST
, sizeof(*aitimers
));
57 for (i
= 0; i
< FREECIV_AI_MOD_LAST
; i
++) {
58 struct ai_timer
*aitimer
= aitimers
+ i
;
60 aitimer
->timer
= NULL
;
63 aitimer_plrs
= fc_calloc(FREECIV_AI_MOD_LAST
* MAX_NUM_PLAYER_SLOTS
,
64 sizeof(*aitimer_plrs
));
65 for (i
= 0; i
< FREECIV_AI_MOD_LAST
* MAX_NUM_PLAYER_SLOTS
; i
++) {
66 struct ai_timer
*aitimer
= aitimer_plrs
+ i
;
68 aitimer
->timer
= NULL
;
72 /*****************************************************************************
73 Free resources allocated for the AI timers.
74 *****************************************************************************/
75 void ai_timer_free(void)
78 struct ai_timer
*aitimer
;
80 for (i
= 0; i
< FREECIV_AI_MOD_LAST
; i
++) {
81 struct ai_type
*ai
= get_ai_type(i
);
83 aitimer
= aitimers
+ i
;
86 log_normal("AI timer stats: [%15.3f] ---- (AI type: %s)",
87 timer_read_seconds(aitimer
->timer
), ai_name(ai
));
88 timer_destroy(aitimer
->timer
);
91 for (j
= 0; j
< MAX_NUM_PLAYER_SLOTS
; j
++) {
92 aitimer
= aitimer_plrs
+ j
* FREECIV_AI_MOD_LAST
+ i
;
95 log_normal("AI timer stats: [%15.3f] P%03d (AI type: %s)",
96 timer_read_seconds(aitimer
->timer
), j
, ai_name(ai
));
97 timer_destroy(aitimer
->timer
);
108 /*****************************************************************************
109 Get the timer for the AI.
110 *****************************************************************************/
111 static struct ai_timer
*ai_timer_get(const struct ai_type
*ai
)
113 struct ai_timer
*aitimer
;
115 fc_assert_ret_val(ai
!= NULL
, NULL
);
117 fc_assert_ret_val(aitimers
!= NULL
, NULL
);
119 aitimer
= aitimers
+ ai_type_number(ai
);
121 if (!aitimer
->timer
) {
122 aitimer
->timer
= timer_new(TIMER_CPU
, TIMER_DEBUG
);
128 /*****************************************************************************
129 Get the timer for the AI of a player.
130 *****************************************************************************/
131 static struct ai_timer
*ai_timer_player_get(const struct player
*pplayer
)
133 struct ai_timer
*aitimer
;
135 fc_assert_ret_val(pplayer
!= NULL
, NULL
);
136 fc_assert_ret_val(pplayer
->ai
!= NULL
, NULL
);
138 fc_assert_ret_val(aitimer_plrs
!= NULL
, NULL
);
140 aitimer
= aitimer_plrs
+ (player_index(pplayer
) * FREECIV_AI_MOD_LAST
141 + ai_type_number(pplayer
->ai
));
143 if (!aitimer
->timer
) {
144 aitimer
->timer
= timer_new(TIMER_CPU
, TIMER_DEBUG
);
150 /*****************************************************************************
151 Start the timer for the AI.
152 *****************************************************************************/
153 void ai_timer_start(const struct ai_type
*ai
)
155 struct ai_timer
*aitimer
= ai_timer_get(ai
);
157 fc_assert_ret(aitimer
!= NULL
);
158 fc_assert_ret(aitimer
->timer
!= NULL
);
160 if (aitimer
->count
== 0) {
161 log_debug("AI timer start [%15.3f] ---- (AI type: %s)",
162 timer_read_seconds(aitimer
->timer
), ai_name(ai
));
163 timer_start(aitimer
->timer
);
165 log_debug("AI timer =====> [depth: %3d] ---- (AI type: %s)",
166 aitimer
->count
, ai_name(ai
));
171 /*****************************************************************************
172 Stop the timer for the AI.
173 *****************************************************************************/
174 void ai_timer_stop(const struct ai_type
*ai
)
176 struct ai_timer
*aitimer
= ai_timer_get(ai
);
178 fc_assert_ret(aitimer
!= NULL
);
179 fc_assert_ret(aitimer
->timer
!= NULL
);
181 if (aitimer
->count
> 0) {
182 if (aitimer
->count
== 1) {
183 timer_stop(aitimer
->timer
);
184 log_debug("AI timer stop [%15.3f] ---- (AI type: %s)",
185 timer_read_seconds(aitimer
->timer
), ai_name(ai
));
187 log_debug("AI timer =====> [depth: %3d] ---- (AI type: %s)",
188 aitimer
->count
, ai_name(ai
));
192 log_debug("AI timer missing? ---- (AI type: %s)",
197 /*****************************************************************************
198 Start the timer for the AI of a player.
199 *****************************************************************************/
200 void ai_timer_player_start(const struct player
*pplayer
)
202 struct ai_timer
*aitimer
= ai_timer_player_get(pplayer
);
204 fc_assert_ret(aitimer
!= NULL
);
205 fc_assert_ret(aitimer
->timer
!= NULL
);
207 if (aitimer
->count
== 0) {
208 log_debug("AI timer start [%15.3f] P%03d (AI type: %s) %s",
209 timer_read_seconds(aitimer
->timer
), player_index(pplayer
),
210 ai_name(pplayer
->ai
), player_name(pplayer
));
211 timer_start(aitimer
->timer
);
213 log_debug("AI timer =====> [depth: %3d] P%03d (AI type: %s) %s",
214 aitimer
->count
, player_index(pplayer
), ai_name(pplayer
->ai
),
215 player_name(pplayer
));
220 /*****************************************************************************
221 Stop the timer for the AI of a player.
222 *****************************************************************************/
223 void ai_timer_player_stop(const struct player
*pplayer
)
225 struct ai_timer
*aitimer
= ai_timer_player_get(pplayer
);
227 fc_assert_ret(aitimer
!= NULL
);
228 fc_assert_ret(aitimer
->timer
!= NULL
);
230 if (aitimer
->count
> 0) {
231 if (aitimer
->count
== 1) {
232 timer_stop(aitimer
->timer
);
233 log_debug("AI timer stop [%15.3f] P%03d (AI type: %s) %s",
234 timer_read_seconds(aitimer
->timer
), player_index(pplayer
),
235 ai_name(pplayer
->ai
), player_name(pplayer
));
237 log_debug("AI timer =====> [depth: %3d] P%03d (AI type: %s) %s",
238 aitimer
->count
, player_index(pplayer
), ai_name(pplayer
->ai
),
239 player_name(pplayer
));
243 log_debug("AI timer missing? P%03d (AI type: %s) %s",
244 player_index(pplayer
), ai_name(pplayer
->ai
),
245 player_name(pplayer
));
248 #endif /* DEBUG_AITIMERS */
250 /***************************************************************
251 Returns ai_type of given id.
252 ***************************************************************/
253 struct ai_type
*get_ai_type(int id
)
255 fc_assert(id
>= 0 && id
< FREECIV_AI_MOD_LAST
);
257 return &ai_types
[id
];
260 /***************************************************************
261 Initializes AI structure.
262 ***************************************************************/
263 void init_ai(struct ai_type
*ai
)
265 memset(ai
, 0, sizeof(*ai
));
268 /***************************************************************
269 Returns id of the given ai_type.
270 ***************************************************************/
271 int ai_type_number(const struct ai_type
*ai
)
273 int ainbr
= ai
- ai_types
;
275 fc_assert_ret_val(ainbr
>= 0 && ainbr
< FREECIV_AI_MOD_LAST
, 0);
280 /***************************************************************
281 Find ai type with given name.
282 ***************************************************************/
283 struct ai_type
*ai_type_by_name(const char *search
)
285 ai_type_iterate(ai
) {
286 if (!fc_strcasecmp(ai_name(ai
), search
)) {
289 } ai_type_iterate_end
;
294 /***************************************************************
295 Return next free ai_type
296 ***************************************************************/
297 struct ai_type
*ai_type_alloc(void)
299 if (ai_type_count
>= FREECIV_AI_MOD_LAST
) {
300 log_error(_("Too many AI modules. Max is %d."),
301 FREECIV_AI_MOD_LAST
);
306 return get_ai_type(ai_type_count
++);
309 /***************************************************************
311 ***************************************************************/
312 void ai_type_dealloc(void)
317 /***************************************************************
318 Return number of ai types
319 ***************************************************************/
320 int ai_type_get_count(void)
322 return ai_type_count
;
325 /*****************************************************************************
326 Return the name of the ai type.
327 *****************************************************************************/
328 const char *ai_name(const struct ai_type
*ai
)
330 fc_assert_ret_val(ai
, NULL
);
334 /*****************************************************************************
335 Return usable ai type name, if possible. This is either the name
336 given as parameter or some fallback name for it. NULL is returned if
338 *****************************************************************************/
339 const char *ai_type_name_or_fallback(const char *orig_name
)
341 if (orig_name
== NULL
) {
345 if (ai_type_by_name(orig_name
) != NULL
) {
349 if (!strcmp("threaded", orig_name
)) {
352 fb
= ai_type_by_name("classic");
355 /* Get pointer to persistent name of the ai_type */