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