Started working on the new asio based network subsystem.
This commit is contained in:
parent
d78714487c
commit
301427f778
9 changed files with 172 additions and 12 deletions
20
SConstruct
20
SConstruct
|
@ -282,6 +282,15 @@ if env["prereqs"]:
|
|||
conf.CheckLib("m")
|
||||
conf.CheckFunc("round")
|
||||
|
||||
def CheckAsio(conf, do_check):
|
||||
if not do_check:
|
||||
return True
|
||||
if env["PLATFORM"] == 'win32':
|
||||
conf.env.Append(LIBS = ["libws2_32"])
|
||||
return conf.CheckBoost("system") and \
|
||||
conf.CheckBoost("thread") and \
|
||||
conf.CheckBoost("asio", header_only = True)
|
||||
|
||||
have_server_prereqs = \
|
||||
conf.CheckCPlusPlus(gcc_version = "3.3") and \
|
||||
conf.CheckGettextLibintl() and \
|
||||
|
@ -289,19 +298,14 @@ if env["prereqs"]:
|
|||
conf.CheckBoostIostreamsGZip() and \
|
||||
conf.CheckBoost("smart_ptr", header_only = True) and \
|
||||
conf.CheckSDL(require_version = '1.2.7') and \
|
||||
conf.CheckSDL('SDL_net') or Warning("Base prerequisites are not met.")
|
||||
if have_server_prereqs and env["use_network_ana"]:
|
||||
if env["PLATFORM"] == 'win32':
|
||||
env.Append(LIBS = ["libws2_32"])
|
||||
have_server_prereqs = \
|
||||
conf.CheckBoost("system") and \
|
||||
conf.CheckBoost("thread") and \
|
||||
conf.CheckBoost("asio", header_only = True) or Warning("Base prerequisites are not met.")
|
||||
conf.CheckSDL('SDL_net') and \
|
||||
CheckAsio(conf, env["use_network_ana"]) or Warning("Base prerequisites are not met.")
|
||||
|
||||
env = conf.Finish()
|
||||
client_env = env.Clone()
|
||||
conf = client_env.Configure(**configure_args)
|
||||
have_client_prereqs = have_server_prereqs and \
|
||||
CheckAsio(conf, not env["use_network_ana"]) and \
|
||||
conf.CheckPango("cairo") and \
|
||||
conf.CheckPKG("fontconfig") and \
|
||||
conf.CheckBoost("program_options", require_version="1.35.0") and \
|
||||
|
|
|
@ -5,6 +5,10 @@ Version 1.9.7+svn:
|
|||
* Moved Reverse Time Graphics display option to Advanced Preferences
|
||||
* Moved Scroll Tracking of Unit Actions display option to Advanced
|
||||
Preferences, renamed to Follow Unit Actions
|
||||
* Miscellaneous and bug fixes:
|
||||
* Started working on the new asio based network subsystem. boost.asio
|
||||
(along with boost.thread and boost.system) is now a dependency for
|
||||
the client no matter whether ANA is enabled.
|
||||
|
||||
Version 1.9.7:
|
||||
* Graphics:
|
||||
|
|
|
@ -524,6 +524,7 @@ set(wesnoth-main_SRC
|
|||
multiplayer_lobby.cpp
|
||||
multiplayer_ui.cpp
|
||||
multiplayer_wait.cpp
|
||||
network_asio.cpp
|
||||
pathfind/pathfind.cpp
|
||||
pathfind/teleport.cpp
|
||||
persist_context.cpp
|
||||
|
|
|
@ -381,6 +381,7 @@ wesnoth_sources = Split("""
|
|||
multiplayer_lobby.cpp
|
||||
multiplayer_ui.cpp
|
||||
multiplayer_wait.cpp
|
||||
network_asio.cpp
|
||||
pathfind/pathfind.cpp
|
||||
pathfind/teleport.cpp
|
||||
persist_context.cpp
|
||||
|
|
|
@ -1125,8 +1125,11 @@ namespace {
|
|||
|
||||
try {
|
||||
if(gui2::new_widgets) {
|
||||
gui2::tnetwork_transmission network_receive("WIP network transmission dialog");
|
||||
network_receive.show(disp.video());
|
||||
network_asio::connection connection(remote_host, lexical_cast<std::string>(remote_port));
|
||||
gui2::tnetwork_transmission network_connect(connection, "WIP network transmission dialog");
|
||||
bool result = network_connect.show(disp.video());
|
||||
if(!result)
|
||||
return;
|
||||
}
|
||||
const network::manager net_manager;
|
||||
const network::connection sock =
|
||||
|
@ -1363,6 +1366,9 @@ namespace {
|
|||
} catch(network::error& e) {
|
||||
ERR_NET << "network::error thrown during transaction with add-on server; \""<< e.message << "\"\n";
|
||||
gui2::show_error_message(disp.video(), _("Remote host disconnected."));
|
||||
} catch(const network_asio::error& e) {
|
||||
ERR_NET << "network_asio::error thrown during transaction with add-on server; \""<< e.what() << "\"\n";
|
||||
gui2::show_error_message(disp.video(), _("Remote host disconnected."));
|
||||
} catch(io_exception& e) {
|
||||
ERR_FS << "io_exception thrown while installing an addon; \"" << e.what() << "\"\n";
|
||||
gui2::show_error_message(disp.video(), _("A problem occurred when trying to create the files necessary to install this add-on."));
|
||||
|
|
|
@ -30,6 +30,14 @@ namespace gui2 {
|
|||
|
||||
REGISTER_DIALOG(network_transmission)
|
||||
|
||||
void tnetwork_transmission::pump_monitor::process(events::pump_info&)
|
||||
{
|
||||
connection_.poll();
|
||||
if(connection_.connected() && window_) {
|
||||
window_.get().set_retval(twindow::OK);
|
||||
}
|
||||
}
|
||||
|
||||
void tnetwork_transmission::pre_show(CVideo& /*video*/, twindow& window)
|
||||
{
|
||||
// ***** ***** ***** ***** Set up the widgets ***** ***** ***** *****
|
||||
|
@ -37,10 +45,13 @@ void tnetwork_transmission::pre_show(CVideo& /*video*/, twindow& window)
|
|||
find_widget<tlabel>(&window, "title", false).set_label(title_);
|
||||
}
|
||||
|
||||
pump_monitor.window_ = window;
|
||||
|
||||
}
|
||||
|
||||
void tnetwork_transmission::post_show(twindow& /*window*/)
|
||||
{
|
||||
pump_monitor.window_.reset();
|
||||
}
|
||||
|
||||
} // namespace gui2
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include "gui/dialogs/dialog.hpp"
|
||||
#include "gui/widgets/control.hpp"
|
||||
#include "network_asio.hpp"
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace gui2 {
|
||||
|
||||
|
@ -31,9 +33,20 @@ class tnetwork_transmission;
|
|||
*/
|
||||
class tnetwork_transmission : public tdialog
|
||||
{
|
||||
network_asio::connection& connection_;
|
||||
|
||||
class pump_monitor : public events::pump_monitor
|
||||
{
|
||||
network_asio::connection& connection_;
|
||||
virtual void process(events::pump_info&);
|
||||
public:
|
||||
pump_monitor(network_asio::connection& connection) : connection_(connection) {}
|
||||
|
||||
boost::optional<twindow&> window_;
|
||||
} pump_monitor;
|
||||
public:
|
||||
tnetwork_transmission(const std::string& title)
|
||||
: title_(title)
|
||||
tnetwork_transmission(network_asio::connection& connection, const std::string& title)
|
||||
: connection_(connection), pump_monitor(connection), title_(title)
|
||||
{}
|
||||
|
||||
protected:
|
||||
|
|
52
src/network_asio.cpp
Normal file
52
src/network_asio.cpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
#include "network_asio.hpp"
|
||||
#include <boost/bind.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace network_asio {
|
||||
|
||||
connection::connection(const std::string& host, const std::string& service) :
|
||||
resolver_(io_service_), socket_(io_service_), connected_(false)
|
||||
{
|
||||
resolver_.async_resolve(
|
||||
boost::asio::ip::tcp::resolver::query(host, service),
|
||||
boost::bind(&connection::handle_resolve, this, _1, _2)
|
||||
);
|
||||
}
|
||||
|
||||
void connection::handle_resolve(
|
||||
const boost::system::error_code& ec,
|
||||
resolver::iterator iterator
|
||||
)
|
||||
{
|
||||
if(ec)
|
||||
throw error(ec);
|
||||
|
||||
std::cout << iterator->endpoint().address() << '\n';
|
||||
connect(iterator);
|
||||
}
|
||||
|
||||
void connection::connect(resolver::iterator iterator)
|
||||
{
|
||||
socket_.async_connect(*iterator, boost::bind(
|
||||
&connection::handle_connect, this, _1, iterator)
|
||||
);
|
||||
}
|
||||
|
||||
void connection::handle_connect(
|
||||
const boost::system::error_code& ec,
|
||||
resolver::iterator iterator
|
||||
)
|
||||
{
|
||||
if(ec) {
|
||||
socket_.close();
|
||||
if(++iterator == resolver::iterator())
|
||||
throw error(ec);
|
||||
else
|
||||
connect(iterator);
|
||||
} else {
|
||||
std::cout << "Connected!\n";
|
||||
connected_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
68
src/network_asio.hpp
Normal file
68
src/network_asio.hpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
#ifndef NETWORK_ASIO_HPP_INCLUDED
|
||||
#define NETWORK_ASIO_HPP_INCLUDED
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include "exceptions.hpp"
|
||||
|
||||
namespace network_asio {
|
||||
|
||||
struct error : public game::error
|
||||
{
|
||||
error(const boost::system::error_code& error) : game::error(error.message()) {}
|
||||
};
|
||||
|
||||
/** A class that represents a TCP/IP connection. */
|
||||
class connection
|
||||
{
|
||||
boost::asio::io_service io_service_;
|
||||
typedef boost::asio::ip::tcp::resolver resolver;
|
||||
resolver resolver_;
|
||||
|
||||
typedef boost::asio::ip::tcp::socket socket;
|
||||
socket socket_;
|
||||
|
||||
bool connected_;
|
||||
|
||||
void handle_resolve(
|
||||
const boost::system::error_code& ec,
|
||||
resolver::iterator iterator
|
||||
);
|
||||
|
||||
void connect(resolver::iterator iterator);
|
||||
void handle_connect(
|
||||
const boost::system::error_code& ec,
|
||||
resolver::iterator iterator
|
||||
);
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param host Name of the host to connect to
|
||||
* @param service Service identifier such as "80" or "http"
|
||||
*/
|
||||
connection(const std::string& host, const std::string& service);
|
||||
|
||||
/** Handle all pending asynchonous events and return */
|
||||
std::size_t poll()
|
||||
{
|
||||
try {
|
||||
return io_service_.poll();
|
||||
} catch(const boost::system::system_error& err) {
|
||||
throw error(err.code());
|
||||
}
|
||||
}
|
||||
/** Run asio's event loop
|
||||
*
|
||||
* Handle asynchronous events blocking until all asynchronous
|
||||
* operations have finished
|
||||
*/
|
||||
void run() { io_service_.run(); }
|
||||
|
||||
bool connected() const { return connected_; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue