MP Join Game: cleaned up implementation of the recent players-choose-factions changes
This commit is contained in:
parent
a2a4dff050
commit
fa01fb14d2
4 changed files with 58 additions and 60 deletions
|
@ -51,19 +51,11 @@ faction_select::faction_select(ng::flg_manager& flg_manager, const std::string&
|
|||
, last_faction_(flg_manager.current_faction_index())
|
||||
, last_leader_(flg_manager.current_leader_index())
|
||||
, last_gender_(flg_manager.current_gender_index())
|
||||
, w_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void faction_select::cancel()
|
||||
{
|
||||
if(w_) {
|
||||
w_->set_retval(retval::CANCEL);
|
||||
}
|
||||
}
|
||||
void faction_select::pre_show(window& window)
|
||||
{
|
||||
w_ = &window;
|
||||
find_widget<label>(&window, "starting_pos", false).set_label(std::to_string(side_));
|
||||
|
||||
//
|
||||
|
|
|
@ -32,13 +32,11 @@ public:
|
|||
|
||||
DEFINE_SIMPLE_EXECUTE_WRAPPER(faction_select)
|
||||
|
||||
void cancel();
|
||||
|
||||
int get_side_num() const { return side_; }
|
||||
private:
|
||||
ng::flg_manager& flg_manager_;
|
||||
|
||||
const std::string tc_color_;
|
||||
const std::string tc_color_;
|
||||
|
||||
const int side_;
|
||||
|
||||
|
@ -46,7 +44,6 @@ private:
|
|||
|
||||
const int last_faction_, last_leader_, last_gender_;
|
||||
|
||||
gui2::window* w_;
|
||||
/** Inherited from modal_dialog, implemented by REGISTER_DIALOG. */
|
||||
virtual const std::string& window_id() const override;
|
||||
|
||||
|
|
|
@ -74,8 +74,7 @@ mp_join_game::mp_join_game(saved_game& state, mp::lobby_info& lobby_info, wesnot
|
|||
, observe_game_(observe_game)
|
||||
, stop_updates_(false)
|
||||
, player_list_(nullptr)
|
||||
, open_flg_dialog_(nullptr)
|
||||
, flg_button_callback_timer_id_(0)
|
||||
, flg_dialog_(nullptr)
|
||||
{
|
||||
set_show_even_without_video(true);
|
||||
}
|
||||
|
@ -86,10 +85,6 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -285,6 +280,7 @@ bool mp_join_game::show_flg_select(int side_num)
|
|||
if(!side_choice["allow_changes"].to_bool(true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const config& era = level_.child("era");
|
||||
if(!era) {
|
||||
ERR_MP << "no era information\n";
|
||||
|
@ -313,16 +309,20 @@ bool mp_join_game::show_flg_select(int side_num)
|
|||
const bool saved_game = level_.child("multiplayer")["savegame"].to_bool();
|
||||
|
||||
ng::flg_manager flg(era_factions, side_choice, lock_settings, use_map_settings, saved_game);
|
||||
gui2::dialogs::faction_select dlg(flg, color, side_num);
|
||||
|
||||
{
|
||||
open_flg_dialog_ = &dlg;
|
||||
utils::scope_exit se([this](){ open_flg_dialog_ = nullptr; });
|
||||
dlg.show();
|
||||
}
|
||||
// Create a new Faction Select dialog. We use a smart pointer here instead of creating
|
||||
// a new scoped object on the stack since other functions (such as network_handler())
|
||||
// need to acces the dialog object while its open.
|
||||
flg_dialog_.reset(new gui2::dialogs::faction_select(flg, color, side_num));
|
||||
|
||||
if(dlg.get_retval() != gui2::retval::OK) {
|
||||
return true;
|
||||
// Destroy the dialog object completely on scope exit.
|
||||
// Using scope_exit ensured this happens even if the dialog throws an exception.
|
||||
utils::scope_exit se([this]() { flg_dialog_.reset(); });
|
||||
|
||||
if(!flg_dialog_->show()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
config faction;
|
||||
|
@ -332,11 +332,12 @@ bool mp_join_game::show_flg_select(int side_num)
|
|||
change["faction"] = flg.current_faction()["id"];
|
||||
change["leader"] = flg.current_leader();
|
||||
change["gender"] = flg.current_gender();
|
||||
//TODO: the host cannot yet handle this and always uses the first side owned by that player.
|
||||
// TODO: the host cannot yet handle this and always uses the first side owned by that player.
|
||||
change["side_num"] = side_num;
|
||||
|
||||
network_connection_.send_data(faction);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -452,23 +453,19 @@ 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)) {
|
||||
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);
|
||||
}
|
||||
//
|
||||
// Small wrapper function in order to set the handled and halt parameters and prevent
|
||||
// crashes in case the dialog closes and the original button to which the callback was
|
||||
// bound had already been destroyed. The other use of show_flg_select doesn't need these
|
||||
// parameters, so it's easier not to declare them as function arguments.
|
||||
//
|
||||
const auto handler = [this, side_num](bool& handled, bool& halt) {
|
||||
show_flg_select(side_num);
|
||||
handled = halt = true;
|
||||
};
|
||||
connect_signal_mouse_left_click(*select_leader_button, std::bind(handler));
|
||||
}
|
||||
else {
|
||||
|
||||
connect_signal_mouse_left_click(*select_leader_button, std::bind(handler, _3, _4));
|
||||
} else {
|
||||
select_leader_button->set_visible(widget::visibility::hidden);
|
||||
}
|
||||
}
|
||||
|
@ -480,6 +477,15 @@ void mp_join_game::generate_side_list(window& window)
|
|||
}
|
||||
}
|
||||
|
||||
void mp_join_game::close_faction_select_dialog_if_open()
|
||||
{
|
||||
if(flg_dialog_) {
|
||||
if(window* w = flg_dialog_->get_window()) {
|
||||
w->set_retval(retval::CANCEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mp_join_game::network_handler(window& window)
|
||||
{
|
||||
// If the game has already started, close the dialog immediately.
|
||||
|
@ -501,20 +507,17 @@ void mp_join_game::network_handler(window& window)
|
|||
}
|
||||
|
||||
if(data["failed"].to_bool()) {
|
||||
if(open_flg_dialog_) {
|
||||
open_flg_dialog_->cancel();
|
||||
}
|
||||
close_faction_select_dialog_if_open();
|
||||
|
||||
window.set_retval(retval::CANCEL);
|
||||
} else if(data.child("start_game")) {
|
||||
if(open_flg_dialog_) {
|
||||
open_flg_dialog_->cancel();
|
||||
}
|
||||
close_faction_select_dialog_if_open();
|
||||
|
||||
level_["started"] = true;
|
||||
window.set_retval(retval::OK);
|
||||
} else if(data.child("leave_game")) {
|
||||
if(open_flg_dialog_) {
|
||||
open_flg_dialog_->cancel();
|
||||
}
|
||||
close_faction_select_dialog_if_open();
|
||||
|
||||
window.set_retval(retval::CANCEL);
|
||||
}
|
||||
|
||||
|
@ -529,10 +532,10 @@ void mp_join_game::network_handler(window& window)
|
|||
if(config& side_to_change = get_scenario().find_child("side", "side", change["side"])) {
|
||||
side_to_change.merge_with(change);
|
||||
}
|
||||
if(open_flg_dialog_ && open_flg_dialog_->get_side_num() == change["side"].to_int()) {
|
||||
open_flg_dialog_->cancel();
|
||||
}
|
||||
|
||||
if(flg_dialog_ && flg_dialog_->get_side_num() == change["side"].to_int()) {
|
||||
close_faction_select_dialog_if_open();
|
||||
}
|
||||
} else if(data.has_child("scenario") || data.has_child("snapshot") || data.child("next_scenario")) {
|
||||
level_ = first_scenario_ ? data : data.child("next_scenario");
|
||||
|
||||
|
|
|
@ -25,13 +25,10 @@ class config;
|
|||
|
||||
namespace gui2
|
||||
{
|
||||
|
||||
class tree_view_node;
|
||||
|
||||
namespace dialogs
|
||||
{
|
||||
class faction_select;
|
||||
|
||||
class mp_join_game : public modal_dialog, private plugin_executor
|
||||
{
|
||||
public:
|
||||
|
@ -57,6 +54,17 @@ private:
|
|||
|
||||
void generate_side_list(window& window);
|
||||
|
||||
/**
|
||||
* Will close the Faction Select dialog if it's open.
|
||||
*
|
||||
* This is used in @ref network_handler to dismiss the dialog if certain actions
|
||||
* occur, such as the game starting.
|
||||
*
|
||||
* @todo maybe move this to a general-purpose close() function in @ref modal_dialog
|
||||
* and @ref modeless_dialog? It could be useful.
|
||||
*/
|
||||
void close_faction_select_dialog_if_open();
|
||||
|
||||
void network_handler(window& window);
|
||||
|
||||
config& get_scenario();
|
||||
|
@ -80,9 +88,7 @@ private:
|
|||
|
||||
std::unique_ptr<player_list_helper> player_list_;
|
||||
|
||||
gui2::dialogs::faction_select* open_flg_dialog_;
|
||||
|
||||
std::size_t flg_button_callback_timer_id_;
|
||||
std::unique_ptr<class faction_select> flg_dialog_;
|
||||
};
|
||||
|
||||
} // namespace dialogs
|
||||
|
|
Loading…
Add table
Reference in a new issue