Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-02 08:58:14

0001 ////////////////////////////////////////////////////////////
0002 //
0003 // SFML - Simple and Fast Multimedia Library
0004 // Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org)
0005 //
0006 // This software is provided 'as-is', without any express or implied warranty.
0007 // In no event will the authors be held liable for any damages arising from the use of this software.
0008 //
0009 // Permission is granted to anyone to use this software for any purpose,
0010 // including commercial applications, and to alter it and redistribute it freely,
0011 // subject to the following restrictions:
0012 //
0013 // 1. The origin of this software must not be misrepresented;
0014 //    you must not claim that you wrote the original software.
0015 //    If you use this software in a product, an acknowledgment
0016 //    in the product documentation would be appreciated but is not required.
0017 //
0018 // 2. Altered source versions must be plainly marked as such,
0019 //    and must not be misrepresented as being the original software.
0020 //
0021 // 3. This notice may not be removed or altered from any source distribution.
0022 //
0023 ////////////////////////////////////////////////////////////
0024 
0025 #ifndef SFML_SOCKETSELECTOR_HPP
0026 #define SFML_SOCKETSELECTOR_HPP
0027 
0028 ////////////////////////////////////////////////////////////
0029 // Headers
0030 ////////////////////////////////////////////////////////////
0031 #include <SFML/Network/Export.hpp>
0032 #include <SFML/System/Time.hpp>
0033 
0034 
0035 namespace sf
0036 {
0037 class Socket;
0038 
0039 ////////////////////////////////////////////////////////////
0040 /// \brief Multiplexer that allows to read from multiple sockets
0041 ///
0042 ////////////////////////////////////////////////////////////
0043 class SFML_NETWORK_API SocketSelector
0044 {
0045 public:
0046 
0047     ////////////////////////////////////////////////////////////
0048     /// \brief Default constructor
0049     ///
0050     ////////////////////////////////////////////////////////////
0051     SocketSelector();
0052 
0053     ////////////////////////////////////////////////////////////
0054     /// \brief Copy constructor
0055     ///
0056     /// \param copy Instance to copy
0057     ///
0058     ////////////////////////////////////////////////////////////
0059     SocketSelector(const SocketSelector& copy);
0060 
0061     ////////////////////////////////////////////////////////////
0062     /// \brief Destructor
0063     ///
0064     ////////////////////////////////////////////////////////////
0065     ~SocketSelector();
0066 
0067     ////////////////////////////////////////////////////////////
0068     /// \brief Add a new socket to the selector
0069     ///
0070     /// This function keeps a weak reference to the socket,
0071     /// so you have to make sure that the socket is not destroyed
0072     /// while it is stored in the selector.
0073     /// This function does nothing if the socket is not valid.
0074     ///
0075     /// \param socket Reference to the socket to add
0076     ///
0077     /// \see remove, clear
0078     ///
0079     ////////////////////////////////////////////////////////////
0080     void add(Socket& socket);
0081 
0082     ////////////////////////////////////////////////////////////
0083     /// \brief Remove a socket from the selector
0084     ///
0085     /// This function doesn't destroy the socket, it simply
0086     /// removes the reference that the selector has to it.
0087     ///
0088     /// \param socket Reference to the socket to remove
0089     ///
0090     /// \see add, clear
0091     ///
0092     ////////////////////////////////////////////////////////////
0093     void remove(Socket& socket);
0094 
0095     ////////////////////////////////////////////////////////////
0096     /// \brief Remove all the sockets stored in the selector
0097     ///
0098     /// This function doesn't destroy any instance, it simply
0099     /// removes all the references that the selector has to
0100     /// external sockets.
0101     ///
0102     /// \see add, remove
0103     ///
0104     ////////////////////////////////////////////////////////////
0105     void clear();
0106 
0107     ////////////////////////////////////////////////////////////
0108     /// \brief Wait until one or more sockets are ready to receive
0109     ///
0110     /// This function returns as soon as at least one socket has
0111     /// some data available to be received. To know which sockets are
0112     /// ready, use the isReady function.
0113     /// If you use a timeout and no socket is ready before the timeout
0114     /// is over, the function returns false.
0115     ///
0116     /// \param timeout Maximum time to wait, (use Time::Zero for infinity)
0117     ///
0118     /// \return True if there are sockets ready, false otherwise
0119     ///
0120     /// \see isReady
0121     ///
0122     ////////////////////////////////////////////////////////////
0123     bool wait(Time timeout = Time::Zero);
0124 
0125     ////////////////////////////////////////////////////////////
0126     /// \brief Test a socket to know if it is ready to receive data
0127     ///
0128     /// This function must be used after a call to Wait, to know
0129     /// which sockets are ready to receive data. If a socket is
0130     /// ready, a call to receive will never block because we know
0131     /// that there is data available to read.
0132     /// Note that if this function returns true for a TcpListener,
0133     /// this means that it is ready to accept a new connection.
0134     ///
0135     /// \param socket Socket to test
0136     ///
0137     /// \return True if the socket is ready to read, false otherwise
0138     ///
0139     /// \see isReady
0140     ///
0141     ////////////////////////////////////////////////////////////
0142     bool isReady(Socket& socket) const;
0143 
0144     ////////////////////////////////////////////////////////////
0145     /// \brief Overload of assignment operator
0146     ///
0147     /// \param right Instance to assign
0148     ///
0149     /// \return Reference to self
0150     ///
0151     ////////////////////////////////////////////////////////////
0152     SocketSelector& operator =(const SocketSelector& right);
0153 
0154 private:
0155 
0156     struct SocketSelectorImpl;
0157 
0158     ////////////////////////////////////////////////////////////
0159     // Member data
0160     ////////////////////////////////////////////////////////////
0161     SocketSelectorImpl* m_impl; //!< Opaque pointer to the implementation (which requires OS-specific types)
0162 };
0163 
0164 } // namespace sf
0165 
0166 
0167 #endif // SFML_SOCKETSELECTOR_HPP
0168 
0169 
0170 ////////////////////////////////////////////////////////////
0171 /// \class sf::SocketSelector
0172 /// \ingroup network
0173 ///
0174 /// Socket selectors provide a way to wait until some data is
0175 /// available on a set of sockets, instead of just one. This
0176 /// is convenient when you have multiple sockets that may
0177 /// possibly receive data, but you don't know which one will
0178 /// be ready first. In particular, it avoids to use a thread
0179 /// for each socket; with selectors, a single thread can handle
0180 /// all the sockets.
0181 ///
0182 /// All types of sockets can be used in a selector:
0183 /// \li sf::TcpListener
0184 /// \li sf::TcpSocket
0185 /// \li sf::UdpSocket
0186 ///
0187 /// A selector doesn't store its own copies of the sockets
0188 /// (socket classes are not copyable anyway), it simply keeps
0189 /// a reference to the original sockets that you pass to the
0190 /// "add" function. Therefore, you can't use the selector as a
0191 /// socket container, you must store them outside and make sure
0192 /// that they are alive as long as they are used in the selector.
0193 ///
0194 /// Using a selector is simple:
0195 /// \li populate the selector with all the sockets that you want to observe
0196 /// \li make it wait until there is data available on any of the sockets
0197 /// \li test each socket to find out which ones are ready
0198 ///
0199 /// Usage example:
0200 /// \code
0201 /// // Create a socket to listen to new connections
0202 /// sf::TcpListener listener;
0203 /// listener.listen(55001);
0204 ///
0205 /// // Create a list to store the future clients
0206 /// std::list<sf::TcpSocket*> clients;
0207 ///
0208 /// // Create a selector
0209 /// sf::SocketSelector selector;
0210 ///
0211 /// // Add the listener to the selector
0212 /// selector.add(listener);
0213 ///
0214 /// // Endless loop that waits for new connections
0215 /// while (running)
0216 /// {
0217 ///     // Make the selector wait for data on any socket
0218 ///     if (selector.wait())
0219 ///     {
0220 ///         // Test the listener
0221 ///         if (selector.isReady(listener))
0222 ///         {
0223 ///             // The listener is ready: there is a pending connection
0224 ///             sf::TcpSocket* client = new sf::TcpSocket;
0225 ///             if (listener.accept(*client) == sf::Socket::Done)
0226 ///             {
0227 ///                 // Add the new client to the clients list
0228 ///                 clients.push_back(client);
0229 ///
0230 ///                 // Add the new client to the selector so that we will
0231 ///                 // be notified when he sends something
0232 ///                 selector.add(*client);
0233 ///             }
0234 ///             else
0235 ///             {
0236 ///                 // Error, we won't get a new connection, delete the socket
0237 ///                 delete client;
0238 ///             }
0239 ///         }
0240 ///         else
0241 ///         {
0242 ///             // The listener socket is not ready, test all other sockets (the clients)
0243 ///             for (std::list<sf::TcpSocket*>::iterator it = clients.begin(); it != clients.end(); ++it)
0244 ///             {
0245 ///                 sf::TcpSocket& client = **it;
0246 ///                 if (selector.isReady(client))
0247 ///                 {
0248 ///                     // The client has sent some data, we can receive it
0249 ///                     sf::Packet packet;
0250 ///                     if (client.receive(packet) == sf::Socket::Done)
0251 ///                     {
0252 ///                         ...
0253 ///                     }
0254 ///                 }
0255 ///             }
0256 ///         }
0257 ///     }
0258 /// }
0259 /// \endcode
0260 ///
0261 /// \see sf::Socket
0262 ///
0263 ////////////////////////////////////////////////////////////