1use std;
2use enum_primitive_derive::Primitive;
3use num_traits;
4
5use ll;
6use crate::{host, Address, Packet};
7
8#[expect(clippy::unnecessary_cast)] pub const PACKET_LOSS_SCALE : u32 = ll::ENET_PEER_PACKET_LOSS_SCALE as u32;
11
12#[derive(Clone, Debug, PartialEq)]
41pub struct Peer {
42 raw : *mut ll::ENetPeer,
43 hostdrop : std::rc::Rc <host::HostDrop>
44}
45
46#[derive(Copy, Clone, Debug, Eq, PartialEq, Primitive)]
51pub enum State {
52 Disconnected = ll::_ENetPeerState_ENET_PEER_STATE_DISCONNECTED as isize,
53 Connecting = ll::_ENetPeerState_ENET_PEER_STATE_CONNECTING as isize,
54 AcknowledgingConnect = ll::_ENetPeerState_ENET_PEER_STATE_ACKNOWLEDGING_CONNECT
55 as isize,
56 ConnectionPending = ll::_ENetPeerState_ENET_PEER_STATE_CONNECTION_PENDING as isize,
57 ConnectionSucceeded = ll::_ENetPeerState_ENET_PEER_STATE_CONNECTION_SUCCEEDED
58 as isize,
59 Connected = ll::_ENetPeerState_ENET_PEER_STATE_CONNECTED as isize,
60 DisconnectLater = ll::_ENetPeerState_ENET_PEER_STATE_DISCONNECT_LATER as isize,
61 Disconnecting = ll::_ENetPeerState_ENET_PEER_STATE_DISCONNECTING as isize,
62 AcknowledgingDisconnect = ll::_ENetPeerState_ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT
63 as isize,
64 Zombie = ll::_ENetPeerState_ENET_PEER_STATE_ZOMBIE as isize
65}
66
67#[derive(Debug)]
68pub enum ConnectError {
69 NoPeersAvailable,
70 Failure
72}
73
74#[derive(Debug)]
75pub enum SendError {
76 PeerNotConnected (State),
77 PeerNoChannelID (u8),
78 PacketCreateZeroLength,
79 PacketCreateMallocFailure,
81 PacketExceedsMaximumSize (usize),
83 Failure
86}
87
88impl Peer {
93 pub(crate) const unsafe fn from_raw (
94 peer : *mut ll::ENetPeer,
95 hostdrop : std::rc::Rc <host::HostDrop>
96 ) -> Self {
97 Peer {
98 raw: peer,
99 hostdrop
100 }
101 }
102
103 #[inline]
107 pub const unsafe fn raw (&self) -> *mut ll::ENetPeer {
108 self.raw
109 }
110
111 #[inline]
115 pub fn incoming_peer_id (&self) -> u16 {
116 unsafe { (*self.raw).incomingPeerID }
117 }
118
119 #[inline]
120 pub fn state (&self) -> State {
121 use num_traits::FromPrimitive;
122 #[expect(clippy::unnecessary_cast)] unsafe { State::from_u32 ((*self.raw).state as u32).unwrap() }
124 }
125
126 #[inline]
127 pub fn address (&self) -> Address {
128 unsafe { Address::from_ll ((*self.raw).address) }
129 }
130
131 #[inline]
132 pub fn packet_loss_epoch (&self) -> u32 {
133 unsafe { (*self.raw).packetLossEpoch }
134 }
135
136 #[inline]
138 pub fn packets_sent (&self) -> u32 {
139 unsafe { (*self.raw).packetsSent }
140 }
141
142 #[inline]
144 pub fn packets_lost (&self) -> u32 {
145 unsafe { (*self.raw).packetsLost }
146 }
147
148 #[inline]
151 pub fn packet_loss (&self) -> u32 {
152 unsafe { (*self.raw).packetLoss }
153 }
154
155 #[inline]
157 pub fn round_trip_time (&self) -> u32 {
158 unsafe { (*self.raw).roundTripTime }
159 }
160
161 #[inline]
163 pub fn round_trip_time_variance (&self) -> u32 {
164 unsafe { (*self.raw).roundTripTimeVariance }
165 }
166
167 #[inline]
197 pub fn ping (&mut self) {
198 unsafe {
199 ll::enet_peer_ping (self.raw())
200 }
201 }
202
203 #[inline]
204 pub fn get_ping_interval (&mut self) -> u32 {
205 unsafe {
206 (*self.raw).pingInterval
207 }
208 }
209
210 #[inline]
212 pub fn ping_interval (&mut self, ping_interval : u32) {
213 unsafe {
214 ll::enet_peer_ping_interval (self.raw(), ping_interval)
215 }
216 }
217
218 #[inline]
220 pub fn timeout (&mut self,
221 timeout_limit : u32, timeout_minimum : u32, timeout_maximum : u32
222 ) {
223 unsafe {
224 ll::enet_peer_timeout (self.raw(),
225 timeout_limit, timeout_minimum, timeout_maximum)
226 }
227 }
228
229 #[inline]
231 pub fn get_timeout (&mut self) -> (u32, u32, u32) {
232 unsafe {
233 ( (*self.raw).timeoutLimit,
234 (*self.raw).timeoutMinimum,
235 (*self.raw).timeoutMaximum )
236 }
237 }
238
239 pub fn send (&mut self, channel_id : u8, packet : Packet) -> Result <(), SendError> {
240 use num_traits::FromPrimitive;
241 unsafe {
242 if (*self.raw).state != ll::_ENetPeerState_ENET_PEER_STATE_CONNECTED {
243 #[expect(clippy::unnecessary_cast)] return Err (SendError::PeerNotConnected(
245 State::from_u32 ((*self.raw).state as u32).unwrap()
246 ))
247 }
248 if (*self.raw).channelCount as u8 <= channel_id {
249 return Err (SendError::PeerNoChannelID (channel_id))
250 }
251 let raw = match packet {
252 Packet::Allocate { bytes, flags } => {
253 if (*self.hostdrop.raw()).maximumPacketSize < bytes.len() {
254 return Err (SendError::PacketExceedsMaximumSize (bytes.len()))
255 }
256 if bytes.is_empty() {
257 return Err (SendError::PacketCreateZeroLength)
258 }
259 ll::enet_packet_create (
260 bytes.as_ptr() as *const std::os::raw::c_void, bytes.len(), flags.bits())
261 }
262 Packet::NoAllocate { bytes, flags } => {
263 if (*(*self.raw).host).maximumPacketSize < bytes.len() {
264 return Err (SendError::PacketExceedsMaximumSize(bytes.len()))
265 }
266 if bytes.is_empty() {
267 return Err (SendError::PacketCreateZeroLength)
268 }
269 #[expect(clippy::unnecessary_cast)] ll::enet_packet_create (
271 bytes.as_ptr() as *const std::os::raw::c_void,
272 bytes.len(),
273 flags.bits() | ll::_ENetPacketFlag_ENET_PACKET_FLAG_NO_ALLOCATE as u32)
274 }
275 };
276 if raw.is_null() {
277 return Err (SendError::PacketCreateMallocFailure)
278 }
279 if ll::enet_peer_send (self.raw(), channel_id, raw) < 0 {
280 return Err (SendError::Failure)
281 }
282 Ok(())
283 }
284 } #[inline]
293 pub fn disconnect (&self) {
294 unsafe {
295 ll::enet_peer_disconnect (self.raw(), 0)
296 }
297 }
298
299 #[inline]
301 pub fn disconnect_now (&self) {
302 unsafe {
303 ll::enet_peer_disconnect_now (self.raw(), 0)
304 }
305 }
306
307 #[inline]
309 pub fn disconnect_later (&self) {
310 unsafe {
311 ll::enet_peer_disconnect_later (self.raw(), 0)
312 }
313 }
314
315 #[inline]
319 pub fn reset (&self) {
320 unsafe {
321 ll::enet_peer_reset (self.raw())
322 }
323 }
324
325}