Skip to content

Commit

Permalink
don't throw exceptions on :droid, :idle
Browse files Browse the repository at this point in the history
This not only simplifies the playsingle/mp_controller code, it also
fixes a bug that actions were aborted when issueing a :droid during an
ai turn causing corrupt replays or worse.

We still use restart_turn_exception to escape insode the ai code but not
during the action. Instead we now check player_type_changed_ after every
action, just like we do for ai_end_turn_exception and catch it inside
ai::manager::play_turn so that the playsingle/mp_controller code doesn't
have to handle this exception anymore.
  • Loading branch information
gfgtdf committed Mar 1, 2015
1 parent f8b4741 commit b60809e
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 138 deletions.
7 changes: 7 additions & 0 deletions src/ai/actions.cpp
Expand Up @@ -44,6 +44,7 @@
#include "../mouse_handler_base.hpp"
#include "../pathfind/teleport.hpp"
#include "../play_controller.hpp"
#include "../playsingle_controller.hpp"
#include "../recall_list_manager.hpp"
#include "../replay_helper.hpp"
#include "../resources.hpp"
Expand Down Expand Up @@ -104,6 +105,12 @@ void action_result::execute()
if(resources::controller->is_end_turn()) {
throw ai_end_turn_exception();
}

if(playsingle_controller* psc = dynamic_cast<playsingle_controller*>(resources::controller)) {
if(psc->get_player_type_changed()) {
throw restart_turn_exception();
}
}
is_execution_ = false;
}

Expand Down
2 changes: 2 additions & 0 deletions src/ai/manager.cpp
Expand Up @@ -798,6 +798,8 @@ void manager::play_turn( side_number side ){
}
catch (const ai_end_turn_exception&) {
}
catch(const restart_turn_exception&) {
}
const int turn_end_time= SDL_GetTicks();
DBG_AI_MANAGER << "side " << side << ": number of user interactions: "<<num_interact_<<std::endl;
DBG_AI_MANAGER << "side " << side << ": total turn time: "<<turn_end_time - turn_start_time << " ms "<< std::endl;
Expand Down
31 changes: 1 addition & 30 deletions src/game_end_exceptions.hpp
Expand Up @@ -30,7 +30,6 @@
#include <string>
#include <exception>
#include <boost/optional.hpp>
#include <boost/variant/variant.hpp>

MAKE_ENUM(LEVEL_RESULT,
(VICTORY, "victory")
Expand Down Expand Up @@ -59,13 +58,6 @@ class ai_end_turn_exception
IMPLEMENT_LUA_JAILBREAK_EXCEPTION(ai_end_turn_exception)
};


/**
* Struct used to transmit info caught from an end_turn_exception.
*/
struct restart_turn_struct {
};

/**
* Exception used to signal the end of a player turn.
*/
Expand All @@ -80,10 +72,6 @@ class restart_turn_exception
{
}
const char * what() const throw() { return "restart_turn_exception"; }
restart_turn_struct to_struct()
{
return restart_turn_struct();
}

private:

Expand Down Expand Up @@ -129,7 +117,7 @@ class end_level_exception
/**
* The two end_*_exceptions are caught and transformed to this signaling object
*/
typedef boost::optional<boost::variant<restart_turn_struct, end_level_struct> > possible_end_play_signal;
typedef boost::optional<end_level_struct> possible_end_play_signal;

#define HANDLE_END_PLAY_SIGNAL( X )\
do\
Expand All @@ -138,8 +126,6 @@ do\
X;\
} catch (end_level_exception & e) {\
return possible_end_play_signal(e.to_struct());\
} catch (restart_turn_exception & e) {\
return possible_end_play_signal(e.to_struct());\
}\
}\
while(0)
Expand Down Expand Up @@ -171,21 +157,6 @@ do\
while(0)


enum END_PLAY_SIGNAL_TYPE {END_TURN, END_LEVEL};

class get_signal_type : public boost::static_visitor<END_PLAY_SIGNAL_TYPE> {
public:
END_PLAY_SIGNAL_TYPE operator()(restart_turn_struct &) const
{
return END_TURN;
}

END_PLAY_SIGNAL_TYPE operator()(end_level_struct& ) const
{
return END_LEVEL;
}
};

/**
* The non-persistent part of end_level_data
*/
Expand Down
13 changes: 7 additions & 6 deletions src/menu_events.cpp
Expand Up @@ -61,6 +61,7 @@
#include "menu_events.hpp"
#include "mouse_events.hpp"
#include "play_controller.hpp"
#include "playsingle_controller.hpp"
#include "preferences_display.hpp"
#include "replay.hpp"
#include "replay_helper.hpp"
Expand Down Expand Up @@ -2711,9 +2712,9 @@ void console_handler::do_droid() {
}
menu_handler_.teams()[side - 1].toggle_droid();
if(team_num_ == side) {
//if it is our turn at the moment, we have to indicate to the
//play_controller, that we are no longer in control
throw restart_turn_exception();
if(playsingle_controller* psc = dynamic_cast<playsingle_controller*>(&menu_handler_.pc_)) {
psc->set_player_type_changed();
}
}
} else if (menu_handler_.teams()[side - 1].is_local_ai()) {
// menu_handler_.teams()[side - 1].make_human();
Expand Down Expand Up @@ -2756,9 +2757,9 @@ void console_handler::do_idle() {
//toggle the proxy controller between idle / non idle
menu_handler_.teams()[side - 1].toggle_idle();
if(team_num_ == side) {
//if it is our turn at the moment, we have to indicate to the
//play_controller, that we are no longer in control
throw restart_turn_exception();
if(playsingle_controller* psc = dynamic_cast<playsingle_controller*>(&menu_handler_.pc_)) {
psc->set_player_type_changed();
}
}
}
menu_handler_.textbox_info_.close(*menu_handler_.gui_);
Expand Down
16 changes: 3 additions & 13 deletions src/mouse_events.cpp
Expand Up @@ -67,7 +67,6 @@
#include "SDL_mouse.h" // for SDL_GetMouseState
#include "SDL_video.h" // for SDL_Color

class restart_turn_exception;
namespace gui { class slider; }

static lg::log_domain log_engine("engine");
Expand Down Expand Up @@ -889,18 +888,9 @@ size_t mouse_handler::move_unit_along_route(const std::vector<map_location> & st
}
}

size_t moves = 0;
try {

LOG_NG << "move unit along route from " << steps.front() << " to " << steps.back() << "\n";
moves = actions::move_unit_and_record(steps, &pc_.get_undo_stack(),
false, true, &interrupted);
} catch(restart_turn_exception&) {
cursor::set(cursor::NORMAL);
gui().invalidate_game_status();
throw;
}

LOG_NG << "move unit along route from " << steps.front() << " to " << steps.back() << "\n";
size_t moves = actions::move_unit_and_record(steps, &pc_.get_undo_stack(), false, true, &interrupted);

cursor::set(cursor::NORMAL);
gui().invalidate_game_status();

Expand Down
19 changes: 8 additions & 11 deletions src/playmp_controller.cpp
Expand Up @@ -128,7 +128,7 @@ possible_end_play_signal playmp_controller::play_human_turn()
if (!linger_ || is_host()) {
end_turn_enable(true);
}
while(!end_turn_) {
while(!end_turn_ && !player_type_changed_) {
try {
config cfg;

Expand All @@ -137,6 +137,7 @@ possible_end_play_signal playmp_controller::play_human_turn()
HANDLE_END_PLAY_SIGNAL( res = turn_data_.process_network_data(cfg) );
if (res == turn_info::PROCESS_RESTART_TURN)
{
player_type_changed_ = true;
// Clean undo stack if turn has to be restarted (losing control)
if ( undo_stack_->can_undo() )
{
Expand All @@ -155,7 +156,7 @@ possible_end_play_signal playmp_controller::play_human_turn()
while( undo_stack_->can_undo() )
undo_stack_->undo();

return possible_end_play_signal(restart_turn_struct());
return boost::none;
}
else if(res == turn_info::PROCESS_END_LINGER)
{
Expand Down Expand Up @@ -199,7 +200,7 @@ possible_end_play_signal playmp_controller::play_idle_loop()

remove_blindfold();

while (!end_turn_)
while (!end_turn_ && !player_type_changed_)
{
try
{
Expand All @@ -210,7 +211,8 @@ possible_end_play_signal playmp_controller::play_idle_loop()

if (res == turn_info::PROCESS_RESTART_TURN)
{
return possible_end_play_signal(restart_turn_struct());
player_type_changed_ = true;
return boost::none;
}
}

Expand Down Expand Up @@ -268,7 +270,7 @@ void playmp_controller::linger()
gamestate_.board_.set_all_units_user_end_turn();

set_end_scenario_button();

assert(is_regular_game_end());
if ( get_end_level_data_const().transient.reveal_map ) {
// Change the view of all players and observers
// to see the whole map regardless of shroud and fog.
Expand All @@ -295,12 +297,6 @@ void playmp_controller::linger()
LOG_NG << "caught end-level-exception" << std::endl;
reset_end_scenario_button();
throw;
} catch (restart_turn_exception&) {
// thrown if the host leaves the game (sends [leave_game]), we need
// to stay in this loop to stay in linger mode, otherwise the game
// gets aborted
LOG_NG << "caught end-turn-exception" << std::endl;
quit = false;
} catch (network::error&) {
LOG_NG << "caught network-error-exception" << std::endl;
quit = false;
Expand Down Expand Up @@ -478,6 +474,7 @@ void playmp_controller::do_idle_notification()
void playmp_controller::maybe_linger()
{
// mouse_handler expects at least one team for linger mode to work.
assert(is_regular_game_end());
if (!get_end_level_data_const().transient.linger_mode || gamestate_.board_.teams().empty()) {
if(!is_host()) {
// If we continue without lingering we need to
Expand Down

0 comments on commit b60809e

Please sign in to comment.