Refactor general-purpose fetch-server-data-with-loading-screen functions

This fully splits the wesnothd loading screen handling from the network_transmission dialog and
into wesnothd_connection. Much cleaner this way. I've also added wait_and_receive_data as a general
spin-and-wait-for-data-to-come-in function instead of having it local in open_connection.
This commit is contained in:
Charles Dang 2017-11-07 20:32:36 +11:00
parent e07a32e658
commit d7302d684d
7 changed files with 52 additions and 65 deletions

View file

@ -95,14 +95,6 @@ wesnothd_connection_ptr open_connection(CVideo& video, std::string host)
gui2::dialogs::loading_screen::progress(loading_stage::waiting);
const auto wait_for_server_to_send_data = [&sock, &data]() {
while(!sock->has_data_received()) {
SDL_Delay(1);
}
sock->receive_data(data);
};
// Then, log in and wait for the lobby/game join prompt.
do {
if(!sock) {
@ -110,7 +102,7 @@ wesnothd_connection_ptr open_connection(CVideo& video, std::string host)
}
data.clear();
wait_for_server_to_send_data();
sock->wait_and_receive_data(data);
if(data.has_child("reject") || data.has_attribute("version")) {
std::string version;
@ -184,7 +176,7 @@ wesnothd_connection_ptr open_connection(CVideo& video, std::string host)
}
sock->send_data(response);
wait_for_server_to_send_data();
sock->wait_and_receive_data(data);
gui2::dialogs::loading_screen::progress(loading_stage::login_response);
@ -262,7 +254,7 @@ wesnothd_connection_ptr open_connection(CVideo& video, std::string host)
// Once again send our request...
sock->send_data(response);
wait_for_server_to_send_data();
sock->wait_and_receive_data(data);
gui2::dialogs::loading_screen::progress(loading_stage::login_response);

View file

@ -25,8 +25,8 @@
#include "gettext.hpp"
#include "gui/auxiliary/find_widget.hpp"
#include "gui/dialogs/helper.hpp"
#include "gui/dialogs/loading_screen.hpp"
#include "gui/dialogs/multiplayer/faction_select.hpp"
#include "gui/dialogs/network_transmission.hpp"
#include "gui/dialogs/transient_message.hpp"
#include "gui/widgets/button.hpp"
#include "gui/widgets/chatbox.hpp"
@ -97,8 +97,8 @@ bool mp_join_game::fetch_game_config(CVideo& video)
bool has_scenario_and_controllers = false;
while(!has_scenario_and_controllers) {
config revc;
const bool data_res = gui2::dialogs::network_transmission::wesnothd_receive_dialog(
video, loading_stage::download_level_data, revc, network_connection_);
const bool data_res =
network_connection_.fetch_data_with_loading_screen(revc, loading_stage::download_level_data);
if(!data_res) {
return false;

View file

@ -23,7 +23,6 @@
#include "gui/widgets/progress_bar.hpp"
#include "gui/widgets/label.hpp"
#include "gui/widgets/settings.hpp"
#include "gui/dialogs/loading_screen.hpp"
#include "gui/widgets/window.hpp"
#include "log.hpp"
#include "serialization/string_utils.hpp"
@ -99,43 +98,5 @@ void network_transmission::post_show(window& /*window*/)
connection_->cancel();
}
void network_transmission::wesnothd_dialog(CVideo& video, network_transmission::connection_data& conn, loading_stage stage)
{
if (video.faked()) {
while (!conn.finished()) {
conn.poll();
SDL_Delay(1);
}
}
else {
loading_screen::display(video, [&]() {
loading_screen::progress(stage);
while(!conn.finished()) {
conn.poll();
SDL_Delay(1);
}
});
}
}
struct read_wesnothd_connection_data : public network_transmission::connection_data
{
read_wesnothd_connection_data(wesnothd_connection& conn) : conn_(conn) {}
size_t total() override { return conn_.bytes_to_read(); }
virtual size_t current() override { return conn_.bytes_read(); }
virtual bool finished() override { return conn_.has_data_received(); }
virtual void cancel() override { }
virtual void poll() override { }
wesnothd_connection& conn_;
};
bool network_transmission::wesnothd_receive_dialog(CVideo& video, loading_stage stage, config& cfg, wesnothd_connection& connection)
{
assert(stage != loading_stage::none);
read_wesnothd_connection_data gui_data(connection);
wesnothd_dialog(video, gui_data, stage);
return connection.receive_data(cfg);
}
} // namespace dialogs
} // namespace gui2

View file

@ -15,7 +15,6 @@
#pragma once
#include "events.hpp"
#include "gui/dialogs/loading_screen.hpp"
#include "gui/dialogs/modal_dialog.hpp"
#include "network_asio.hpp"
#include "wesnothd_connection.hpp"
@ -36,7 +35,7 @@ namespace dialogs
class network_transmission : public modal_dialog
{
public:
//A wrapper of either a wesnothd_connection or a network_asio::connection
/** A wrapper of either a wesnothd_connection or a network_asio::connection. */
class connection_data
{
public:
@ -48,10 +47,7 @@ public:
virtual ~connection_data() {}
};
static bool wesnothd_receive_dialog(CVideo& video, loading_stage stage, config& cfg, wesnothd_connection& connection);
private:
static void wesnothd_dialog(CVideo& video, connection_data& conn, loading_stage stage);
connection_data* connection_;
class pump_monitor : public events::pump_monitor

View file

@ -18,7 +18,7 @@
#include "actions/undo.hpp"
#include "display_chat_manager.hpp"
#include "game_end_exceptions.hpp"
#include "gui/dialogs/network_transmission.hpp"
#include "gui/dialogs/loading_screen.hpp"
#include "gettext.hpp"
#include "hotkey/hotkey_handler_mp.hpp"
#include "log.hpp"
@ -287,8 +287,8 @@ void playmp_controller::wait_for_upload()
network_reader_.set_source(playturn_network_adapter::get_source_from_config(cfg));
while(true) {
try {
const bool res = gui2::dialogs::network_transmission::wesnothd_receive_dialog(
gui_->video(), loading_stage::next_scenario, cfg, mp_info_->connection);
const bool res =
mp_info_->connection.fetch_data_with_loading_screen(cfg, loading_stage::next_scenario);
if(res) {
if (turn_data_.process_network_data_from_reader() == turn_info::PROCESS_END_LINGER) {

View file

@ -12,14 +12,19 @@
See the COPYING file for more details.
*/
#include <deque>
#include "utils/functional.hpp"
#include <cstdint>
#include "log.hpp"
#include "wesnothd_connection.hpp"
#include "gui/dialogs/loading_screen.hpp"
#include "log.hpp"
#include "serialization/parser.hpp"
#include "utils/functional.hpp"
#include "video.hpp"
#include <boost/thread.hpp>
#include <SDL_timer.h>
#include <cstdint>
#include <deque>
static lg::log_domain log_network("network");
#define DBG_NW LOG_STREAM(debug, log_network)
@ -374,6 +379,30 @@ bool wesnothd_connection::receive_data(config& result)
return false;
}
bool wesnothd_connection::wait_and_receive_data(config& data)
{
while(!has_data_received()) {
SDL_Delay(1);
}
return receive_data(data);
};
bool wesnothd_connection::fetch_data_with_loading_screen(config& cfg, loading_stage stage)
{
assert(stage != loading_stage::none);
bool res = false;
gui2::dialogs::loading_screen::display(CVideo::get_singleton(), [&]() {
gui2::dialogs::loading_screen::progress(stage);
res = wait_and_receive_data(cfg);
});
return res;
}
wesnothd_connection::~wesnothd_connection()
{
MPTEST_LOG;

View file

@ -42,6 +42,7 @@ namespace boost
class config;
class wesnothd_connection_ptr;
enum class loading_stage;
/** A class that represents a TCP/IP connection to the wesnothd server. */
class wesnothd_connection : public std::enable_shared_from_this<wesnothd_connection>
@ -64,10 +65,18 @@ private:
public:
static wesnothd_connection_ptr create(const std::string& host, const std::string& service);
bool fetch_data_with_loading_screen(config& cfg, loading_stage stage);
void send_data(const configr_of& request);
bool receive_data(config& result);
/**
* Helper function that spins until data has been received.
* Should be used in tandem with the loading screen or other multi-threaded components.
*/
bool wait_and_receive_data(config& data);
/** Handle all pending asynchonous events and return */
std::size_t poll();
/** Run asio's event loop