extern crate enet_sys as ll;
use std::sync::atomic;
pub mod address;
pub mod event;
pub mod host;
pub mod packet;
pub mod peer;
pub mod version;
pub use self::address::Address;
pub use self::event::Event;
pub use self::host::Host;
pub use self::packet::Packet;
pub use self::peer::Peer;
pub use self::version::Version;
#[expect(clippy::unnecessary_cast)] pub const MAX_PEERS : u32 = ll::ENET_PROTOCOL_MAXIMUM_PEER_ID as u32;
#[expect(clippy::unnecessary_cast)] pub const MAX_CHANNEL_COUNT : u32 = ll::ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT as u32;
static ENET_CONTEXT_ALIVE : atomic::AtomicBool = atomic::AtomicBool::new (false);
#[derive(Clone)]
pub struct Enet {
enetdrop : std::sync::Arc <EnetDrop>
}
#[derive(Clone, Debug, PartialEq)]
struct EnetDrop;
#[derive(Clone, Debug)]
pub enum Error {
Initialize (String),
ServerCreate (host::CreateError),
ClientCreate (host::CreateError)
}
#[inline]
pub fn initialize() -> Result <Enet, Error> {
Enet::new()
}
pub fn linked_version() -> Version {
unsafe {
Version::from_ll (ll::enet_linked_version())
}
}
impl Enet {
pub fn client_host_create (&self,
peer_count : u32,
incoming_bandwidth : Option <u32>,
outgoing_bandwidth : Option <u32>
) -> Result <Host, Error> {
Host::new (
None,
peer_count,
None,
incoming_bandwidth,
outgoing_bandwidth,
self.enetdrop.clone()
).map_err (Error::ClientCreate)
}
pub fn server_host_create (&self,
address : Address,
peer_count : u32,
channel_limit : Option <u32>,
incoming_bandwidth : Option <u32>,
outgoing_bandwidth : Option <u32>
) -> Result <Host, Error> {
Host::new (
Some (address),
peer_count,
channel_limit,
incoming_bandwidth,
outgoing_bandwidth,
self.enetdrop.clone()
).map_err (Error::ServerCreate)
}
fn new() -> Result <Self, Error> {
unsafe {
let was_alive =
ENET_CONTEXT_ALIVE.swap (true, atomic::Ordering::Relaxed);
if was_alive {
return Err (Error::Initialize (
"`Enet` cannot be initialized more than once".to_owned()))
}
if ll::enet_initialize() < 0 {
return Err (Error::Initialize(
"`enet_initialize` returned an error".to_owned()))
}
Ok (Enet { enetdrop: std::sync::Arc::new (EnetDrop) })
}
}
}
impl Drop for EnetDrop {
#[inline]
fn drop (&mut self) {
let was_alive = ENET_CONTEXT_ALIVE.swap (false, atomic::Ordering::Relaxed);
debug_assert!(was_alive);
if was_alive {
unsafe { ll::enet_deinitialize() }
}
}
}