1extern crate enet_sys as ll;
4
5use std::sync::atomic;
6
7pub mod address;
8pub mod event;
9pub mod host;
10pub mod packet;
11pub mod peer;
12pub mod version;
13
14pub use self::address::Address;
15pub use self::event::Event;
16pub use self::host::Host;
17pub use self::packet::Packet;
18pub use self::peer::Peer;
19pub use self::version::Version;
20
21#[expect(clippy::unnecessary_cast)] pub const MAX_PEERS : u32 = ll::ENET_PROTOCOL_MAXIMUM_PEER_ID as u32;
24#[expect(clippy::unnecessary_cast)] pub const MAX_CHANNEL_COUNT : u32 = ll::ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT as u32;
27
28static ENET_CONTEXT_ALIVE : atomic::AtomicBool = atomic::AtomicBool::new (false);
29
30#[derive(Clone)]
36pub struct Enet {
37 enetdrop : std::sync::Arc <EnetDrop>
38}
39
40#[derive(Clone, Debug, PartialEq)]
41struct EnetDrop;
42
43#[derive(Clone, Debug)]
45pub enum Error {
46 Initialize (String),
47 ServerCreate (host::CreateError),
48 ClientCreate (host::CreateError)
49}
50
51#[inline]
55pub fn initialize() -> Result <Enet, Error> {
56 Enet::new()
57}
58
59pub fn linked_version() -> Version {
61 unsafe {
62 Version::from_ll (ll::enet_linked_version())
63 }
64}
65
66impl Enet {
67 pub fn client_host_create (&self,
77 peer_count : u32,
78 incoming_bandwidth : Option <u32>,
79 outgoing_bandwidth : Option <u32>
80 ) -> Result <Host, Error> {
81 Host::new (
82 None,
83 peer_count,
84 None,
85 incoming_bandwidth,
86 outgoing_bandwidth,
87 self.enetdrop.clone()
88 ).map_err (Error::ClientCreate)
89 }
90
91 pub fn server_host_create (&self,
101 address : Address,
102 peer_count : u32,
103 channel_limit : Option <u32>,
104 incoming_bandwidth : Option <u32>,
105 outgoing_bandwidth : Option <u32>
106 ) -> Result <Host, Error> {
107 Host::new (
108 Some (address),
109 peer_count,
110 channel_limit,
111 incoming_bandwidth,
112 outgoing_bandwidth,
113 self.enetdrop.clone()
114 ).map_err (Error::ServerCreate)
115 }
116
117 fn new() -> Result <Self, Error> {
118 unsafe {
119 let was_alive =
120 ENET_CONTEXT_ALIVE.swap (true, atomic::Ordering::Relaxed);
121 if was_alive {
122 return Err (Error::Initialize (
123 "`Enet` cannot be initialized more than once".to_owned()))
124 }
125 if ll::enet_initialize() < 0 {
126 return Err (Error::Initialize(
127 "`enet_initialize` returned an error".to_owned()))
128 }
129 Ok (Enet { enetdrop: std::sync::Arc::new (EnetDrop) })
130 }
131 }
132}
133
134impl Drop for EnetDrop {
135 #[inline]
136 fn drop (&mut self) {
137 let was_alive = ENET_CONTEXT_ALIVE.swap (false, atomic::Ordering::Relaxed);
138 debug_assert!(was_alive);
139 if was_alive {
140 unsafe { ll::enet_deinitialize() }
141 }
142 }
143}
144
145