414a941859c474fbf382fed5acbcb67ef0bfcc06
[TDDC76_proj.git] /
1 ////////////////////////////////////////////////////////////
2 //
3 // SFML - Simple and Fast Multimedia Library
4 // Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com)
5 //
6 // This software is provided 'as-is', without any express or implied warranty.
7 // In no event will the authors be held liable for any damages arising from the use of this software.
8 //
9 // Permission is granted to anyone to use this software for any purpose,
10 // including commercial applications, and to alter it and redistribute it freely,
11 // subject to the following restrictions:
12 //
13 // 1. The origin of this software must not be misrepresented;
14 // you must not claim that you wrote the original software.
15 // If you use this software in a product, an acknowledgment
16 // in the product documentation would be appreciated but is not required.
17 //
18 // 2. Altered source versions must be plainly marked as such,
19 // and must not be misrepresented as being the original software.
20 //
21 // 3. This notice may not be removed or altered from any source distribution.
22 //
23 ////////////////////////////////////////////////////////////
24
25 #ifndef SFML_SOCKETSELECTOR_HPP
26 #define SFML_SOCKETSELECTOR_HPP
27
28 ////////////////////////////////////////////////////////////
29 // Headers
30 ////////////////////////////////////////////////////////////
31 #include <SFML/Network/Export.hpp>
32 #include <SFML/System/Time.hpp>
33
34
35 namespace sf
36 {
37 class Socket;
38
39 ////////////////////////////////////////////////////////////
40 /// \brief Multiplexer that allows to read from multiple sockets
41 ///
42 ////////////////////////////////////////////////////////////
43 class SFML_NETWORK_API SocketSelector
44 {
45 public :
46
47 ////////////////////////////////////////////////////////////
48 /// \brief Default constructor
49 ///
50 ////////////////////////////////////////////////////////////
51 SocketSelector();
52
53 ////////////////////////////////////////////////////////////
54 /// \brief Copy constructor
55 ///
56 /// \param copy Instance to copy
57 ///
58 ////////////////////////////////////////////////////////////
59 SocketSelector(const SocketSelector& copy);
60
61 ////////////////////////////////////////////////////////////
62 /// \brief Destructor
63 ///
64 ////////////////////////////////////////////////////////////
65 ~SocketSelector();
66
67 ////////////////////////////////////////////////////////////
68 /// \brief Add a new socket to the selector
69 ///
70 /// This function keeps a weak reference to the socket,
71 /// so you have to make sure that the socket is not destroyed
72 /// while it is stored in the selector.
73 /// This function does nothing if the socket is not valid.
74 ///
75 /// \param socket Reference to the socket to add
76 ///
77 /// \see remove, clear
78 ///
79 ////////////////////////////////////////////////////////////
80 void add(Socket& socket);
81
82 ////////////////////////////////////////////////////////////
83 /// \brief Remove a socket from the selector
84 ///
85 /// This function doesn't destroy the socket, it simply
86 /// removes the reference that the selector has to it.
87 ///
88 /// \param socket Reference to the socket to remove
89 ///
90 /// \see add, clear
91 ///
92 ////////////////////////////////////////////////////////////
93 void remove(Socket& socket);
94
95 ////////////////////////////////////////////////////////////
96 /// \brief Remove all the sockets stored in the selector
97 ///
98 /// This function doesn't destroy any instance, it simply
99 /// removes all the references that the selector has to
100 /// external sockets.
101 ///
102 /// \see add, remove
103 ///
104 ////////////////////////////////////////////////////////////
105 void clear();
106
107 ////////////////////////////////////////////////////////////
108 /// \brief Wait until one or more sockets are ready to receive
109 ///
110 /// This function returns as soon as at least one socket has
111 /// some data available to be received. To know which sockets are
112 /// ready, use the isReady function.
113 /// If you use a timeout and no socket is ready before the timeout
114 /// is over, the function returns false.
115 ///
116 /// \param timeout Maximum time to wait, (use Time::Zero for infinity)
117 ///
118 /// \return True if there are sockets ready, false otherwise
119 ///
120 /// \see isReady
121 ///
122 ////////////////////////////////////////////////////////////
123 bool wait(Time timeout = Time::Zero);
124
125 ////////////////////////////////////////////////////////////
126 /// \brief Test a socket to know if it is ready to receive data
127 ///
128 /// This function must be used after a call to Wait, to know
129 /// which sockets are ready to receive data. If a socket is
130 /// ready, a call to receive will never block because we know
131 /// that there is data available to read.
132 /// Note that if this function returns true for a TcpListener,
133 /// this means that it is ready to accept a new connection.
134 ///
135 /// \param socket Socket to test
136 ///
137 /// \return True if the socket is ready to read, false otherwise
138 ///
139 /// \see isReady
140 ///
141 ////////////////////////////////////////////////////////////
142 bool isReady(Socket& socket) const;
143
144 ////////////////////////////////////////////////////////////
145 /// \brief Overload of assignment operator
146 ///
147 /// \param right Instance to assign
148 ///
149 /// \return Reference to self
150 ///
151 ////////////////////////////////////////////////////////////
152 SocketSelector& operator =(const SocketSelector& right);
153
154 private :
155
156 struct SocketSelectorImpl;
157
158 ////////////////////////////////////////////////////////////
159 // Member data
160 ////////////////////////////////////////////////////////////
161 SocketSelectorImpl* m_impl; ///< Opaque pointer to the implementation (which requires OS-specific types)
162 };
163
164 } // namespace sf
165
166
167 #endif // SFML_SOCKETSELECTOR_HPP
168
169
170 ////////////////////////////////////////////////////////////
171 /// \class sf::SocketSelector
172 /// \ingroup network
173 ///
174 /// Socket selectors provide a way to wait until some data is
175 /// available on a set of sockets, instead of just one. This
176 /// is convenient when you have multiple sockets that may
177 /// possibly receive data, but you don't know which one will
178 /// be ready first. In particular, it avoids to use a thread
179 /// for each socket; with selectors, a single thread can handle
180 /// all the sockets.
181 ///
182 /// All types of sockets can be used in a selector:
183 /// \li sf::TcpListener
184 /// \li sf::TcpSocket
185 /// \li sf::UdpSocket
186 ///
187 /// A selector doesn't store its own copies of the sockets
188 /// (socket classes are not copyable anyway), it simply keeps
189 /// a reference to the original sockets that you pass to the
190 /// "add" function. Therefore, you can't use the selector as a
191 /// socket container, you must store them oustide and make sure
192 /// that they are alive as long as they are used in the selector.
193 ///
194 /// Using a selector is simple:
195 /// \li populate the selector with all the sockets that you want to observe
196 /// \li make it wait until there is data available on any of the sockets
197 /// \li test each socket to find out which ones are ready
198 ///
199 /// Usage example:
200 /// \code
201 /// // Create a socket to listen to new connections
202 /// sf::TcpListener listener;
203 /// listener.listen(55001);
204 ///
205 /// // Create a list to store the future clients
206 /// std::list<sf::TcpSocket*> clients;
207 ///
208 /// // Create a selector
209 /// sf::SocketSelector selector;
210 ///
211 /// // Add the listener to the selector
212 /// selector.add(listener);
213 ///
214 /// // Endless loop that waits for new connections
215 /// while (running)
216 /// {
217 /// // Make the selector wait for data on any socket
218 /// if (selector.wait())
219 /// {
220 /// // Test the listener
221 /// if (selector.isReady(listener))
222 /// {
223 /// // The listener is ready: there is a pending connection
224 /// sf::TcpSocket* client = new sf::TcpSocket;
225 /// if (listener.accept(*client) == sf::Socket::Done)
226 /// {
227 /// // Add the new client to the clients list
228 /// clients.push_back(client);
229 ///
230 /// // Add the new client to the selector so that we will
231 /// // be notified when he sends something
232 /// selector.add(*client);
233 /// }
234 /// else
235 /// {
236 /// // Error, we won't get a new connection, delete the socket
237 /// delete client;
238 /// }
239 /// }
240 /// else
241 /// {
242 /// // The listener socket is not ready, test all other sockets (the clients)
243 /// for (std::list<sf::TcpSocket*>::iterator it = clients.begin(); it != clients.end(); ++it)
244 /// {
245 /// sf::TcpSocket& client = **it;
246 /// if (selector.isReady(client))
247 /// {
248 /// // The client has sent some data, we can receive it
249 /// sf::Packet packet;
250 /// if (client.receive(packet) == sf::Socket::Done)
251 /// {
252 /// ...
253 /// }
254 /// }
255 /// }
256 /// }
257 /// }
258 /// }
259 /// \endcode
260 ///
261 /// \see sf::Socket
262 ///
263 ////////////////////////////////////////////////////////////