Skip to content

Commit

Permalink
refactor end_turn_exception
Browse files Browse the repository at this point in the history
end_turn_exception was split into 2 exceptions.
restart_turn_exception/struct which is used when a side got reassigned
this case covers most of end_turn_exceptions previous usecases.
and ai_end_turn_exception which is only used by the ai internally, we
also move the throwing of ai_end_turn_exception fom
playsingle/mp_controller::handle_generic_event to
ai::action_result::execute so that non ai code that might call
handle_generic_event doesn't have to think about ai_end_turn_exception.

This also partly fixes a bug where undroiding a side caused the sides turn to end.
  • Loading branch information
gfgtdf committed Feb 26, 2015
1 parent 0866ccb commit 4251252
Show file tree
Hide file tree
Showing 14 changed files with 115 additions and 128 deletions.
3 changes: 3 additions & 0 deletions src/ai/actions.cpp
Expand Up @@ -101,6 +101,9 @@ void action_result::execute()
if (is_success()){
check_after();
}
if(resources::controller->is_end_turn()) {
throw ai_end_turn_exception();
}
is_execution_ = false;
}

Expand Down
17 changes: 11 additions & 6 deletions src/ai/manager.cpp
Expand Up @@ -34,6 +34,7 @@
#include "configuration.hpp" // for configuration
#include "contexts.hpp" // for readonly_context, etc
#include "default/contexts.hpp" // for default_ai_context, etc
#include "game_end_exceptions.hpp" // for ai_end_turn_exception
#include "game_info.hpp" // for side_number, engine_ptr, etc
#include "game_config.hpp" // for debug
#include "game_errors.hpp" // for game_error
Expand Down Expand Up @@ -787,12 +788,16 @@ void manager::play_turn( side_number side ){
num_interact_ = 0;
const int turn_start_time = SDL_GetTicks();
/*hack. @todo 1.9 rework via extended event system*/
get_ai_info().recent_attacks.clear();
interface& ai_obj = get_active_ai_for_side(side);
resources::game_events->pump().fire("ai turn");
raise_turn_started();
ai_obj.new_turn();
ai_obj.play_turn();
try {
get_ai_info().recent_attacks.clear();
interface& ai_obj = get_active_ai_for_side(side);
resources::game_events->pump().fire("ai turn");
raise_turn_started();
ai_obj.new_turn();
ai_obj.play_turn();
}
catch (const ai_end_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
71 changes: 39 additions & 32 deletions src/game_end_exceptions.hpp
Expand Up @@ -28,7 +28,7 @@
#include "make_enum.hpp"

#include <string>

#include <exception>
#include <boost/optional.hpp>
#include <boost/variant/variant.hpp>

Expand All @@ -42,37 +42,54 @@ MAKE_ENUM(LEVEL_RESULT,
)
MAKE_ENUM_STREAM_OPS1(LEVEL_RESULT)

/**
* Exception used to escape form the ai code in case of [end_turn].
*/
class ai_end_turn_exception
: public tlua_jailbreak_exception, public std::exception
{
public:

ai_end_turn_exception()
: tlua_jailbreak_exception()
, std::exception()
{
}
const char * what() const { return "ai_end_turn_exception"; }
private:

IMPLEMENT_LUA_JAILBREAK_EXCEPTION(ai_end_turn_exception)
};


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

/**
* Exception used to signal the end of a player turn.
*/
class end_turn_exception
: public tlua_jailbreak_exception
class restart_turn_exception
: public tlua_jailbreak_exception, public std::exception
{
public:

end_turn_exception(unsigned r = 0)
restart_turn_exception()
: tlua_jailbreak_exception()
, redo(r)
, std::exception()
{
}

unsigned redo;

end_turn_struct to_struct() {
end_turn_struct ets = {redo};
return ets;
const char * what() const { return "restart_turn_exception"; }
restart_turn_struct to_struct()
{
return restart_turn_struct();
}

private:

IMPLEMENT_LUA_JAILBREAK_EXCEPTION(end_turn_exception)
IMPLEMENT_LUA_JAILBREAK_EXCEPTION(restart_turn_exception)
};

/**
Expand All @@ -87,11 +104,13 @@ struct end_level_struct {
*/
class end_level_exception
: public tlua_jailbreak_exception
, public std::exception
{
public:

end_level_exception(LEVEL_RESULT res)
: tlua_jailbreak_exception()
, std::exception()
, result(res)
{
}
Expand All @@ -102,7 +121,8 @@ class end_level_exception
end_level_struct els = {result};
return els;
}


const char * what() const { return "end_level_exception"; }
private:

IMPLEMENT_LUA_JAILBREAK_EXCEPTION(end_level_exception)
Expand All @@ -111,7 +131,7 @@ class end_level_exception
/**
* The two end_*_exceptions are caught and transformed to this signaling object
*/
typedef boost::optional<boost::variant<end_turn_struct, end_level_struct> > possible_end_play_signal;
typedef boost::optional<boost::variant<restart_turn_struct, end_level_struct> > possible_end_play_signal;

#define HANDLE_END_PLAY_SIGNAL( X )\
do\
Expand All @@ -120,7 +140,7 @@ do\
X;\
} catch (end_level_exception & e) {\
return possible_end_play_signal(e.to_struct());\
} catch (end_turn_exception & e) {\
} catch (restart_turn_exception & e) {\
return possible_end_play_signal(e.to_struct());\
}\
}\
Expand Down Expand Up @@ -157,7 +177,7 @@ 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()(end_turn_struct &) const
END_PLAY_SIGNAL_TYPE operator()(restart_turn_struct &) const
{
return END_TURN;
}
Expand All @@ -168,22 +188,9 @@ class get_signal_type : public boost::static_visitor<END_PLAY_SIGNAL_TYPE> {
}
};

class get_redo : public boost::static_visitor<unsigned> {
public:
unsigned operator()(end_turn_struct & s) const
{
return s.redo;
}

unsigned operator()(end_level_struct &) const
{
return 0;
}
};

class get_result : public boost::static_visitor<LEVEL_RESULT> {
public:
LEVEL_RESULT operator()(end_turn_struct & ) const
LEVEL_RESULT operator()(restart_turn_struct & ) const
{
return NONE;
}
Expand Down
6 changes: 2 additions & 4 deletions src/menu_events.cpp
Expand Up @@ -2713,7 +2713,7 @@ void console_handler::do_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 end_turn_exception(side);
throw restart_turn_exception();
}
} else if (menu_handler_.teams()[side - 1].is_local_ai()) {
// menu_handler_.teams()[side - 1].make_human();
Expand Down Expand Up @@ -2758,7 +2758,7 @@ void console_handler::do_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 end_turn_exception(side);
throw restart_turn_exception();
}
}
menu_handler_.textbox_info_.close(*menu_handler_.gui_);
Expand Down Expand Up @@ -3322,8 +3322,6 @@ void menu_handler::do_ai_formula(const std::string& str,
{
try {
add_chat_message(time(NULL), _("ai"), 0, ai::manager::evaluate_command(side_num, str));
} catch(end_turn_exception&) {
pc_.force_end_turn();
} catch(...) {
//add_chat_message(time(NULL), _("ai"), 0, "ERROR IN FORMULA");
}
Expand Down
4 changes: 2 additions & 2 deletions src/mouse_events.cpp
Expand Up @@ -67,7 +67,7 @@
#include "SDL_mouse.h" // for SDL_GetMouseState
#include "SDL_video.h" // for SDL_Color

class end_turn_exception;
class restart_turn_exception;
namespace gui { class slider; }

static lg::log_domain log_engine("engine");
Expand Down Expand Up @@ -895,7 +895,7 @@ size_t mouse_handler::move_unit_along_route(const std::vector<map_location> & st
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(end_turn_exception&) {
} catch(restart_turn_exception&) {
cursor::set(cursor::NORMAL);
gui().invalidate_game_status();
throw;
Expand Down
2 changes: 1 addition & 1 deletion src/play_controller.hpp
Expand Up @@ -169,7 +169,7 @@ class play_controller : public controller_base, public events::observer, public

bool is_skipping_replay() const { return skip_replay_;}
bool is_linger_mode() const { return linger_; }

virtual bool is_end_turn() const { return false; }
void do_autosave();

void do_consolesave(const std::string& filename);
Expand Down
21 changes: 6 additions & 15 deletions src/playmp_controller.cpp
Expand Up @@ -96,11 +96,10 @@ possible_end_play_signal playmp_controller::play_side()
return playsingle_controller::play_side();
}

possible_end_play_signal playmp_controller::before_human_turn(){
void playmp_controller::before_human_turn(){
LOG_NG << "playmp::before_human_turn...\n";
PROPOGATE_END_PLAY_SIGNAL( playsingle_controller::before_human_turn() );
playsingle_controller::before_human_turn();
turn_data_.send_data();
return boost::none;
}

void playmp_controller::on_not_observer() {
Expand Down Expand Up @@ -196,9 +195,7 @@ possible_end_play_signal playmp_controller::play_human_turn()
while( undo_stack_->can_undo() )
undo_stack_->undo();

end_turn_struct ets = {static_cast<unsigned>(gui_->playing_side())};
return possible_end_play_signal(ets);
//throw end_turn_exception(gui_->playing_side());
return restart_turn_struct();
}
else if(res == turn_info::PROCESS_END_LINGER)
{
Expand Down Expand Up @@ -239,8 +236,7 @@ possible_end_play_signal playmp_controller::play_human_turn()
current_team().set_countdown_time(10);
}

return possible_end_play_signal(end_turn_exception().to_struct());
//throw end_turn_exception();
return boost::none;
}
}
}
Expand Down Expand Up @@ -273,9 +269,7 @@ possible_end_play_signal playmp_controller::play_idle_loop()

if (res == turn_info::PROCESS_RESTART_TURN)
{
end_turn_struct ets = {static_cast<unsigned>(gui_->playing_side())};
return possible_end_play_signal(ets);
//throw end_turn_exception(gui_->playing_side());
return restart_turn_struct();
}
}

Expand Down Expand Up @@ -363,7 +357,7 @@ void playmp_controller::linger()
LOG_NG << "caught end-level-exception" << std::endl;
reset_end_scenario_button();
throw;
} catch (end_turn_exception&) {
} 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
Expand Down Expand Up @@ -544,9 +538,6 @@ void playmp_controller::handle_generic_event(const std::string& name){
gui_->invalidate_theme();
}
}
if (end_turn_) {
throw end_turn_exception();
}
}

void playmp_controller::do_idle_notification()
Expand Down
2 changes: 1 addition & 1 deletion src/playmp_controller.hpp
Expand Up @@ -51,7 +51,7 @@ class playmp_controller : public playsingle_controller, public events::pump_moni
void stop_network();

virtual possible_end_play_signal play_side();
virtual possible_end_play_signal before_human_turn();
virtual void before_human_turn();
virtual possible_end_play_signal play_human_turn();
virtual void after_human_turn();
virtual void finish_side_turn();
Expand Down

0 comments on commit 4251252

Please sign in to comment.