diff --git a/src/playmp_controller.cpp b/src/playmp_controller.cpp index 0c4cde17b118..0dd3493d0e52 100644 --- a/src/playmp_controller.cpp +++ b/src/playmp_controller.cpp @@ -255,7 +255,7 @@ possible_end_play_signal playmp_controller::play_human_turn(){ return boost::none; } -void playmp_controller::play_idle_loop() +possible_end_play_signal playmp_controller::play_idle_loop() { LOG_NG << "playmp::play_human_turn...\n"; @@ -266,16 +266,19 @@ void playmp_controller::play_idle_loop() turn_info_send send_safe(turn_data_); config cfg; if(network_reader_.read(cfg)) { - turn_info::PROCESS_DATA_RESULT res = turn_data_.process_network_data(cfg, skip_replay_); + turn_info::PROCESS_DATA_RESULT res; + HANDLE_END_PLAY_SIGNAL( res = turn_data_.process_network_data(cfg, skip_replay_) ); if (res == turn_info::PROCESS_RESTART_TURN || res == turn_info::PROCESS_RESTART_TURN_TEMPORARY_LOCAL) { - throw end_turn_exception(gui_->playing_side()); + end_turn_struct ets = {gui_->playing_side()}; + return possible_end_play_signal(ets); + //throw end_turn_exception(gui_->playing_side()); } } - play_slice(); - check_end_level(); + HANDLE_END_PLAY_SIGNAL ( play_slice() ); + HANDLE_END_PLAY_SIGNAL ( check_end_level() ); if (!linger_) { SDL_Delay(1); @@ -283,6 +286,7 @@ void playmp_controller::play_idle_loop() gui_->draw(); } + return boost::none; } void playmp_controller::set_end_scenario_button() diff --git a/src/playmp_controller.hpp b/src/playmp_controller.hpp index d42ea63183a3..d2e7f3e92066 100644 --- a/src/playmp_controller.hpp +++ b/src/playmp_controller.hpp @@ -55,7 +55,7 @@ class playmp_controller : public playsingle_controller, public events::pump_moni virtual void finish_side_turn(); virtual possible_end_play_signal play_network_turn(); virtual void do_idle_notification(); - virtual void play_idle_loop(); + virtual possible_end_play_signal play_idle_loop(); void linger(); /** Wait for the host to upload the next scenario. */ diff --git a/src/playsingle_controller.cpp b/src/playsingle_controller.cpp index eda9faf3d922..5c686964e08d 100644 --- a/src/playsingle_controller.cpp +++ b/src/playsingle_controller.cpp @@ -694,13 +694,14 @@ possible_end_play_signal playsingle_controller::play_turn() return boost::none; } -void playsingle_controller::play_idle_loop() +possible_end_play_signal playsingle_controller::play_idle_loop() { while(!end_turn_) { - play_slice(); + HANDLE_END_PLAY_SIGNAL( play_slice() ); gui_->draw(); SDL_Delay(10); } + return boost::none; } possible_end_play_signal playsingle_controller::play_side() @@ -787,28 +788,38 @@ possible_end_play_signal playsingle_controller::play_side() } else if(current_team().is_network()) { PROPOGATE_END_PLAY_SIGNAL( play_network_turn() ); } else if(current_team().is_idle()) { + end_turn_enable(false); + do_idle_notification(); + + possible_end_play_signal signal; try{ - end_turn_enable(false); - do_idle_notification(); - before_human_turn(); - play_idle_loop(); - + before_human_turn(); //This line throws! the ai manager "raise" line throws exception from here: https://github.com/wesnoth/wesnoth/blob/ac96a2b91b3276e20b682210617cf87d1e0d366a/src/playsingle_controller.cpp#L954 + signal = play_idle_loop(); } catch(end_turn_exception& end_turn) { - LOG_NG << "Escaped from idle state with exception!" << std::endl; - if (int(end_turn.redo) == player_number_) { - player_type_changed_ = true; - // If new controller is not human, - // reset gui to prev human one - if (!gameboard_.teams_[player_number_-1].is_human()) { - browse_ = true; - int s = find_human_team_before_current_player(); - if (s <= 0) - s = gui_->playing_side(); - update_gui_to_player(s-1); - } + signal = end_turn.to_struct(); + } catch(end_level_exception& e) { + signal = e.to_struct(); + } + + if (signal) { + switch (boost::apply_visitor(get_signal_type(), *signal)) { + case END_LEVEL: + return signal; + case END_TURN: + LOG_NG << "Escaped from idle state with exception!" << std::endl; + if (int(boost::apply_visitor(get_redo(), *signal)) == player_number_) { + player_type_changed_ = true; + // If new controller is not human, + // reset gui to prev human one + if (!gameboard_.teams_[player_number_-1].is_human()) { + browse_ = true; + int s = find_human_team_before_current_player(); + if (s <= 0) + s = gui_->playing_side(); + update_gui_to_player(s-1); + } + } } - } catch (end_level_exception e) { //this shouldn't really be possible, but in case it is somehow this will prevent a crash. - return possible_end_play_signal(e.to_struct()); } } diff --git a/src/playsingle_controller.hpp b/src/playsingle_controller.hpp index 72db21611280..a83461224a7c 100644 --- a/src/playsingle_controller.hpp +++ b/src/playsingle_controller.hpp @@ -101,7 +101,7 @@ class playsingle_controller : public play_controller void end_turn_enable(bool enable); virtual hotkey::ACTION_STATE get_action_state(hotkey::HOTKEY_COMMAND command, int index) const; void play_ai_turn(); - virtual void play_idle_loop(); + virtual possible_end_play_signal play_idle_loop(); virtual void do_idle_notification(); virtual possible_end_play_signal play_network_turn(); virtual void init_gui();