The Battle for Wesnoth  1.15.1+dev
wesnothd_connection.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2018 by Sergey Popov <loonycyborg@gmail.com>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 #ifdef _WIN32
18 
19 #ifdef INADDR_ANY
20 #undef INADDR_ANY
21 #endif
22 
23 #ifdef INADDR_BROADCAST
24 #undef INADDR_BROADCAST
25 #endif
26 
27 #ifdef INADDR_NONE
28 #undef INADDR_NONE
29 #endif
30 
31 #endif // endif _WIN32
32 
33 #include "configr_assign.hpp"
35 
36 #include <boost/asio.hpp>
37 
38 #include <condition_variable>
39 #include <deque>
40 #include <future>
41 #include <list>
42 #include <thread>
43 #include <mutex>
44 #include <queue>
45 
46 class config;
47 enum class loading_stage;
48 
49 union data_union {
50  char binary[4];
51  uint32_t num;
52 };
53 
54 /** A class that represents a TCP/IP connection to the wesnothd server. */
56 {
57 public:
59 
61  wesnothd_connection& operator=(const wesnothd_connection&) = delete;
62 
64 
65 public:
66  /**
67  * Constructor.
68  *
69  * @param host Name of the host to connect to
70  * @param service Service identifier such as "80" or "http"
71  */
72  wesnothd_connection(const std::string& host, const std::string& service);
73 
74  bool fetch_data_with_loading_screen(config& cfg, loading_stage stage);
75 
76  void send_data(const configr_of& request);
77 
78  bool receive_data(config& result);
79 
80  /**
81  * Helper function that spins until data has been received.
82  * Should be used in tandem with the loading screen or other multi-threaded components.
83  */
84  bool wait_and_receive_data(config& data);
85 
86  void wait_for_handshake();
87 
88  void cancel();
89 
90  // Destroys this object.
91  void stop();
92 
93  std::size_t bytes_to_write() const
94  {
95  return bytes_to_write_;
96  }
97 
98  std::size_t bytes_written() const
99  {
100  return bytes_written_;
101  }
102 
103  std::size_t bytes_to_read() const
104  {
105  return bytes_to_read_;
106  }
107 
108  std::size_t bytes_read() const
109  {
110  return bytes_read_;
111  }
112 
113  bool has_data_received() const
114  {
115  return !recv_queue_.empty();
116  }
117 
118  bool is_sending_data() const
119  {
120  return !send_queue_.empty();
121  }
122 
123 private:
124  std::thread worker_thread_;
125 
126  boost::asio::io_service io_service_;
127 
128  typedef boost::asio::ip::tcp::resolver resolver;
129  resolver resolver_;
130 
131  typedef boost::asio::ip::tcp::socket socket;
132  socket socket_;
133 
134  boost::system::error_code last_error_;
135 
136  std::mutex last_error_mutex_;
137 
138  std::promise<void> handshake_finished_;
139 
140  boost::asio::streambuf read_buf_;
141 
142  void handle_resolve(const boost::system::error_code& ec, resolver::iterator iterator);
143 
144  void connect(resolver::iterator iterator);
145  void handle_connect(const boost::system::error_code& ec, resolver::iterator iterator);
146 
147  void handshake();
148  void handle_handshake(const boost::system::error_code& ec);
149 
151 
152  std::size_t is_write_complete(const boost::system::error_code& error, std::size_t bytes_transferred);
153  void handle_write(const boost::system::error_code& ec, std::size_t bytes_transferred);
154 
155  std::size_t is_read_complete(const boost::system::error_code& error, std::size_t bytes_transferred);
156  void handle_read(const boost::system::error_code& ec, std::size_t bytes_transferred);
157 
158  void send();
159  void recv();
160 
161  template<typename T>
162  using data_queue = std::queue<T, std::list<T>>;
163 
166 
167  std::mutex recv_queue_mutex_;
168 
169  std::condition_variable recv_queue_lock_;
170 
171  uint32_t payload_size_;
172 
173  // TODO: do i need to guard the following 4 values with a mutex?
174  std::size_t bytes_to_write_;
175  std::size_t bytes_written_;
176  std::size_t bytes_to_read_;
177  std::size_t bytes_read_;
178 };
179 
180 using wesnothd_connection_ptr = std::unique_ptr<wesnothd_connection>;
an error occurred inside the underlying network communication code (boost asio) TODO: find a short na...
std::condition_variable recv_queue_lock_
std::promise< void > handshake_finished_
std::unique_ptr< wesnothd_connection > wesnothd_connection_ptr
std::size_t bytes_to_write() const
boost::asio::ip::tcp::socket socket
loading_stage
Loading screen stage IDs.
data_queue< std::shared_ptr< boost::asio::streambuf > > send_queue_
std::queue< T, std::list< T > > data_queue
A class that represents a TCP/IP connection to the wesnothd server.
std::size_t bytes_read() const
void send(const std::string &, const std::string &, type)
Displays a desktop notification message, from owner, of type t.
boost::asio::streambuf read_buf_
boost::system::error_code last_error_
std::size_t bytes_to_read() const
boost::asio::io_service io_service_
std::size_t bytes_written() const
boost::asio::ip::tcp::resolver resolver
data_queue< config > recv_queue_
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:92
std::string::const_iterator iterator
Definition: tokenizer.hpp:24