1 /// Provides the ReceivedPacket struct and the Packet class.
2 
3 module gfm.enet.peer;
4 
5 import derelict.enet.enet;
6 import gfm.enet.enet;
7 import gfm.enet.packet;
8 
9 struct ReceivedPacket
10 {
11     Packet packet;
12     ubyte channelID;
13 }
14 
15 /// Encompasses an ENetPeer with an object-oriented wrapper.
16 final class Peer
17 {
18     private ENet _enet;
19     private ENetPeer *_handle;
20 
21     this(ENet enet, ENetPeer *handle)
22     {
23         _enet = enet;
24         _handle = handle;
25     }
26 
27     /// Queues a Packet's internal ENetPacket to be sent. Dirties the sent
28     /// packet, meaning it cannot be changed.
29     /// Throws: ENetException if enet_peer_send fails
30     void send(Packet packet, ubyte channelID=0)
31     {
32         auto errCode = enet_peer_send(_handle, channelID, packet._handle);
33         if(errCode < 0)
34             throw new ENetException("enet_peer_send failed");
35         packet._dirty = true;
36     }
37 
38     /** 
39      * Attempts to dequeue any incoming queued packet.
40      * Returns: A ReceivedPacket struct, with packet member being null if no
41      *          packet is received.
42      */
43     ReceivedPacket receive()
44     {
45         ubyte channelID;
46         ENetPacket *packet = enet_peer_receive(_handle, &channelID);
47         Packet wrappedPacket = new Packet(_enet, packet);
48         return ReceivedPacket(wrappedPacket, channelID);
49     }
50 
51     /// Forcefully disconnects a peer.
52     void reset()
53     {
54         enet_peer_reset(_handle);
55     }
56 
57     /// Request a disconnection from a peer.
58     void disconnect(uint data=0)
59     {
60         enet_peer_disconnect(_handle, data);
61     }
62 
63     /// Force an immediate disconnection from a peer
64     void disconnectNow(uint data=0)
65     {
66         enet_peer_disconnect_now(_handle, data);
67     }
68 
69     /// Request a disconnection from a peer, but only after all queued
70     /// outgoing packets are sent.
71     void disconnectLater(uint data=0)
72     {
73         enet_peer_disconnect_later(_handle, data);
74     }
75 
76     /// Sends a ping request to a peer.
77     void ping()
78     {
79         enet_peer_ping(_handle);
80     }
81 
82     /// Sets the timeout parameters for a peer.
83     void setTimeout(uint limit, uint min, uint max)
84     {
85         enet_peer_timeout(_handle, limit, min, max);
86     }
87 
88     /// Sets the throttle parameters for a peer. The throttle represents a
89     /// probability that an unreliable packet should not be dropped and thus
90     /// sent by ENet to the peer.
91     void throttleConfigure(uint interval, uint accel, uint decel)
92     {
93         enet_peer_throttle_configure(_handle, interval, accel, decel);
94     }
95 
96     // Todo: Add all
97     /// Trivial getters for _ENetPeer struct.    
98     ENetAddress address() pure const nothrow
99     { 
100         return _handle.address; 
101     }
102 
103     size_t channelCount() pure const nothrow
104     { 
105         return _handle.channelCount; 
106     }
107 
108     uint incomingBandwidth() pure const nothrow
109     { 
110         return _handle.incomingBandwidth; 
111     }
112 
113     uint outgoingBandwidth() pure const nothrow
114     { 
115         return _handle.outgoingBandwidth; 
116     }
117 
118     uint packetLoss() pure const nothrow
119     { 
120         return _handle.packetLoss; 
121     }
122 
123     uint roundTripTime() pure const nothrow
124     { 
125         return _handle.roundTripTime; 
126     }
127 
128     ENetPeerState state() pure const nothrow
129     { 
130         return _handle.state; 
131     }
132 }