1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use crate::constants::*;
#[repr(transparent)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Entity {
handle: u32,
}
impl Default for Entity {
fn default() -> Self {
Self::INVALID
}
}
impl Entity {
pub const INVALID: Entity =
unsafe { Entity::new_unchecked(MAX_ENTITY_HANDLE_VALUE, MAX_ENTITY_VERSION_VALUE) };
pub const unsafe fn from_raw(raw: u32) -> Entity {
Self { handle: raw }
}
pub const fn is_valid(&self) -> bool {
self.handle != Self::INVALID.handle
}
pub const fn invalid() -> Entity {
Self::INVALID
}
pub const unsafe fn new_unchecked(index: u32, version: u8) -> Entity {
Entity {
handle: (index << ENTITY_VERSION_BITS) | version as u32,
}
}
pub const fn index(&self) -> u32 {
self.handle >> ENTITY_VERSION_BITS
}
pub unsafe fn set_index(&mut self, index: u32) {
debug_assert!(
index < 2u32.pow(ENTITY_HANDLE_BITS as u32),
"Entity index must be < 2^24!"
);
let version: u8 = (0xFFFFFF & self.handle) as u8;
self.handle = (index << ENTITY_VERSION_BITS) | version as u32;
}
pub const fn version(&self) -> u8 {
(0xFFFFFF & self.handle) as u8
}
pub fn set_version(&mut self, version: u8) {
self.handle = (self.index() << ENTITY_VERSION_BITS) | version as u32;
}
pub const fn raw(&self) -> u32 {
self.handle
}
}
#[test]
fn test_entity_handles() {
let mut entity = unsafe { Entity::new_unchecked(8_000_000, 255) };
assert_eq!(entity.index(), 8_000_000);
assert_eq!(entity.version(), 255);
entity.set_version(20);
assert_eq!(entity.version(), 20);
assert_eq!(entity.index(), 8_000_000);
unsafe {
entity.set_index(30);
}
assert_eq!(entity.index(), 30);
assert_eq!(entity.version(), 20);
assert_eq!(Entity::invalid().raw(), u32::MAX);
}