Skip to content

Commit

Permalink
wait dialog for user choices during prestart events
Browse files Browse the repository at this point in the history
gna.org/bugs/?23297

If we are waiting for a synced user choice during a prestart events we
now show a gui2 dialog that informs the player about why the client is
waiting and also offers the player the option to quit the game.
  • Loading branch information
gfgtdf committed Sep 20, 2015
1 parent de3db53 commit 3ed4eed
Show file tree
Hide file tree
Showing 7 changed files with 290 additions and 4 deletions.
114 changes: 114 additions & 0 deletions data/gui/default/window/synced_choice_wait.cfg
@@ -0,0 +1,114 @@
#textdomain wesnoth-lib
###
### Definition of the window to ask for the savegame filename
###

[window]
id = "synced_choice_wait"
description = "Waiting dialogs while other players execute local choices."

[resolution]
definition = "default"

automatic_placement = "true"
vertical_placement = "center"
horizontal_placement = "center"

[tooltip]
id = "tooltip_large"
[/tooltip]

[helptip]
id = "tooltip_large"
[/helptip]

[grid]

[row]
grow_factor = 0

[column]
grow_factor = 1

border = "all"
border_size = 5
horizontal_alignment = "left"
[label]
id = "lblTitle"
definition = "title"

label = _ "Waiting..."
[/label]

[/column]

[/row]

[row]
grow_factor = 0

[column]
grow_factor = 1

border = "all"
border_size = 5
horizontal_alignment = "left"
[label]
id = "lblMessage"
definition = "default"

label = _ "Waiting for remote input"
[/label]

[/column]

[/row]

[row]
grow_factor = 0

[column]
grow_factor = 1
horizontal_grow = "true"

[grid]

[row]
grow_factor = 0

[column]

[spacer]
definition = "default"
[/spacer]

[/column]

[column]
border = "all"
border_size = 5
horizontal_alignment = "right"

[button]
id = "btn_quit_game"
definition = "default"

size_text = _ "Quit game"
label = _ "Quit game"
[/button]

[/column]

[/row]

[/grid]

[/column]

[/row]

[/grid]

[/resolution]

[/window]
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Expand Up @@ -928,6 +928,7 @@ set(wesnoth-main_SRC
gui/dialogs/edit_text.cpp
gui/dialogs/screenshot_notification.cpp
gui/dialogs/simple_item_selector.cpp
gui/dialogs/synced_choice_wait.cpp
gui/dialogs/theme_list.cpp
gui/dialogs/title_screen.cpp
gui/dialogs/transient_message.cpp
Expand Down
1 change: 1 addition & 0 deletions src/SConscript
Expand Up @@ -449,6 +449,7 @@ wesnoth_sources = Split("""
gui/dialogs/edit_text.cpp
gui/dialogs/screenshot_notification.cpp
gui/dialogs/simple_item_selector.cpp
gui/dialogs/synced_choice_wait.cpp
gui/dialogs/theme_list.cpp
gui/dialogs/tip.cpp
gui/dialogs/title_screen.cpp
Expand Down
111 changes: 111 additions & 0 deletions src/gui/dialogs/synced_choice_wait.cpp
@@ -0,0 +1,111 @@
/*
Copyright (C) 2014 - 2015 by Ignacio Riquelme Morelle <shadowm2006@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/

#include "gui/dialogs/synced_choice_wait.hpp"

#include "gui/auxiliary/find_widget.tpp"
#include "gui/widgets/label.hpp"
#include "gui/widgets/button.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/widgets/window.hpp"


#include "message.hpp"
#include "../../game_end_exceptions.hpp"
#include "../../gettext.hpp"
#include "../../resources.hpp"
#include "../../game_display.hpp"


#include <boost/bind.hpp>

namespace gui2
{

/*WIKI
* @page = GUIWindowDefinitionWML
* @order = 2_theme_list
*
* == Theme list ==
*
* Dialog for selecting a GUI theme.
*
* @begin{table}{dialog_widgets}
*
* themes & & listbox & m &
* Listbox displaying user choices. $
*
* -name & & control & m &
* Widget which shows a theme item name. $
*
* -description & & control & m &
* Widget which shows a theme item description. $
*
* @end{table}
*/

REGISTER_DIALOG(synced_choice_wait)

tsynced_choice_wait::tsynced_choice_wait(user_choice_manager& mgr)
: mgr_(mgr)
, message_()
{
mgr_.changed_event_.attach_handler(this);
}

tsynced_choice_wait::~tsynced_choice_wait()
{
mgr_.changed_event_.detach_handler(this);
}

void tsynced_choice_wait::pre_show(CVideo& /*video*/, twindow& window)
{
window_ = &window;
message_ = find_widget<tlabel>(&window, "lblMessage", false, true);


tbutton& quit_button = find_widget<tbutton>(
&window, "btn_quit_game", false);

connect_signal_mouse_left_click(
quit_button,
boost::bind(&tsynced_choice_wait::on_btn_quit_game, this)
);

message_->set_label(mgr_.wait_message());
if(mgr_.finished() || !mgr_.waiting()) {
window_->close();
}
}

void tsynced_choice_wait::handle_generic_event(const std::string& event_name)
{
assert(event_name == "user_choice_update");
assert(message_);
message_->set_label(mgr_.wait_message());
if(mgr_.finished() || !mgr_.waiting()) {
window_->close();
}
}

void tsynced_choice_wait::on_btn_quit_game()
{
const int res = gui2::show_message(resources::screen->video(), _("Quit"),
_("Do you really want to quit?"), gui2::tmessage::yes_no_buttons);
if (res != gui2::twindow::CANCEL) {
throw_quit_game_exception();
}
}

}
45 changes: 45 additions & 0 deletions src/gui/dialogs/synced_choice_wait.hpp
@@ -0,0 +1,45 @@
/*
Copyright (C) 2014 - 2015 by Ignacio Riquelme Morelle <shadowm2006@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/

#ifndef GUI_DIALOGS_THEME_LIST_HPP_INCLUDED
#define GUI_DIALOGS_THEME_LIST_HPP_INCLUDED

#include "gui/dialogs/dialog.hpp"
#include "../../synced_user_choice.hpp"
#include "../../generic_event.hpp"
namespace gui2
{
class tlabel;
class twindow;
class tsynced_choice_wait : public tdialog, public events::observer
{
public:
explicit tsynced_choice_wait(user_choice_manager& mgr);
~tsynced_choice_wait();
private:
user_choice_manager& mgr_;
tlabel* message_;
twindow* window_;
/** Inherited from tdialog, implemented by REGISTER_DIALOG. */
virtual const std::string& window_id() const;

/** Inherited from tdialog. */
void pre_show(CVideo& video, twindow& window);

virtual void handle_generic_event(const std::string& event_name);
void on_btn_quit_game();
};
}

#endif
21 changes: 17 additions & 4 deletions src/synced_user_choice.cpp
Expand Up @@ -25,7 +25,7 @@
#include "synced_context.hpp"
#include "replay.hpp"
#include "resources.hpp"

#include "gui/dialogs/synced_choice_wait.hpp"
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <set>
Expand Down Expand Up @@ -296,10 +296,8 @@ void user_choice_manager::pull()
synced_context::pull_remote_user_input();
do_replay_handle();
update_local_choice();
bool is_replay_end = resources::recorder->at_end();
if(!resources::recorder->at_end())
{
changed_event_.notify_observers();
DBG_REPLAY << "MP synchronization: extracting choice from replay with has_local_side=" << has_local_choice() << "\n";

const config *action = resources::recorder->get_next_action();
Expand All @@ -311,6 +309,8 @@ void user_choice_manager::pull()
resources::recorder->revert_action();
// execute this local choice locally
oos_ = true;
changed_event_.notify_observers();
return;
}
int from_side = (*action)["from_side"].to_int(0);
if((*action)["side_invalid"].to_bool(false) == true)
Expand All @@ -327,6 +327,7 @@ void user_choice_manager::pull()
replay::process_error("MP synchronization: we got already our answer from side " + boost::lexical_cast<std::string>(from_side) + "for [" + tagname_ + "] now we have it twice.\n");
}
res_[from_side] = action->child(tagname_);
changed_event_.notify_observers();
}
}

Expand Down Expand Up @@ -421,14 +422,26 @@ static void wait_ingame(user_choice_manager& man)
}
}

static void wait_prestart(user_choice_manager& man)
{
gui2::tsynced_choice_wait scw(man);
scw.show(resources::screen->video());
}

std::map<int, config> user_choice_manager::get_user_choice_internal(const std::string &name, const mp_sync::user_choice &uch, const std::set<int>& sides)
{
const bool is_too_early = resources::gamedata->phase() != game_data::START && resources::gamedata->phase() != game_data::PLAY;
user_choice_manager man(name, uch, sides);
while(!man.finished())
{
if(man.waiting())
{
wait_ingame(man);
if(is_too_early) {
wait_prestart(man);
}
else {
wait_ingame(man);
}
}
else if(man.has_local_choice())
{
Expand Down
1 change: 1 addition & 0 deletions src/tests/gui/test_gui2.cpp
Expand Up @@ -475,6 +475,7 @@ BOOST_AUTO_TEST_CASE(test_gui2)
list.erase(std::remove(list.begin(), list.end(), "addon_filter_options"), list.end());
list.erase(std::remove(list.begin(), list.end(), "addon_uninstall_list"), list.end());
list.erase(std::remove(list.begin(), list.end(), "network_transmission"), list.end());
list.erase(std::remove(list.begin(), list.end(), "synced_choice_wait"), list.end());

// Test size() instead of empty() to get the number of offenders
BOOST_CHECK_EQUAL(list.size(), 0);
Expand Down

0 comments on commit 3ed4eed

Please sign in to comment.