1use std;
2use ll;
3use crate::{
4 peer, Address, EnetDrop, Event, Packet, Peer, MAX_PEERS, MAX_CHANNEL_COUNT
5};
6
7#[derive(Clone, Debug)]
15pub struct Host {
16 hostdrop : std::rc::Rc <HostDrop>
17}
18
19#[derive(Debug, PartialEq)]
20pub(crate) struct HostDrop {
21 raw : *mut ll::ENetHost,
22 enetdrop : std::sync::Arc <EnetDrop>
23}
24
25#[derive(Debug)]
30pub enum Error {
31 ServiceError,
33 DispatchError
35}
36
37#[derive(Clone, Debug)]
38pub enum CreateError {
39 TooManyPeers (u32),
41 TooManyChannels (u32),
43 ReturnedNull
44}
45
46impl Host {
51 pub(crate) fn new (
52 address : Option <Address>,
53 peer_count : u32,
54 channel_limit : Option <u32>,
55 incoming_bandwidth : Option <u32>,
56 outgoing_bandwidth : Option <u32>,
57 enetdrop : std::sync::Arc <EnetDrop>
58 ) -> Result <Self, CreateError> {
59 if MAX_PEERS < peer_count {
60 return Err (CreateError::TooManyPeers (peer_count))
61 }
62 let channel_limit = channel_limit.unwrap_or (0);
63 if MAX_CHANNEL_COUNT < channel_limit {
64 return Err (CreateError::TooManyChannels (channel_limit))
65 }
66 let host;
67 match address {
68 Some (a) => unsafe {
69 host = ll::enet_host_create (
70 a.raw(),
71 peer_count as usize,
72 channel_limit as usize,
73 incoming_bandwidth.unwrap_or (0),
74 outgoing_bandwidth.unwrap_or (0)
75 );
76 if host.is_null() {
77 return Err (CreateError::ReturnedNull)
78 }
79 },
80 None => unsafe {
81 host = ll::enet_host_create (
82 std::ptr::null(),
83 peer_count as usize,
84 channel_limit as usize,
85 incoming_bandwidth.unwrap_or (0),
86 outgoing_bandwidth.unwrap_or (0)
87 );
88 if host.is_null() {
89 return Err (CreateError::ReturnedNull)
90 }
91 }
92 } Ok (Host {
94 hostdrop: std::rc::Rc::new (HostDrop {
95 raw: host, enetdrop
96 })
97 })
98 } #[inline]
104 pub unsafe fn raw (&self) -> *mut ll::ENetHost {
105 unsafe { self.hostdrop.raw() }
106 }
107
108 #[inline]
110 pub fn peer_count (&self) -> usize {
111 unsafe { (*self.raw()).peerCount }
112 }
113
114 #[inline]
116 pub fn connected_peers (&self) -> usize {
117 unsafe { (*self.raw()).connectedPeers }
118 }
119
120 #[inline]
122 pub fn channel_limit (&self) -> usize {
123 unsafe { (*self.raw()).channelLimit }
124 }
125
126 #[inline]
130 pub fn total_sent_packets (&self) -> u32 {
131 unsafe { (*self.raw()).totalSentPackets }
132 }
133 pub fn reset_total_sent_packets (&mut self) {
134 unsafe {
135 (*self.raw()).totalSentPackets = 0;
136 }
137 }
138
139 #[inline]
143 pub fn total_sent_data (&self) -> u32 {
144 unsafe { (*self.raw()).totalSentPackets }
145 }
146 pub fn reset_total_sent_data (&mut self) {
147 unsafe {
148 (*self.raw()).totalSentData = 0;
149 }
150 }
151
152 #[inline]
156 pub fn total_received_packets (&self) -> u32 {
157 unsafe { (*self.raw()).totalReceivedPackets }
158 }
159 pub fn reset_total_received_packets (&mut self) {
160 unsafe {
161 (*self.raw()).totalReceivedPackets = 0;
162 }
163 }
164
165 #[inline]
169 pub fn total_received_data (&self) -> u32 {
170 unsafe { (*self.raw()).totalReceivedPackets }
171 }
172 pub fn reset_total_received_data (&mut self) {
173 unsafe {
174 (*self.raw()).totalReceivedData = 0;
175 }
176 }
177
178
179 pub fn connect (&mut self, address : &Address, channel_count : u8, data : u32)
208 -> Result <Peer, peer::ConnectError>
209 {
210 unsafe {
211 if self.peer_count() <= self.connected_peers() {
212 return Err (peer::ConnectError::NoPeersAvailable)
213 }
214 let peer = ll::enet_host_connect (
215 self.raw(),
216 address.raw(),
217 channel_count as usize,
218 data
219 );
220 if peer.is_null() {
221 return Err (peer::ConnectError::Failure)
222 }
223 Ok (Peer::from_raw(peer, self.hostdrop.clone()))
224 }
225 }
226
227 pub fn service (&mut self, timeout : u32) -> Result <Option <Event>, Error> {
234 let event = unsafe {
235 let mut mem = std::mem::MaybeUninit::<ll::ENetEvent>::uninit();
236 let event = mem.as_mut_ptr();
237 if ll::enet_host_service (self.hostdrop.raw, event, timeout) < 0 {
238 return Err (Error::ServiceError)
239 }
240 *event
241 };
242 Ok (Event::from_ll (event, self.hostdrop.clone()))
243 }
244
245 #[inline]
247 pub fn check_events (&mut self) -> Result <Option <Event>, Error> {
248 let event = unsafe {
249 let mut mem = std::mem::MaybeUninit::<ll::ENetEvent>::uninit();
250 let event = mem.as_mut_ptr();
251 if ll::enet_host_check_events (self.hostdrop.raw, event) < 0 {
252 return Err (Error::DispatchError)
253 }
254 *event
255 };
256 Ok (Event::from_ll (event, self.hostdrop.clone()))
257 }
258
259 #[inline]
262 pub fn flush (&mut self) {
263 unsafe { ll::enet_host_flush (self.hostdrop.raw) }
264 }
265
266 pub fn broadcast (&mut self, channel_id : u8, packet : Packet) {
268 unsafe {
269 let raw = match packet {
270 Packet::Allocate { bytes, flags } => {
271 ll::enet_packet_create (
272 bytes.as_ptr() as *const std::os::raw::c_void,
273 bytes.len(),
274 flags.bits())
275 }
276 #[expect(clippy::unnecessary_cast)] Packet::NoAllocate { bytes, flags } => {
278 ll::enet_packet_create (
279 bytes.as_ptr() as *const std::os::raw::c_void,
280 bytes.len(),
281 flags.bits() | ll::_ENetPacketFlag_ENET_PACKET_FLAG_NO_ALLOCATE as u32)
282 }
283 };
284 ll::enet_host_broadcast (self.raw(), channel_id, raw)
285 }
286 }
287
288} impl HostDrop {
291 #[inline]
292 pub(crate) const unsafe fn raw (&self) -> *mut ll::ENetHost {
293 self.raw
294 }
295}
296impl Drop for HostDrop {
297 #[inline]
298 fn drop (&mut self) {
299 unsafe { ll::enet_host_destroy (self.raw) }
300 }
301}