aetheris_protocol/
types.rs1use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
10pub struct NetworkId(pub u64);
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct LocalId(pub u64);
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
20pub struct ClientId(pub u64);
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
28pub struct ComponentKind(pub u16);
29
30#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
32#[repr(C)]
33pub struct Transform {
34 pub x: f32,
36 pub y: f32,
38 pub z: f32,
40 pub rotation: f32,
42 pub entity_type: u16,
44}
45
46use std::sync::atomic::{AtomicU64, Ordering};
47use thiserror::Error;
48
49#[derive(Debug, Error, PartialEq, Eq)]
50pub enum AllocatorError {
51 #[error("NetworkId overflow (reached u64::MAX)")]
52 Overflow,
53 #[error("NetworkId allocator exhausted (reached limit)")]
54 Exhausted,
55}
56
57#[derive(Debug)]
62pub struct NetworkIdAllocator {
63 start_id: u64,
64 next: AtomicU64,
65}
66
67impl Default for NetworkIdAllocator {
68 fn default() -> Self {
69 Self::new(1)
70 }
71}
72
73impl NetworkIdAllocator {
74 #[must_use]
76 pub fn new(start_id: u64) -> Self {
77 Self {
78 start_id,
79 next: AtomicU64::new(start_id),
80 }
81 }
82
83 pub fn allocate(&self) -> Result<NetworkId, AllocatorError> {
88 let val = self
89 .next
90 .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |curr| {
91 if curr == u64::MAX {
92 None
93 } else {
94 Some(curr + 1)
95 }
96 })
97 .map_err(|_| AllocatorError::Overflow)?;
98
99 if val == 0 {
100 return Err(AllocatorError::Exhausted);
101 }
102
103 Ok(NetworkId(val))
104 }
105
106 pub fn reset(&self) {
109 self.next.store(self.start_id, Ordering::Relaxed);
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116
117 #[test]
118 fn test_primitive_derives() {
119 let nid1 = NetworkId(42);
120 let nid2 = nid1;
121 assert_eq!(nid1, nid2);
122
123 let lid1 = LocalId(42);
124 let lid2 = LocalId(42);
125 assert_eq!(lid1, lid2);
126
127 let cid = ClientId(99);
128 assert_eq!(format!("{cid:?}"), "ClientId(99)");
129
130 let kind = ComponentKind(1);
131 assert_eq!(kind.0, 1);
132 }
133}