mp join: fix crash when the dialog is updated while the flg dialog is 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
This commit is contained in:
gfgtdf 2018-06-28 12:10:15 +02:00
parent 2dd6557449
commit c555127552
2 changed files with 23 additions and 1 deletions

View file

@ -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"
@ -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);
}
@ -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;
}
}
/*
@ -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);

View file

@ -80,6 +80,8 @@ private:
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