Skip to content

Commit

Permalink
fix chat during [delay] and animations
Browse files Browse the repository at this point in the history
fixes #1856
  • Loading branch information
gfgtdf committed Mar 25, 2018
1 parent 125c330 commit 219f977
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/controller_base.hpp
Expand Up @@ -66,7 +66,7 @@ class controller_base : public video2::draw_layering
controller_base(const config& game_config);
virtual ~controller_base();

void play_slice(bool is_delay_enabled = true);
virtual void play_slice(bool is_delay_enabled = true);

static const config& get_theme(const config& game_config, std::string theme_name);

Expand Down
17 changes: 14 additions & 3 deletions src/playmp_controller.cpp
Expand Up @@ -454,7 +454,15 @@ void playmp_controller::send_user_choice()
turn_data_.send_data();
}

void playmp_controller::process_network_data()
void playmp_controller::play_slice(bool is_delay_enabled)
{
process_network_data(true);
//cannot use turn_data_.send_data() here.
replay_sender_.sync_non_undoable();
playsingle_controller::play_slice(is_delay_enabled);
}

void playmp_controller::process_network_data(bool chat_only)
{
if(end_turn_ == END_TURN_SYNCED || is_regular_game_end() || player_type_changed_) {
return;
Expand All @@ -465,10 +473,13 @@ void playmp_controller::process_network_data()
res = turn_info::replay_to_process_data_result(do_replay());
}
else if(network_reader_.read(cfg)) {
res = turn_data_.process_network_data(cfg);
res = turn_data_.process_network_data(cfg, chat_only);
}

if (res == turn_info::PROCESS_RESTART_TURN) {
if (res == turn_info::PROCESS_CANNOT_HANDLE) {
network_reader_.push_front(std::move(cfg));
}
else if (res == turn_info::PROCESS_RESTART_TURN) {
player_type_changed_ = true;
}
else if (res == turn_info::PROCESS_END_TURN) {
Expand Down
5 changes: 4 additions & 1 deletion src/playmp_controller.hpp
Expand Up @@ -40,6 +40,9 @@ class playmp_controller : public playsingle_controller, public syncmp_handler
bool is_networked_mp() const override;
void send_to_wesnothd(const config& cfg, const std::string& packet_type = "unknown") const override;
bool receive_from_wesnothd(config& cfg) const override;


void play_slice(bool is_delay_enabled = true) override;
protected:
virtual void handle_generic_event(const std::string& name) override;

Expand Down Expand Up @@ -67,6 +70,6 @@ class playmp_controller : public playsingle_controller, public syncmp_handler
private:
void set_end_scenario_button();
void reset_end_scenario_button();
void process_network_data();
void process_network_data(bool chat_only = false);
mp_campaign_info* mp_info_;
};
13 changes: 10 additions & 3 deletions src/playturn.cpp
Expand Up @@ -85,10 +85,14 @@ void turn_info::send_data()
}
}

turn_info::PROCESS_DATA_RESULT turn_info::handle_turn(const config& t)
turn_info::PROCESS_DATA_RESULT turn_info::handle_turn(const config& t, bool chat_only)
{
//t can contain a [command] or a [upload_log]
assert(t.all_children_count() == 1);

if(!t.child_or_empty("command").has_child("speak") && chat_only) {
return PROCESS_CANNOT_HANDLE;
}
/** @todo FIXME: Check what commands we execute when it's our turn! */

//note, that this function might call itself recursively: do_replay -> ... -> get_user_choice -> ... -> playmp_controller::pull_remote_choice -> sync_network -> handle_turn
Expand Down Expand Up @@ -119,7 +123,7 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data_from_reader()
return PROCESS_CONTINUE;
}

turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg)
turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg, bool chat_only)
{
// the simple wesnothserver implementation in wesnoth was removed years ago.
assert(cfg.all_children_count() == 1);
Expand Down Expand Up @@ -154,7 +158,7 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
}
else if (const config &turn = cfg.child("turn"))
{
return handle_turn(turn);
return handle_turn(turn, chat_only);
}
else if (cfg.has_child("whiteboard"))
{
Expand Down Expand Up @@ -346,6 +350,9 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
// The host has ended linger mode in a campaign -> enable the "End scenario" button
// and tell we did get the notification.
else if (cfg.child("notify_next_scenario")) {
if(chat_only) {
return PROCESS_CANNOT_HANDLE;
}
std::shared_ptr<gui::button> btn_end = display::get_singleton()->find_action_button("button-endturn");
if(btn_end) {
btn_end->enable(true);
Expand Down
6 changes: 4 additions & 2 deletions src/playturn.hpp
Expand Up @@ -42,6 +42,8 @@ class turn_info
PROCESS_END_LINGER,
/** When we couldn't process the network data because we found a dependent command, this should only happen if we were called playmp_controller::from handle_generic_event -> sync_network*/
PROCESS_FOUND_DEPENDENT,
/** when we couldn't handle the given action currently. */
PROCESS_CANNOT_HANDLE,
/** We found a player action in the replay that caused the game to end*/
PROCESS_END_LEVEL
};
Expand All @@ -51,7 +53,7 @@ class turn_info
void send_data();

//function which will process incoming network data received with playturn_network_adapter, and act on it.
PROCESS_DATA_RESULT process_network_data(const config& cfg);
PROCESS_DATA_RESULT process_network_data(const config& cfg, bool chat_only = false);

//reads as much data from network_reader_ as possible and processed it.
PROCESS_DATA_RESULT process_network_data_from_reader();
Expand All @@ -61,7 +63,7 @@ class turn_info
static PROCESS_DATA_RESULT replay_to_process_data_result(REPLAY_RETURN replayreturn);
private:
static void change_side_controller(int side, const std::string& player);
PROCESS_DATA_RESULT handle_turn(const config& t);
PROCESS_DATA_RESULT handle_turn(const config& t, bool chat_only = false);

void do_save();

Expand Down
21 changes: 17 additions & 4 deletions src/playturn_network_adapter.cpp
Expand Up @@ -66,9 +66,20 @@ bool playturn_network_adapter::is_at_end()
return this->next_ == data_.back().ordered_end();
}

void playturn_network_adapter::push_front(config&& cfg)
{
data_front_.emplace_front(std::move(cfg));
}

bool playturn_network_adapter::read(config& dst)
{
assert(dst.empty());
if(!data_front_.empty())
{
dst = std::move(data_front_.back());
data_front_.pop_back();
return true;
}
if(is_at_end())
{
read_from_network();
Expand Down Expand Up @@ -114,10 +125,12 @@ bool playturn_network_adapter::read(config& dst)
}

playturn_network_adapter::playturn_network_adapter(source_type source)
: data_({config()}),
next_(data_.front().ordered_end()),
next_command_num_(0),
network_reader_(source)
: network_reader_(source)
, data_({config()})
, data_front_()
, next_(data_.front().ordered_end())
, next_command_num_(0)

{

}
Expand Down
12 changes: 10 additions & 2 deletions src/playturn_network_adapter.hpp
Expand Up @@ -37,16 +37,24 @@ class playturn_network_adapter
void set_source(source_type source);
//returns a function to be passed to set_source.
static source_type get_source_from_config(config& src);
void push_front(config&& cfg);
private:
//reads data from the network stream.
void read_from_network();
//a function to receive data from the network.
source_type network_reader_;

// note: all of the following could be replaced by a simple std::list<config> if we would
// split incoming tags right after we rechived them from network_reader_ the reason
// why we currently don'T do that is for performance.

//this always contains one empty config because we want a valid value for next_.
std::list<config> data_;
//packages that the client could not process at that point.
std::list<config> data_front_;
//the position of the next to be received element in data_->front().
config::all_children_iterator next_;
//if we are processing a [turn] with multiple [command] we want to split them.
//In this case next_command_num_ is the next to be processed turn into a command otherwise it's 0;
unsigned int next_command_num_;
//a function to receive data from the network.
source_type network_reader_;
};

0 comments on commit 219f977

Please sign in to comment.