SFML/DSFML/import/dsfml/network/selector.d

188 lines
5.8 KiB
D

/*
* DSFML - SFML Library binding in D language.
* Copyright (C) 2008 Julien Dagorn (sirjulio13@gmail.com)
*
* This software is provided 'as-is', without any express or
* implied warranty. In no event will the authors be held
* liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute
* it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented;
* you must not claim that you wrote the original software.
* If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but
* is not required.
*
* 2. Altered source versions must be plainly marked as such,
* and must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any
* source distribution.
*/
module dsfml.network.selector;
import dsfml.network.sockettcp;
import dsfml.network.socketudp;
import dsfml.system.common;
/**
* Selector TCP allow reading from multiple sockets
* without blocking. It's a kind of multiplexer. Use SocketTCP or
* SocketUDP aliases.
*/
class Selector(T) : DSFMLObject
{
//Ensure type is correct
static if (!is(T : SocketTCP) && !is(T : SocketUDP))
static assert("Only SocketTCP and SocketUDP are valid for Selector.");
/**
* Default constructor
*/
this()
{
super(sfSelector_Create());
}
override void dispose()
{
sfSelector_Destroy(m_ptr);
}
/**
* Add a socket to watch
*
* Params:
* socket = A tcp or udp socket
*/
void add(T socket)
{
if (!(socket.getNativePointer in m_watchedSockets))
{
sfSelector_Add(m_ptr, socket.getNativePointer);
m_watchedSockets[socket.getNativePointer] = socket;
m_numSocketsWatched++;
}
}
/**
* Remove a previously added socket
*
* Params:
* socket = A tcp or udp socket
*/
void remove(T socket)
{
if (socket.getNativePointer in m_watchedSockets)
{
sfSelector_Remove(m_ptr, socket.getNativePointer);
m_watchedSockets.remove(socket.getNativePointer);
m_numSocketsWatched--;
}
}
/**
* Clear all sockets being watched
*/
void clear()
{
sfSelector_Clear(m_ptr);
foreach(key; m_watchedSockets.keys)
m_watchedSockets.remove(key);
m_numSocketsWatched = 0;
}
/**
* Wait and collect sockets which are ready for reading.
* This functions will return either when at least one socket
* is ready, or when the given time is out
*
* Params:
* timeout = Maximum time to wait, in seconds (0 to disable timeout)
*
* Returns:
* Number of sockets ready
*/
uint wait(float timeout = 0.f)
{
return sfSelector_Wait(m_ptr, timeout);
}
/**
* After a call to Wait(), get the Index-th socket which is
* ready for reading. The total number of sockets ready
* is the integer returned by the previous call to Wait()
*
* Params:
* index = Index of the socket to get
*
* Returns:
* The Index-th socket
*/
T GetSocketsReady(uint index)
{
return m_watchedSockets[sfSelector_GetSocketReady(m_ptr, index)];
}
private:
size_t m_numSocketsWatched;
T[void*] m_watchedSockets;
// External ====================================================================
extern (C)
{
typedef void* function() pf_sfSelector_Create;
typedef void function(void*) pf_sfSelector_Destroy;
typedef void function(void*, void*) pf_sfSelector_Add;
typedef void function(void*, void*) pf_sfSelector_Remove;
typedef void function(void*) pf_sfSelector_Clear;
typedef uint function(void*, float) pf_sfSelector_Wait;
typedef void* function(void*, uint) pf_sfSelector_GetSocketReady;
static pf_sfSelector_Create sfSelector_Create;
static pf_sfSelector_Destroy sfSelector_Destroy;
static pf_sfSelector_Add sfSelector_Add;
static pf_sfSelector_Remove sfSelector_Remove;
static pf_sfSelector_Clear sfSelector_Clear;
static pf_sfSelector_Wait sfSelector_Wait;
static pf_sfSelector_GetSocketReady sfSelector_GetSocketReady;
}
static this()
{
DllLoader dll = DllLoader.load("csfml-network");
static if (is (T : SocketTCP))
{
char[] symbol = "sfSelectorTCP";
}
else static if (is (T : SocketUDP))
{
char[] symbol = "sfSelectorUDP";
}
sfSelector_Add = cast(pf_sfSelector_Add)dll.getSymbol(symbol ~ "_Add");
sfSelector_Clear = cast(pf_sfSelector_Clear)dll.getSymbol(symbol ~ "_Clear");
sfSelector_Create = cast(pf_sfSelector_Create)dll.getSymbol(symbol ~ "_Create");
sfSelector_Destroy = cast(pf_sfSelector_Destroy)dll.getSymbol(symbol ~ "_Destroy");
sfSelector_GetSocketReady = cast(pf_sfSelector_GetSocketReady)dll.getSymbol(symbol ~ "_GetSocketReady");
sfSelector_Wait = cast(pf_sfSelector_Wait)dll.getSymbol(symbol ~ "_Wait");
sfSelector_Remove = cast(pf_sfSelector_Remove)dll.getSymbol(symbol ~ "_Remove");
}
}
/**
* alias of selector for TCP or UDP Socket.
*/
alias Selector!(SocketTCP) SelectorTCP;
/// ditto
alias Selector!(SocketUDP) SelectorUDP;