From 3eb208193d3466aab916ba246448e8b9105c95d6 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 1 Oct 2022 18:37:42 +0300 Subject: [PATCH 41/41] Drop 'threaded' AI module Based on 'unfixable' report by andrewmcg See osdn #42268 Signed-off-by: Marko Lindqvist --- ai/Makefile.am | 7 - ai/threaded/.gitignore | 3 - ai/threaded/Makefile.am | 33 -- ai/threaded/taicity.c | 503 ------------------------------ ai/threaded/taicity.h | 23 -- ai/threaded/taimsg.c | 74 ----- ai/threaded/taimsg.h | 62 ---- ai/threaded/taiplayer.c | 298 ------------------ ai/threaded/taiplayer.h | 67 ---- ai/threaded/threadedai.c | 644 --------------------------------------- configure.ac | 14 +- doc/README.AI_modules | 6 +- doc/README.packaging | 1 + 13 files changed, 5 insertions(+), 1730 deletions(-) delete mode 100644 ai/threaded/.gitignore delete mode 100644 ai/threaded/Makefile.am delete mode 100644 ai/threaded/taicity.c delete mode 100644 ai/threaded/taicity.h delete mode 100644 ai/threaded/taimsg.c delete mode 100644 ai/threaded/taimsg.h delete mode 100644 ai/threaded/taiplayer.c delete mode 100644 ai/threaded/taiplayer.h delete mode 100644 ai/threaded/threadedai.c diff --git a/ai/Makefile.am b/ai/Makefile.am index 2e56eee1e6..5cf801ba5f 100644 --- a/ai/Makefile.am +++ b/ai/Makefile.am @@ -10,10 +10,6 @@ if AI_MOD_STATIC_CLASSIC module_dirs += classic endif -if AI_MOD_STATIC_THREADED -module_dirs += threaded -endif - if AI_MOD_STATIC_TEX module_dirs += tex endif @@ -32,9 +28,6 @@ if !AI_MOD_STATIC_CLASSIC module_dirs += classic endif if EXP_AI_MODULES -if !AI_MOD_STATIC_THREADED -module_dirs += threaded -endif if !AI_MOD_STATIC_TEX module_dirs += tex endif diff --git a/ai/threaded/.gitignore b/ai/threaded/.gitignore deleted file mode 100644 index dc1ebd209a..0000000000 --- a/ai/threaded/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/Makefile -/Makefile.in -/.deps diff --git a/ai/threaded/Makefile.am b/ai/threaded/Makefile.am deleted file mode 100644 index 245dc641c6..0000000000 --- a/ai/threaded/Makefile.am +++ /dev/null @@ -1,33 +0,0 @@ -## Process this file with automake to produce Makefile.in - -if AI_MOD_STATIC_THREADED -noinst_LTLIBRARIES = libthreadedai.la -else -aimodule_LTLIBRARIES = fc_ai_threaded.la -endif - -AM_CPPFLAGS = \ - -I$(top_srcdir)/utility \ - -I$(top_srcdir)/common \ - -I$(top_srcdir)/common/aicore \ - -I$(top_srcdir)/common/networking \ - -I$(top_srcdir)/server/ \ - -I$(top_srcdir)/server/advisors \ - -I$(top_srcdir)/ai/default \ - -I$(top_srcdir)/dependencies/tinycthread - -da_sources = \ - taicity.c \ - taicity.h \ - taimsg.c \ - taimsg.h \ - taiplayer.c \ - taiplayer.h \ - threadedai.c - -if AI_MOD_STATIC_THREADED -libthreadedai_la_SOURCES = $(da_sources) -else -fc_ai_threaded_la_SOURCES = $(da_sources) -fc_ai_threaded_la_LDFLAGS = -module -endif diff --git a/ai/threaded/taicity.c b/ai/threaded/taicity.c deleted file mode 100644 index 6042710e89..0000000000 --- a/ai/threaded/taicity.c +++ /dev/null @@ -1,503 +0,0 @@ -/*********************************************************************** - Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* utility */ -#include "log.h" - -/* common */ -#include "city.h" -#include "game.h" -#include "map.h" -#include "movement.h" -#include "tile.h" -#include "unit.h" -#include "workertask.h" - -/* server */ -#include "citytools.h" - -/* server/advisors */ -#include "autosettlers.h" -#include "infracache.h" - -/* ai/threaded */ -#include "taimsg.h" - -#include "taicity.h" - -/* Task Want Multiplier */ -#define TWMP 100 - -struct tai_worker_task_req -{ - int city_id; - struct worker_task task; -}; - -enum tai_worker_task_limitation { - TWTL_CURRENT_UNITS, - TWTL_BUILDABLE_UNITS -}; - -static bool tai_city_worker_task_select(struct ai_type *ait, - struct player *pplayer, struct city *pcity, - struct worker_task *task, - enum tai_worker_task_limitation limit); - -/**********************************************************************//** - Create worker request for the city. Only tasks that existing units can - do are created. -**************************************************************************/ -void tai_city_worker_requests_create(struct ai_type *ait, - struct player *pplayer, struct city *pcity) -{ - struct worker_task task; - - if (tai_city_worker_task_select(ait, pplayer, pcity, &task, TWTL_CURRENT_UNITS)) { - struct tai_worker_task_req *data = fc_malloc(sizeof(*data)); - - data->city_id = pcity->id; - data->task.ptile = task.ptile; - data->task.act = task.act; - data->task.tgt = task.tgt; - data->task.want = task.want; - - tai_send_req(TAI_REQ_WORKER_TASK, pplayer, data); - } -} - -struct tai_tile_state -{ - int uw_max_base; /* Value for the city working the tile */ - int uw_max; /* With road connectivity bonus */ - int worst_worked; - int orig_worst_worked; - int old_worst_worked; - int *wants; -}; - -static int dummy_wants[U_LAST]; - -/**********************************************************************//** - Select worker task suitable for the tile. -**************************************************************************/ -static void tai_tile_worker_task_select(struct player *pplayer, - struct city *pcity, struct tile *ptile, - int cindex, struct unit_list *units, - struct worker_task *worked, - struct worker_task *unworked, - struct tai_tile_state *state, - enum tai_worker_task_limitation limit) -{ - int orig_value; - bool potential_worst_worked = FALSE; - - if (!city_can_work_tile(pcity, ptile)) { - return; - } - - orig_value = city_tile_value(pcity, ptile, 0, 0); - - if (tile_worked(ptile) == pcity - && orig_value < state->worst_worked) { - state->worst_worked = orig_value; - state->orig_worst_worked = orig_value; - potential_worst_worked = TRUE; - } - - as_transform_action_iterate(act) { - bool consider = TRUE; - bool possible = FALSE; - struct extra_type *tgt = NULL; - enum extra_cause cause; - enum extra_rmcause rmcause; - - /* Do not request activities that already are under way. */ - unit_list_iterate(ptile->units, punit) { - if (unit_owner(punit) == pplayer - && unit_has_type_flag(punit, UTYF_SETTLERS) - && punit->activity == action_id_get_activity(act)) { - consider = FALSE; - break; - } - } unit_list_iterate_end; - - if (!consider) { - continue; - } - - cause = activity_to_extra_cause(action_id_get_activity(act)); - rmcause = activity_to_extra_rmcause(action_id_get_activity(act)); - - unit_list_iterate(units, punit) { - if (cause != EC_NONE) { - tgt = next_extra_for_tile(ptile, cause, pplayer, punit); - } else if (rmcause != ERM_NONE) { - tgt = prev_extra_in_tile(ptile, rmcause, pplayer, punit); - } - - if (action_prob_possible( - action_speculate_unit_on_tile(act, - punit, unit_home(punit), ptile, - TRUE, - ptile, tgt))) { - possible = TRUE; - break; - } - } unit_list_iterate_end; - - if (possible) { - int value = adv_city_worker_act_get(pcity, cindex, - action_id_get_activity(act)); - - if (tile_worked(ptile) == pcity) { - if ((value - orig_value) * TWMP > worked->want) { - worked->want = TWMP * (value - orig_value); - worked->ptile = ptile; - worked->act = action_id_get_activity(act); - worked->tgt = NULL; - worked->tgt = NULL; - if (limit == TWTL_BUILDABLE_UNITS) { - unit_list_iterate(units, punit) { - if (action_prob_possible( - action_speculate_unit_on_tile(act, - punit, unit_home(punit), - ptile, - TRUE, - ptile, tgt))) { - state->wants[utype_index(unit_type_get(punit))] += worked->want; - } - } unit_list_iterate_end; - } - } - if (value > state->old_worst_worked) { - /* After improvement it would not be the worst */ - potential_worst_worked = FALSE; - } else { - state->worst_worked = value; - } - } else { - if (value > orig_value && value > state->uw_max) { - state->uw_max = value; - state->uw_max_base = value; - unworked->want = TWMP * (value - orig_value); - unworked->ptile = ptile; - unworked->act = action_id_get_activity(act); - unworked->tgt = NULL; - if (limit == TWTL_BUILDABLE_UNITS) { - unit_list_iterate(units, punit) { - if (action_prob_possible( - action_speculate_unit_on_tile(act, - punit, unit_home(punit), - ptile, - TRUE, - ptile, tgt))) { - state->wants[utype_index(unit_type_get(punit))] += unworked->want; - } - } unit_list_iterate_end; - } - } - } - } - } as_transform_action_iterate_end; - - extra_type_iterate(tgt) { - struct action *paction = NULL; - bool removing = tile_has_extra(ptile, tgt); - - unit_list_iterate(units, punit) { - if (removing) { - as_rmextra_action_iterate(try_act) { - struct action *taction = action_by_number(try_act); - if (is_extra_removed_by_action(tgt, taction) - && action_prob_possible( - action_speculate_unit_on_tile(try_act, - punit, - unit_home(punit), ptile, - TRUE, - ptile, tgt))) { - paction = taction; - break; - } - } as_rmextra_action_iterate_end; - } else { - as_extra_action_iterate(try_act) { - struct action *taction = action_by_number(try_act); - if (is_extra_caused_by_action(tgt, taction) - && action_prob_possible( - action_speculate_unit_on_tile(try_act, - punit, - unit_home(punit), ptile, - TRUE, - ptile, tgt))) { - paction = taction; - break; - } - } as_extra_action_iterate_end; - } - } unit_list_iterate_end; - - if (paction != NULL) { - adv_want base_value; - int value; - adv_want extra; - bool consider = TRUE; - struct road_type *proad; - - /* Do not request activities that already are under way. */ - unit_list_iterate(ptile->units, punit) { - if (unit_owner(punit) == pplayer - && unit_has_type_flag(punit, UTYF_SETTLERS) - && punit->activity == action_get_activity(paction)) { - consider = FALSE; - break; - } - } unit_list_iterate_end; - - if (!consider) { - continue; - } - - proad = extra_road_get(tgt); - - if (removing) { - base_value = adv_city_worker_rmextra_get(pcity, cindex, tgt); - } else { - base_value = adv_city_worker_extra_get(pcity, cindex, tgt); - } - - if (proad != NULL && road_provides_move_bonus(proad)) { - int old_move_cost; - int mc_multiplier = 1; - int mc_divisor = 1; - - /* Here 'old' means actually 'without the evaluated': In case of - * removal activity it's the value after the removal. */ - old_move_cost = tile_terrain(ptile)->movement_cost * SINGLE_MOVE; - - extra_type_by_cause_iterate(EC_ROAD, poe) { - struct road_type *pold = extra_road_get(poe); - - if (tile_has_extra(ptile, poe) && poe != tgt) { - if (road_provides_move_bonus(pold) - && pold->move_cost < old_move_cost) { - old_move_cost = pold->move_cost; - } - } - } extra_type_by_cause_iterate_end; - - if (proad->move_cost < old_move_cost) { - if (proad->move_cost >= terrain_control.move_fragments) { - mc_divisor = proad->move_cost / terrain_control.move_fragments; - } else { - if (proad->move_cost == 0) { - mc_multiplier = 2; - } else { - mc_multiplier = 1 - proad->move_cost; - } - mc_multiplier += old_move_cost; - } - } - - extra = adv_settlers_road_bonus(ptile, proad) * mc_multiplier / mc_divisor; - - if (removing) { - extra = -extra; - } - } else { - extra = 0; - } - - value = base_value + extra; - - if (tile_worked(ptile) == pcity) { - if ((value - orig_value) * TWMP > worked->want) { - worked->want = TWMP * (value - orig_value); - worked->ptile = ptile; - worked->act = action_get_activity(paction); - worked->tgt = tgt; - if (limit == TWTL_BUILDABLE_UNITS) { - unit_list_iterate(units, punit) { - fc_assert_action(action_get_target_kind(paction) == ATK_TILE, - break); - if (action_prob_possible(action_speculate_unit_on_tile( - paction->id, - punit, unit_home(punit), ptile, - TRUE, - ptile, tgt))) { - state->wants[utype_index(unit_type_get(punit))] += worked->want; - } - } unit_list_iterate_end; - } - } - if (value > state->old_worst_worked) { - /* After improvement it would not be the worst */ - potential_worst_worked = FALSE; - } else { - state->worst_worked = value; - } - } else { - if (value > orig_value && value > state->uw_max) { - state->uw_max = value; - state->uw_max_base = base_value; - unworked->want = TWMP * (value - orig_value); - unworked->ptile = ptile; - unworked->act = action_get_activity(paction); - unworked->tgt = tgt; - if (limit == TWTL_BUILDABLE_UNITS) { - unit_list_iterate(units, punit) { - fc_assert_action(action_get_target_kind(paction) == ATK_TILE, - break); - if (action_prob_possible(action_speculate_unit_on_tile( - paction->id, - punit, unit_home(punit), ptile, - TRUE, - ptile, tgt))) { - state->wants[utype_index(unit_type_get(punit))] += unworked->want; - } - } unit_list_iterate_end; - } - } - } - } - } extra_type_iterate_end; - - if (potential_worst_worked) { - /* Would still be worst worked even if we improved *it*. */ - state->old_worst_worked = state->worst_worked; - } -} - -/**********************************************************************//** - Select worker task suitable for the city. -**************************************************************************/ -static bool tai_city_worker_task_select(struct ai_type *ait, - struct player *pplayer, struct city *pcity, - struct worker_task *task, - enum tai_worker_task_limitation limit) -{ - struct worker_task *selected; - struct worker_task worked = { .ptile = NULL, .want = 0, .act = ACTIVITY_IDLE, .tgt = NULL }; - struct worker_task unworked = { .ptile = NULL, .want = 0, .act = ACTIVITY_IDLE, .tgt = NULL }; - struct tai_tile_state state = { .uw_max = 0, .uw_max_base = 0, .worst_worked = FC_INFINITY, - .orig_worst_worked = 0, .old_worst_worked = FC_INFINITY }; - struct unit_list *units = NULL; - - switch (limit) { - case TWTL_CURRENT_UNITS: - units = pplayer->units; - state.wants = NULL; - break; - case TWTL_BUILDABLE_UNITS: - units = unit_list_new(); - unit_type_iterate(ptype) { - if (can_city_build_unit_now(pcity, ptype)) { - unit_list_append(units, unit_virtual_create(pplayer, pcity, ptype, 0)); - } - } unit_type_iterate_end; - state.wants = dummy_wants; - break; - } - - city_tile_iterate_index(city_map_radius_sq_get(pcity), city_tile(pcity), - ptile, cindex) { - tai_tile_worker_task_select(pplayer, pcity, ptile, cindex, units, &worked, &unworked, - &state, limit); - } city_tile_iterate_end; - - if (worked.ptile == NULL - || (state.old_worst_worked < state.uw_max - && (state.uw_max - state.orig_worst_worked) * TWMP > worked.want) - || (state.uw_max - state.uw_max_base * TWMP > worked.want)) { - /* It's better to improve best yet unworked tile and take it to use after that, - than to improve already worked tile. OR it's more important to - improve road connectivity outside worked tiles than improve worked tiles */ - selected = &unworked; - } else { - selected = &worked; - } - - if (limit == TWTL_BUILDABLE_UNITS) { - unit_list_iterate(units, punit) { - unit_virtual_destroy(punit); - } unit_list_iterate_end; - unit_list_destroy(units); - } - - if (selected->ptile != NULL) { - struct extra_type *target = NULL; - - if (selected->tgt == NULL) { - enum extra_cause cause = activity_to_extra_cause(selected->act); - - if (cause != EC_NONE) { - target = next_extra_for_tile(selected->ptile, cause, pplayer, NULL); - } else { - enum extra_rmcause rmcause = activity_to_extra_rmcause(selected->act); - - if (rmcause != ERM_NONE) { - target = prev_extra_in_tile(selected->ptile, rmcause, pplayer, NULL); - } - } - } else { - target = selected->tgt; - } - - task->ptile = selected->ptile; - task->act = selected->act; - task->tgt = target; - task->want = selected->want; - - return TRUE; - } - - return FALSE; -} - -/**********************************************************************//** - Receive message from thread to main thread. -**************************************************************************/ -void tai_req_worker_task_rcv(struct tai_req *req) -{ - struct tai_worker_task_req *data = (struct tai_worker_task_req *)req->data; - struct city *pcity; - - pcity = game_city_by_number(data->city_id); - - if (pcity != NULL && city_owner(pcity) == req->plr) { - /* City has not been lost meanwhile */ - struct worker_task *ptask = worker_task_list_get(pcity->task_reqs, 0); - - if (ptask == NULL) { - ptask = fc_malloc(sizeof(struct worker_task)); - worker_task_init(ptask); - worker_task_list_append(pcity->task_reqs, ptask); - } - - log_debug("%s storing req for act %d at (%d,%d)", - pcity->name, data->task.act, TILE_XY(data->task.ptile)); - ptask->ptile = data->task.ptile; - ptask->act = data->task.act; - ptask->tgt = data->task.tgt; - ptask->want = data->task.want; - - /* Send info to observers */ - package_and_send_worker_tasks(pcity); - } - - free(data); -} diff --git a/ai/threaded/taicity.h b/ai/threaded/taicity.h deleted file mode 100644 index 0df29ec853..0000000000 --- a/ai/threaded/taicity.h +++ /dev/null @@ -1,23 +0,0 @@ -/*********************************************************************** - Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -***********************************************************************/ -#ifndef FC__TAICITY_H -#define FC__TAICITY_H - -struct city; -struct tai_req; - -void tai_city_worker_requests_create(struct ai_type *ait, - struct player *pplayer, struct city *pcity); -void tai_req_worker_task_rcv(struct tai_req *req); - -#endif /* FC__TAICITY_H */ diff --git a/ai/threaded/taimsg.c b/ai/threaded/taimsg.c deleted file mode 100644 index 202e208188..0000000000 --- a/ai/threaded/taimsg.c +++ /dev/null @@ -1,74 +0,0 @@ -/*********************************************************************** - Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* ai/threaded */ -#include "taiplayer.h" - -#include "taimsg.h" - -/**********************************************************************//** - Construct and send message to player thread. -**************************************************************************/ -void tai_send_msg(enum taimsgtype type, struct player *pplayer, - void *data) -{ - struct tai_msg *msg; - - if (!tai_thread_running()) { - /* No player thread to send messages to */ - return; - } - - msg = fc_malloc(sizeof(*msg)); - - msg->type = type; - msg->plr = pplayer; - msg->data = data; - - tai_msg_to_thr(msg); -} - -/**********************************************************************//** - Construct and send request from player thread. -**************************************************************************/ -void tai_send_req(enum taireqtype type, struct player *pplayer, - void *data) -{ - struct tai_req *req = fc_malloc(sizeof(*req)); - - req->type = type; - req->plr = pplayer; - req->data = data; - - tai_req_from_thr(req); -} - -/**********************************************************************//** - Time for phase first activities -**************************************************************************/ -void tai_first_activities(struct ai_type *ait, struct player *pplayer) -{ - tai_send_msg(TAI_MSG_FIRST_ACTIVITIES, pplayer, NULL); -} - -/**********************************************************************//** - Player phase has finished -**************************************************************************/ -void tai_phase_finished(struct ai_type *ait, struct player *pplayer) -{ - tai_send_msg(TAI_MSG_PHASE_FINISHED, pplayer, NULL); -} diff --git a/ai/threaded/taimsg.h b/ai/threaded/taimsg.h deleted file mode 100644 index 86c57c1853..0000000000 --- a/ai/threaded/taimsg.h +++ /dev/null @@ -1,62 +0,0 @@ -/*********************************************************************** - Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -***********************************************************************/ -#ifndef FC__TAIMSG_H -#define FC__TAIMSG_H - -#define SPECENUM_NAME taimsgtype -#define SPECENUM_VALUE0 TAI_MSG_THR_EXIT -#define SPECENUM_VALUE0NAME "Exit" -#define SPECENUM_VALUE1 TAI_MSG_FIRST_ACTIVITIES -#define SPECENUM_VALUE1NAME "FirstActivities" -#define SPECENUM_VALUE2 TAI_MSG_PHASE_FINISHED -#define SPECENUM_VALUE2NAME "PhaseFinished" -#include "specenum_gen.h" - -#define SPECENUM_NAME taireqtype -#define SPECENUM_VALUE0 TAI_REQ_WORKER_TASK -#define SPECENUM_VALUE0NAME "WorkerTask" -#define SPECENUM_VALUE1 TAI_REQ_TURN_DONE -#define SPECENUM_VALUE1NAME "TurnDone" -#include "specenum_gen.h" - -struct tai_msg -{ - enum taimsgtype type; - struct player *plr; - void *data; -}; - -struct tai_req -{ - enum taireqtype type; - struct player *plr; - void *data; -}; - -#define SPECLIST_TAG taimsg -#define SPECLIST_TYPE struct tai_msg -#include "speclist.h" - -#define SPECLIST_TAG taireq -#define SPECLIST_TYPE struct tai_req -#include "speclist.h" - -void tai_send_msg(enum taimsgtype type, struct player *pplayer, - void *data); -void tai_send_req(enum taireqtype type, struct player *pplayer, - void *data); - -void tai_first_activities(struct ai_type *ait, struct player *pplayer); -void tai_phase_finished(struct ai_type *ait, struct player *pplayer); - -#endif /* FC__TAIMSG_H */ diff --git a/ai/threaded/taiplayer.c b/ai/threaded/taiplayer.c deleted file mode 100644 index 9a650e7dd2..0000000000 --- a/ai/threaded/taiplayer.c +++ /dev/null @@ -1,298 +0,0 @@ -/*********************************************************************** - Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* utility */ -#include "log.h" - -/* common */ -#include "ai.h" -#include "city.h" -#include "game.h" -#include "unit.h" - -/* server/advisors */ -#include "infracache.h" - -/* ai/default */ -#include "daiplayer.h" - -/* ai/threaded */ -#include "taicity.h" - -#include "taiplayer.h" - -/* What level of operation we should abort because - * of received messages. Lower is more critical; - * TAI_ABORT_EXIT means that whole thread should exit, - * TAI_ABORT_NONE means that we can continue what we were doing */ -enum tai_abort_msg_class -{ - TAI_ABORT_EXIT, - TAI_ABORT_PHASE_END, - TAI_ABORT_NONE -}; - -static enum tai_abort_msg_class tai_check_messages(struct ai_type *ait); - -struct tai_thr -{ - int num_players; - struct tai_msgs msgs_to; - struct tai_reqs reqs_from; - bool thread_running; - fc_thread ait; -} thrai; - -/**********************************************************************//** - Initialize ai thread. -**************************************************************************/ -void tai_init_threading(void) -{ - thrai.thread_running = FALSE; - - thrai.num_players = 0; -} - -/**********************************************************************//** - This is main function of ai thread. -**************************************************************************/ -static void tai_thread_start(void *arg) -{ - bool finished = FALSE; - struct ai_type *ait = arg; - - log_debug("New AI thread launched"); - - /* Just wait until we are signaled to shutdown */ - fc_allocate_mutex(&thrai.msgs_to.mutex); - while (!finished) { - fc_thread_cond_wait(&thrai.msgs_to.thr_cond, &thrai.msgs_to.mutex); - - if (tai_check_messages(ait) <= TAI_ABORT_EXIT) { - finished = TRUE; - } - } - fc_release_mutex(&thrai.msgs_to.mutex); - - log_debug("AI thread exiting"); -} - -/**********************************************************************//** - Handle messages from message queue. -**************************************************************************/ -static enum tai_abort_msg_class tai_check_messages(struct ai_type *ait) -{ - enum tai_abort_msg_class ret_abort = TAI_ABORT_NONE; - - taimsg_list_allocate_mutex(thrai.msgs_to.msglist); - while (taimsg_list_size(thrai.msgs_to.msglist) > 0) { - struct tai_msg *msg; - enum tai_abort_msg_class new_abort = TAI_ABORT_NONE; - - msg = taimsg_list_get(thrai.msgs_to.msglist, 0); - taimsg_list_remove(thrai.msgs_to.msglist, msg); - taimsg_list_release_mutex(thrai.msgs_to.msglist); - - log_debug("Plr thr got %s", taimsgtype_name(msg->type)); - - switch (msg->type) { - case TAI_MSG_FIRST_ACTIVITIES: - fc_allocate_mutex(&game.server.mutexes.city_list); - - initialize_infrastructure_cache(msg->plr); - - /* Use _safe iterate in case the main thread - * destroyes cities while we are iterating through these. */ - city_list_iterate_safe(msg->plr->cities, pcity) { - tai_city_worker_requests_create(ait, msg->plr, pcity); - - /* Release mutex for a second in case main thread - * wants to do something to city list. */ - fc_release_mutex(&game.server.mutexes.city_list); - - /* Recursive message check in case phase is finished. */ - new_abort = tai_check_messages(ait); - fc_allocate_mutex(&game.server.mutexes.city_list); - if (new_abort < TAI_ABORT_NONE) { - break; - } - } city_list_iterate_safe_end; - fc_release_mutex(&game.server.mutexes.city_list); - - tai_send_req(TAI_REQ_TURN_DONE, msg->plr, NULL); - - break; - case TAI_MSG_PHASE_FINISHED: - new_abort = TAI_ABORT_PHASE_END; - break; - case TAI_MSG_THR_EXIT: - new_abort = TAI_ABORT_EXIT; - break; - default: - log_error("Illegal message type %s (%d) for threaded ai!", - taimsgtype_name(msg->type), msg->type); - break; - } - - if (new_abort < ret_abort) { - ret_abort = new_abort; - } - - FC_FREE(msg); - - taimsg_list_allocate_mutex(thrai.msgs_to.msglist); - } - taimsg_list_release_mutex(thrai.msgs_to.msglist); - - return ret_abort; -} - -/**********************************************************************//** - Initialize player for use with threaded AI. -**************************************************************************/ -void tai_player_alloc(struct ai_type *ait, struct player *pplayer) -{ - struct tai_plr *player_data = fc_calloc(1, sizeof(struct tai_plr)); - - player_set_ai_data(pplayer, ait, player_data); - - /* Default AI */ - dai_data_init(ait, pplayer); -} - -/**********************************************************************//** - Free player from use with threaded AI. -**************************************************************************/ -void tai_player_free(struct ai_type *ait, struct player *pplayer) -{ - struct tai_plr *player_data = player_ai_data(pplayer, ait); - - /* Default AI */ - dai_data_close(ait, pplayer); - - if (player_data != NULL) { - player_set_ai_data(pplayer, ait, NULL); - FC_FREE(player_data); - } -} - -/**********************************************************************//** - We actually control the player -**************************************************************************/ -void tai_control_gained(struct ai_type *ait, struct player *pplayer) -{ - thrai.num_players++; - - log_debug("%s now under threaded AI (%d)", pplayer->name, thrai.num_players); - - if (!thrai.thread_running) { - thrai.msgs_to.msglist = taimsg_list_new(); - thrai.reqs_from.reqlist = taireq_list_new(); - - thrai.thread_running = TRUE; - - fc_thread_cond_init(&thrai.msgs_to.thr_cond); - fc_init_mutex(&thrai.msgs_to.mutex); - fc_thread_start(&thrai.ait, tai_thread_start, ait); - } -} - -/**********************************************************************//** - We no longer control the player -**************************************************************************/ -void tai_control_lost(struct ai_type *ait, struct player *pplayer) -{ - thrai.num_players--; - - log_debug("%s no longer under threaded AI (%d)", pplayer->name, thrai.num_players); - - if (thrai.num_players <= 0) { - tai_send_msg(TAI_MSG_THR_EXIT, pplayer, NULL); - - fc_thread_wait(&thrai.ait); - thrai.thread_running = FALSE; - - fc_thread_cond_destroy(&thrai.msgs_to.thr_cond); - fc_destroy_mutex(&thrai.msgs_to.mutex); - taimsg_list_destroy(thrai.msgs_to.msglist); - taireq_list_destroy(thrai.reqs_from.reqlist); - } -} - -/**********************************************************************//** - Check for messages sent by player thread -**************************************************************************/ -void tai_refresh(struct ai_type *ait, struct player *pplayer) -{ - if (thrai.thread_running) { - taireq_list_allocate_mutex(thrai.reqs_from.reqlist); - while (taireq_list_size(thrai.reqs_from.reqlist) > 0) { - struct tai_req *req; - - req = taireq_list_get(thrai.reqs_from.reqlist, 0); - taireq_list_remove(thrai.reqs_from.reqlist, req); - - taireq_list_release_mutex(thrai.reqs_from.reqlist); - - log_debug("Plr thr sent %s", taireqtype_name(req->type)); - - switch (req->type) { - case TAI_REQ_WORKER_TASK: - tai_req_worker_task_rcv(req); - break; - case TAI_REQ_TURN_DONE: - req->plr->ai_phase_done = TRUE; - break; - } - - FC_FREE(req); - - taireq_list_allocate_mutex(thrai.reqs_from.reqlist); - } - taireq_list_release_mutex(thrai.reqs_from.reqlist); - } -} - -/**********************************************************************//** - Send message to thread. Be sure that thread is running so that messages - are not just piling up to the list without anybody reading them. -**************************************************************************/ -void tai_msg_to_thr(struct tai_msg *msg) -{ - fc_allocate_mutex(&thrai.msgs_to.mutex); - taimsg_list_append(thrai.msgs_to.msglist, msg); - fc_thread_cond_signal(&thrai.msgs_to.thr_cond); - fc_release_mutex(&thrai.msgs_to.mutex); -} - -/**********************************************************************//** - Thread sends message. -**************************************************************************/ -void tai_req_from_thr(struct tai_req *req) -{ - taireq_list_allocate_mutex(thrai.reqs_from.reqlist); - taireq_list_append(thrai.reqs_from.reqlist, req); - taireq_list_release_mutex(thrai.reqs_from.reqlist); -} - -/**********************************************************************//** - Return whether player thread is running -**************************************************************************/ -bool tai_thread_running(void) -{ - return thrai.thread_running; -} diff --git a/ai/threaded/taiplayer.h b/ai/threaded/taiplayer.h deleted file mode 100644 index cf77bf6455..0000000000 --- a/ai/threaded/taiplayer.h +++ /dev/null @@ -1,67 +0,0 @@ -/*********************************************************************** - Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -***********************************************************************/ -#ifndef FC__TAIPLAYER_H -#define FC__TAIPLAYER_H - -/* utility */ -#include "fcthread.h" - -/* common */ -#include "player.h" - -/* ai/default */ -#include "daidata.h" - -/* ai/threaded */ -#include "taimsg.h" - -struct player; - -struct tai_msgs -{ - fc_thread_cond thr_cond; - fc_mutex mutex; - struct taimsg_list *msglist; -}; - -struct tai_reqs -{ - struct taireq_list *reqlist; -}; - -struct tai_plr -{ - struct ai_plr defai; /* Keep this first so default ai finds it */ -}; - -void tai_init_threading(void); - -bool tai_thread_running(void); - -void tai_player_alloc(struct ai_type *ait, struct player *pplayer); -void tai_player_free(struct ai_type *ait, struct player *pplayer); -void tai_control_gained(struct ai_type *ait, struct player *pplayer); -void tai_control_lost(struct ai_type *ait, struct player *pplayer); -void tai_refresh(struct ai_type *ait, struct player *pplayer); - -void tai_msg_to_thr(struct tai_msg *msg); - -void tai_req_from_thr(struct tai_req *req); - -static inline struct tai_plr *tai_player_data(struct ai_type *ait, - const struct player *pplayer) -{ - return (struct tai_plr *)player_ai_data(pplayer, ait); -} - -#endif /* FC__TAIPLAYER_H */ diff --git a/ai/threaded/threadedai.c b/ai/threaded/threadedai.c deleted file mode 100644 index 12de5536c9..0000000000 --- a/ai/threaded/threadedai.c +++ /dev/null @@ -1,644 +0,0 @@ -/*********************************************************************** - Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -/* common */ -#include "ai.h" - -/* ai/default */ -#include "aiferry.h" -#include "aihand.h" -#include "aitools.h" -#include "daicity.h" -#include "daidiplomacy.h" -#include "daidomestic.h" -#include "dailog.h" -#include "daimilitary.h" -#include "daiplayer.h" -#include "daisettler.h" - -/* threaded ai */ -#include "taimsg.h" -#include "taiplayer.h" - -const char *fc_ai_threaded_capstr(void); -bool fc_ai_threaded_setup(struct ai_type *ai); - -static void tai_init_self(struct ai_type *ai); -static struct ai_type *tai_get_self(void); - -static struct ai_type *self = NULL; - -/**********************************************************************//** - Set pointer to ai type of the threaded ai. -**************************************************************************/ -static void tai_init_self(struct ai_type *ai) -{ - self = ai; - - tai_init_threading(); -} - -/**********************************************************************//** - Get pointer to ai type of the threaded ai. -**************************************************************************/ -static struct ai_type *tai_get_self(void) -{ - return self; -} - -#define TAI_AIT struct ai_type *ait = tai_get_self(); -#define TAI_TFUNC(_func, ...) _func(ait, ## __VA_ARGS__ ); -#define TAI_DFUNC(_func, ...) _func(ait, ## __VA_ARGS__ ); - -/**********************************************************************//** - Free resources allocated by the threaded AI module -**************************************************************************/ -static void tai_module_close(void) -{ - TAI_AIT; - - FC_FREE(ait->private); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_player_alloc(struct player *pplayer) -{ - TAI_AIT; - TAI_TFUNC(tai_player_alloc, pplayer); - /* Do not call default AI here, tai_player_alloc() does necessary parts */ -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_player_free(struct player *pplayer) -{ - TAI_AIT; - TAI_TFUNC(tai_player_free, pplayer); - /* Do not call default AI here, tai_player_free() does necessary parts */ -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_player_save(struct player *pplayer, struct section_file *file, - int plrno) -{ - TAI_AIT; - TAI_DFUNC(dai_player_save, "tai", pplayer, file, plrno); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_player_load(struct player *pplayer, - const struct section_file *file, - int plrno) -{ - TAI_AIT; - TAI_DFUNC(dai_player_load, "tai", pplayer, file, plrno); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_control_gained(struct player *pplayer) -{ - TAI_AIT; - TAI_TFUNC(tai_control_gained, pplayer); - TAI_DFUNC(dai_gained_control, pplayer); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_control_lost(struct player *pplayer) -{ - TAI_AIT; - TAI_TFUNC(tai_control_lost, pplayer); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_split_by_civil_war(struct player *original, - struct player *created) -{ - TAI_AIT; - TAI_DFUNC(dai_assess_danger_player, original, &(wld.map)); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_created_by_civil_war(struct player *original, - struct player *created) -{ - TAI_AIT; - TAI_DFUNC(dai_player_copy, original, created); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_phase_begin(struct player *pplayer, bool is_new_phase) -{ - TAI_AIT; - TAI_DFUNC(dai_data_phase_begin, pplayer, is_new_phase); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_phase_finished(struct player *pplayer) -{ - TAI_AIT; - TAI_TFUNC(tai_phase_finished, pplayer); - TAI_DFUNC(dai_data_phase_finished, pplayer); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_city_alloc(struct city *pcity) -{ - TAI_AIT; - TAI_DFUNC(dai_city_alloc, pcity); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_city_free(struct city *pcity) -{ - TAI_AIT; - TAI_DFUNC(dai_city_free, pcity); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_city_save(struct section_file *file, const struct city *pcity, - const char *citystr) -{ - TAI_AIT; - TAI_DFUNC(dai_city_save, "tai", file, pcity, citystr); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_city_load(const struct section_file *file, struct city *pcity, - const char *citystr) -{ - TAI_AIT; - TAI_DFUNC(dai_city_load, "tai", file, pcity, citystr); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_build_adv_override(struct city *pcity, struct adv_choice *choice) -{ - TAI_AIT; - TAI_DFUNC(dai_build_adv_override, pcity, choice); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_wonder_city_distance(struct player *pplayer, struct adv_data *adv) -{ - TAI_AIT; - TAI_DFUNC(dai_wonder_city_distance, pplayer, adv); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_build_adv_init(struct player *pplayer) -{ - TAI_AIT; - TAI_DFUNC(dai_build_adv_init, pplayer); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_build_adv_adjust(struct player *pplayer, struct city *wonder_city) -{ - TAI_AIT; - TAI_DFUNC(dai_build_adv_adjust, pplayer, wonder_city); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_gov_value(struct player *pplayer, struct government *gov, - adv_want *val, bool *override) -{ - TAI_AIT; - TAI_DFUNC(dai_gov_value, pplayer, gov, val, override); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_units_ruleset_init(void) -{ - TAI_AIT; - TAI_DFUNC(dai_units_ruleset_init); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_units_ruleset_close(void) -{ - TAI_AIT; - TAI_DFUNC(dai_units_ruleset_close); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_unit_alloc(struct unit *punit) -{ - TAI_AIT; - TAI_DFUNC(dai_unit_init, punit); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_unit_free(struct unit *punit) -{ - TAI_AIT; - TAI_DFUNC(dai_unit_close, punit); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_ferry_init_ferry(struct unit *ferry) -{ - TAI_AIT; - TAI_DFUNC(dai_ferry_init_ferry, ferry); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_ferry_transformed(struct unit *ferry, - const struct unit_type *old) -{ - TAI_AIT; - TAI_DFUNC(dai_ferry_transformed, ferry, old); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_ferry_lost(struct unit *punit) -{ - TAI_AIT; - TAI_DFUNC(dai_ferry_lost, punit); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_unit_turn_end(struct unit *punit) -{ - TAI_AIT; - TAI_DFUNC(dai_unit_turn_end, punit); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_unit_move_or_attack(struct unit *punit, struct tile *ptile, - struct pf_path *path, int step) -{ - TAI_AIT; - TAI_DFUNC(dai_unit_move_or_attack, punit, ptile, path, step); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_unit_new_adv_task(struct unit *punit, enum adv_unit_task task, - struct tile *ptile) -{ - TAI_AIT; - TAI_DFUNC(dai_unit_new_adv_task, punit, task, ptile); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_unit_save(struct section_file *file, const struct unit *punit, - const char *unitstr) -{ - TAI_AIT; - TAI_DFUNC(dai_unit_save, "tai", file, punit, unitstr); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_unit_load(const struct section_file *file, struct unit *punit, - const char *unitstr) -{ - TAI_AIT; - TAI_DFUNC(dai_unit_load, "tai", file, punit, unitstr); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_auto_settler_reset(struct player *pplayer) -{ - TAI_AIT; - TAI_DFUNC(dai_auto_settler_reset, pplayer); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_auto_settler_run(struct player *pplayer, struct unit *punit, - struct settlermap *state) -{ - TAI_AIT; - TAI_DFUNC(dai_auto_settler_run, pplayer, punit, state); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_auto_settler_cont(struct player *pplayer, struct unit *punit, - struct settlermap *state) -{ - TAI_AIT; - TAI_DFUNC(dai_auto_settler_cont, pplayer, punit, state); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_switch_to_explore(struct unit *punit, struct tile *target, - enum override_bool *allow) -{ - TAI_AIT; - TAI_DFUNC(dai_switch_to_explore, punit, target, allow); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_first_activities(struct player *pplayer) -{ - TAI_AIT; - TAI_TFUNC(tai_first_activities, pplayer); - TAI_DFUNC(dai_do_first_activities, pplayer); -} - -/**********************************************************************//** - Start working on the thread again. -**************************************************************************/ -static void twai_restart_phase(struct player *pplayer) -{ - TAI_AIT; - TAI_TFUNC(tai_first_activities, pplayer); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_diplomacy_actions(struct player *pplayer) -{ - TAI_AIT; - TAI_DFUNC(dai_diplomacy_actions, pplayer); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_last_activities(struct player *pplayer) -{ - TAI_AIT; - TAI_DFUNC(dai_do_last_activities, pplayer); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_treaty_evaluate(struct player *pplayer, struct player *aplayer, - struct Treaty *ptreaty) -{ - TAI_AIT; - TAI_DFUNC(dai_treaty_evaluate, pplayer, aplayer, ptreaty); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_treaty_accepted(struct player *pplayer, struct player *aplayer, - struct Treaty *ptreaty) -{ - TAI_AIT; - TAI_DFUNC(dai_treaty_accepted, pplayer, aplayer, ptreaty); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_diplomacy_first_contact(struct player *pplayer, - struct player *aplayer) -{ - TAI_AIT; - TAI_DFUNC(dai_diplomacy_first_contact, pplayer, aplayer); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_incident(enum incident_type type, - enum casus_belli_range scope, - const struct action *paction, - struct player *receiver, - struct player *violator, struct player *victim) -{ - TAI_AIT; - TAI_DFUNC(dai_incident, type, scope, paction, receiver, violator, victim); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_city_log(char *buffer, int buflength, const struct city *pcity) -{ - TAI_AIT; - TAI_DFUNC(dai_city_log, buffer, buflength, pcity); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_unit_log(char *buffer, int buflength, const struct unit *punit) -{ - TAI_AIT; - TAI_DFUNC(dai_unit_log, buffer, buflength, punit); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_consider_plr_dangerous(struct player *plr1, struct player *plr2, - enum override_bool *result) -{ - TAI_AIT; - TAI_DFUNC(dai_consider_plr_dangerous, plr1, plr2, result); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_consider_tile_dangerous(struct tile *ptile, struct unit *punit, - enum override_bool *result) -{ - TAI_AIT; - TAI_DFUNC(dai_consider_tile_dangerous, ptile, punit, result); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_consider_wonder_city(struct city *pcity, bool *result) -{ - TAI_AIT; - TAI_DFUNC(dai_consider_wonder_city, pcity, result); -} - -/**********************************************************************//** - Call default ai with threaded ai type as parameter. -**************************************************************************/ -static void twai_refresh(struct player *pplayer) -{ - TAI_AIT; - TAI_TFUNC(tai_refresh, pplayer); -} - -/**********************************************************************//** - Return module capability string -**************************************************************************/ -const char *fc_ai_threaded_capstr(void) -{ - return FC_AI_MOD_CAPSTR; -} - -/**********************************************************************//** - Setup player ai_funcs function pointers. -**************************************************************************/ -bool fc_ai_threaded_setup(struct ai_type *ai) -{ - struct dai_private_data *private; - - if (!has_thread_cond_impl()) { - log_error(_("This Freeciv compilation has no full threads " - "implementation, threaded ai cannot be used.")); - return FALSE; - } - - strncpy(ai->name, "threaded", sizeof(ai->name)); - - private = fc_malloc(sizeof(struct dai_private_data)); - private->contemplace_workers = TRUE; - ai->private = private; - - tai_init_self(ai); - - ai->funcs.module_close = tai_module_close; - ai->funcs.player_alloc = twai_player_alloc; - ai->funcs.player_free = twai_player_free; - ai->funcs.player_save = twai_player_save; - ai->funcs.player_load = twai_player_load; - ai->funcs.gained_control = twai_control_gained; - ai->funcs.lost_control = twai_control_lost; - ai->funcs.split_by_civil_war = twai_split_by_civil_war; - ai->funcs.created_by_civil_war = twai_created_by_civil_war; - - ai->funcs.phase_begin = twai_phase_begin; - ai->funcs.phase_finished = twai_phase_finished; - - ai->funcs.city_alloc = twai_city_alloc; - ai->funcs.city_free = twai_city_free; - ai->funcs.city_save = twai_city_save; - ai->funcs.city_load = twai_city_load; - ai->funcs.choose_building = twai_build_adv_override; - ai->funcs.build_adv_prepare = twai_wonder_city_distance; - ai->funcs.build_adv_init = twai_build_adv_init; - ai->funcs.build_adv_adjust_want = twai_build_adv_adjust; - - ai->funcs.gov_value = twai_gov_value; - - ai->funcs.units_ruleset_init = twai_units_ruleset_init; - ai->funcs.units_ruleset_close = twai_units_ruleset_close; - - ai->funcs.unit_alloc = twai_unit_alloc; - ai->funcs.unit_free = twai_unit_free; - - ai->funcs.unit_got = twai_ferry_init_ferry; - ai->funcs.unit_lost = twai_ferry_lost; - ai->funcs.unit_transformed = twai_ferry_transformed; - - ai->funcs.unit_turn_end = twai_unit_turn_end; - ai->funcs.unit_move = twai_unit_move_or_attack; - ai->funcs.unit_task = twai_unit_new_adv_task; - - ai->funcs.unit_save = twai_unit_save; - ai->funcs.unit_load = twai_unit_load; - - ai->funcs.settler_reset = twai_auto_settler_reset; - ai->funcs.settler_run = twai_auto_settler_run; - ai->funcs.settler_cont = twai_auto_settler_cont; - - ai->funcs.want_to_explore = twai_switch_to_explore; - - ai->funcs.first_activities = twai_first_activities; - ai->funcs.restart_phase = twai_restart_phase; - ai->funcs.diplomacy_actions = twai_diplomacy_actions; - ai->funcs.last_activities = twai_last_activities; - - ai->funcs.treaty_evaluate = twai_treaty_evaluate; - ai->funcs.treaty_accepted = twai_treaty_accepted; - ai->funcs.first_contact = twai_diplomacy_first_contact; - ai->funcs.incident = twai_incident; - - ai->funcs.log_fragment_city = twai_city_log; - ai->funcs.log_fragment_unit = twai_unit_log; - - ai->funcs.consider_plr_dangerous = twai_consider_plr_dangerous; - ai->funcs.consider_tile_dangerous = twai_consider_tile_dangerous; - ai->funcs.consider_wonder_city = twai_consider_wonder_city; - - ai->funcs.refresh = twai_refresh; - - return TRUE; -} diff --git a/configure.ac b/configure.ac index 254a5468d6..36dde467ee 100644 --- a/configure.ac +++ b/configure.ac @@ -1068,7 +1068,6 @@ else fi]) ai_mod_static_classic=no -ai_mod_static_threaded=no ai_mod_static_tex=no ai_mod_static_stub=no @@ -1078,16 +1077,11 @@ for module in $(echo $static_modules | $SED 's/,/ /g') ; do ai_mod_default_needed=yes AC_DEFINE([AI_MOD_STATIC_CLASSIC], [1], [classic ai module statically linked]) - elif test "x$module" = "xthreaded" ; then - ai_mod_static_threaded=yes - ai_mod_default_needed=yes - AC_DEFINE([AI_MOD_STATIC_THREADED], [1], - [threaded ai module statically linked]) elif test "x$module" = "xtex" ; then ai_mod_static_tex=yes ai_mod_default_needed=yes AC_DEFINE([AI_MOD_STATIC_TEX], [1], - [experimental threads ai module statically linked]) + [tex ai module statically linked]) elif test "x$module" = "xstub" ; then ai_mod_static_stub=yes AC_DEFINE([AI_MOD_STATIC_STUB], [1], @@ -1102,8 +1096,6 @@ for module in $(echo $static_modules | $SED 's/,/ /g') ; do done AM_CONDITIONAL([AI_MOD_STATIC_CLASSIC], [test "x$ai_mod_static_classic" = "xyes" || test "x$enable_aimodules" != "xyes"]) -AM_CONDITIONAL([AI_MOD_STATIC_THREADED], -[test "x$ai_mod_static_threaded" = "xyes"]) AM_CONDITIONAL([AI_MOD_STATIC_TEX], [test "x$ai_mod_static_tex" = "xyes"]) AM_CONDITIONAL([AI_MOD_STATIC_STUB], @@ -1129,9 +1121,6 @@ fc_ai_last=0 if test "x$ai_mod_static_classic" = "xyes" ; then fc_ai_last=$fc_ai_last+1 fi -if test "x$ai_mod_static_threaded" = "xyes" ; then - fc_ai_last=$fc_ai_last+1 -fi if test "x$ai_mod_static_tex" = "xyes" ; then fc_ai_last=$fc_ai_last+1 fi @@ -1852,7 +1841,6 @@ AC_CONFIG_FILES([Makefile ai/default/Makefile ai/classic/Makefile ai/stub/Makefile - ai/threaded/Makefile ai/tex/Makefile tests/Makefile windows/Makefile diff --git a/doc/README.AI_modules b/doc/README.AI_modules index 7433a31249..5fe1f26467 100644 --- a/doc/README.AI_modules +++ b/doc/README.AI_modules @@ -97,7 +97,7 @@ For "--LoadAI " to find the AI module, it must reside in ${libdir}/f -------------------------------------------- Default AI here refers to specific code module that any AI module can use, not to any -one AI module. Classic AI module is just a thin wrapper around it, and also Threaded AI +one AI module. Classic AI module is just a thin wrapper around it, and also Tex AI uses it. Almost all functions in default AI API take pointer to current AI type as parameter. @@ -106,10 +106,10 @@ having such AI type specific data. If a AI type wants to add its own data associated with some code structure, it needs to make sure data needed by default AI is in the beginning of the allocated data blocks. -For example, see threaded AI: tai_player_alloc(), tai_player_free(), and struct tai_plr. +For example, see tex AI: texai_player_alloc(), texai_player_free(), and struct tai_plr. Default AI code is usually built in freeciv only if some AI type using it has been built; -either 'classic' or 'threaded'. If no such ai type has been built, you can still force +either 'classic' or 'tex'. If no such ai type has been built, you can still force it in for custom ai types to use by passing configure option --with-ai-lib diff --git a/doc/README.packaging b/doc/README.packaging index 807a6f7398..f5a40c6a6c 100644 --- a/doc/README.packaging +++ b/doc/README.packaging @@ -20,6 +20,7 @@ Updating from 3.1 to 3.2 * Gtk3-client has been dropped * Minimum SDL2 requirement for sound support is 2.0.6. * Minimum Python requirement for code generation scripts is 3.5. +* Threaded AI has been dropped completely ---------------------------------------------------------------------- Compatibility of modified versions -- 2.35.1