concinnity_physics/
handle.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
17pub struct BodyHandle(u64);
18
19impl BodyHandle {
20 pub const fn from_parts(index: u32, generation: u32) -> Self {
22 Self(((index as u64) << 32) | generation as u64)
23 }
24
25 pub const fn index(self) -> u32 {
27 (self.0 >> 32) as u32
28 }
29
30 pub const fn generation(self) -> u32 {
32 self.0 as u32
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn parts_round_trip() {
42 for (index, generation) in [(0, 0), (1, 0), (0, 1), (7, 3), (u32::MAX, u32::MAX)] {
43 let handle = BodyHandle::from_parts(index, generation);
44 assert_eq!(handle.index(), index);
45 assert_eq!(handle.generation(), generation);
46 }
47 }
48
49 #[test]
50 fn a_reused_slot_is_a_different_handle() {
51 let first = BodyHandle::from_parts(4, 0);
52 let reused = BodyHandle::from_parts(4, 1);
53 assert_ne!(first, reused, "the generation must distinguish the slot");
54 }
55
56 #[test]
57 fn handles_order_by_slot_then_generation() {
58 let mut handles = [
59 BodyHandle::from_parts(2, 0),
60 BodyHandle::from_parts(1, 5),
61 BodyHandle::from_parts(1, 2),
62 ];
63 handles.sort();
64 assert_eq!(
65 handles,
66 [
67 BodyHandle::from_parts(1, 2),
68 BodyHandle::from_parts(1, 5),
69 BodyHandle::from_parts(2, 0),
70 ]
71 );
72 }
73}