Skip to content

Commit

Permalink
mp join: fix crash when the dialog is updated while the flg dialog is…
Browse files Browse the repository at this point in the history
… open.

we cannnot call show_flg_select from inside the select_leader_buttons callback because that select_leader_buttons might be deleted/recreated while that dialog is open whihc leads to crashes, so what we do is executing the show_flg_select
 in a seperate callstack by using a 0 ms non-repeating timer
  • Loading branch information
gfgtdf committed Jun 29, 2018
1 parent b8a119d commit 75e0d08
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
22 changes: 21 additions & 1 deletion src/gui/dialogs/multiplayer/mp_join_game.cpp
Expand Up @@ -25,6 +25,7 @@
#include "preferences/credentials.hpp"
#include "gettext.hpp"
#include "gui/auxiliary/find_widget.hpp"
#include "gui/core/timer.hpp"
#include "gui/dialogs/loading_screen.hpp"
#include "gui/dialogs/multiplayer/faction_select.hpp"
#include "gui/dialogs/transient_message.hpp"
Expand Down Expand Up @@ -74,6 +75,7 @@ mp_join_game::mp_join_game(saved_game& state, mp::lobby_info& lobby_info, wesnot
, stop_updates_(false)
, player_list_(nullptr)
, open_flg_dialog_(nullptr)
, flg_button_callback_timer_id_(0)
{
set_show_even_without_video(true);
}
Expand All @@ -84,6 +86,10 @@ mp_join_game::~mp_join_game()
remove_timer(update_timer_);
update_timer_ = 0;
}
if(flg_button_callback_timer_id_ != 0) {
remove_timer(flg_button_callback_timer_id_);
flg_button_callback_timer_id_ = 0;
}
}

/*
Expand Down Expand Up @@ -491,7 +497,21 @@ void mp_join_game::generate_side_list(window& window)
auto* select_leader_button = find_widget<button>(&row_grid, "select_leader", false, false);
if(select_leader_button) {
if(side["player_id"] == preferences::login() && side["allow_changes"].to_bool(true)) {
connect_signal_mouse_left_click(*select_leader_button, std::bind(&mp_join_game::show_flg_select, this, side_num));
auto handler = [this, side_num](){
if(flg_button_callback_timer_id_ != 0) {
remove_timer(flg_button_callback_timer_id_);
flg_button_callback_timer_id_ = 0;
}
if(flg_button_callback_timer_id_ == 0) {
auto real_handler = [this, side_num](size_t /*timer_id*/ ) {
show_flg_select(side_num);
//we cannot remoe the timer here as we are currently executing the timers handler.
};
//don't call this now but in a seperate callstack since the widget might be recreates while the dialog is open.
flg_button_callback_timer_id_ = add_timer(0, real_handler, /*repeat=*/false);
}
};
connect_signal_mouse_left_click(*select_leader_button, std::bind(handler));
}
else {
select_leader_button->set_visible(widget::visibility::hidden);
Expand Down
2 changes: 2 additions & 0 deletions src/gui/dialogs/multiplayer/mp_join_game.hpp
Expand Up @@ -81,6 +81,8 @@ class mp_join_game : public modal_dialog, private plugin_executor
std::unique_ptr<player_list_helper> player_list_;

gui2::dialogs::faction_select* open_flg_dialog_;

std::size_t flg_button_callback_timer_id_;
};

} // namespace dialogs
Expand Down

0 comments on commit 75e0d08

Please sign in to comment.