1#![allow(dead_code)]
2
3use {
4 std::{
5 sync::atomic::{AtomicU64, Ordering},
6 ops::{Index, IndexMut, Deref, DerefMut},
7 collections::{HashMap},
8 sync::Once,
9 fmt,
10 cmp,
11 }
12};
13
14
15impl LiveIdInterner {
16 pub fn add(&mut self, val: &str) {
17 self.id_to_string.insert(LiveId::from_str(val), val.to_string());
18 }
19
20 pub fn contains(&mut self, val: &str) -> bool {
21 self.id_to_string.contains_key(&LiveId::from_str(val))
22 }
23
24 pub fn with<F, R>(f: F) -> R
25 where
26 F: FnOnce(&mut Self) -> R,
27 {
28 static mut IDMAP: Option<LiveIdInterner> = None;
29 static ONCE: Once = Once::new();
30 ONCE.call_once( || unsafe {
31 let mut map = LiveIdInterner {
32 id_to_string: HashMap::new()
34 };
35 let fill = [
37 "default",
38 "exp",
39 "void",
40 "true",
41 "false",
42 "use",
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 "tracks",
86 "state",
87 "state_id",
88 "user",
89 "play",
90 "ended"
91 ];
92 for item in &fill {
93 if map.contains(item) {
94 eprintln!("WE HAVE AN ID COLLISION!");
95 }
96 map.add(item);
97 }
98 IDMAP = Some(map)
99 });
100 f(unsafe {IDMAP.as_mut().unwrap()})
101 }
102}
103
104#[derive(Clone, Default, Eq, Hash, Copy, PartialEq)]
105pub struct LiveId(pub u64);
106
107pub const LIVE_ID_SEED:u64 = 0xd6e8_feb8_6659_fd93;
108
109impl LiveId {
110 pub fn empty() -> Self {
111 Self (0)
112 }
113 pub fn from_lo_hi(lo:u32, hi:u32)->Self{
114 Self( (lo as u64) | ((hi as u64)<<32) )
115 }
116 pub fn lo(&self)->u32{
117 (self.0&0xffff_ffff) as u32
118 }
119 pub fn hi(&self)->u32{
120 (self.0>>32) as u32
121 }
122
123 pub fn seeded()->Self{
124 Self(LIVE_ID_SEED)
125 }
126
127 pub fn is_unique(&self) -> bool {
128 (self.0 & 0x8000_0000_0000_0000) == 0 && self.0 != 0
129 }
130
131 pub fn is_ident(&self) -> bool {
132 (self.0 & 0x8000_0000_0000_0000) != 0
133 }
134
135 pub fn is_empty(&self) -> bool {
136 self.0 == 0
137 }
138
139 pub fn get_value(&self) -> u64 {
140 self.0
141 }
142
143 pub const fn from_bytes(seed:u64, id_bytes: &[u8], start: usize, end: usize) -> Self {
146 let mut x = seed;
147 let mut i = start;
148 while i < end {
149 x = x.overflowing_add(id_bytes[i] as u64).0;
150 x ^= x >> 32;
151 x = x.overflowing_mul(0xd6e8_feb8_6659_fd93).0;
152 x ^= x >> 32;
153 x = x.overflowing_mul(0xd6e8_feb8_6659_fd93).0;
154 x ^= x >> 32;
155 i += 1;
156 }
157 Self ((x & 0x7fff_ffff_ffff_ffff) | 0x8000_0000_0000_0000)
159 }
160
161 pub const fn from_str(id_str: &str) -> Self {
162 let bytes = id_str.as_bytes();
163 Self::from_bytes(LIVE_ID_SEED, bytes, 0, bytes.len())
164 }
165
166 pub const fn str_append(self, id_str: &str) -> Self {
167 let bytes = id_str.as_bytes();
168 Self::from_bytes(self.0, bytes, 0, bytes.len())
169 }
170
171 pub const fn bytes_append(self, bytes: &[u8]) -> Self {
172 Self::from_bytes(self.0, bytes, 0, bytes.len())
173 }
174
175 pub const fn id_append(self, id: LiveId) -> Self {
176 let bytes = id.0.to_be_bytes();
177 Self::from_bytes(self.0, &bytes, 0, bytes.len())
178 }
179
180 pub const fn from_str_num(id_str: &str, num:u64) -> Self {
181 let bytes = id_str.as_bytes();
182 let id = Self::from_bytes(LIVE_ID_SEED, bytes, 0, bytes.len());
183 Self::from_bytes(id.0, &num.to_be_bytes(), 0, 8)
184 }
185
186 pub const fn from_num(seed:u64, num:u64) -> Self {
187 Self::from_bytes(seed, &num.to_be_bytes(), 0, 8)
188 }
189
190 pub fn from_str_with_lut(id_str: &str) -> Result<Self,
191 String> {
192 let id = Self::from_str(id_str);
193 LiveIdInterner::with( | idmap | {
194 if let Some(stored) = idmap.id_to_string.get(&id) {
195 if stored != id_str {
196 return Err(stored.clone())
197 }
198 }
199 else {
200 idmap.id_to_string.insert(id, id_str.to_string());
201 }
202 Ok(id)
203 })
204 }
205
206 pub fn from_str_num_with_lut(id_str: &str, num:u64) -> Result<Self,
207 String> {
208 let id = Self::from_str_num(id_str, num);
209 LiveIdInterner::with( | idmap | {
210 idmap.id_to_string.insert(id, format!("{}{}",id_str, num));
211 Ok(id)
212 })
213 }
214
215 pub fn as_string<F, R>(&self, f: F) -> R
216 where F: FnOnce(Option<&str>) -> R
217 {
218 LiveIdInterner::with( | idmap | {
219 match idmap.id_to_string.get(self){
220 Some(v)=>f(Some(v)),
221 None=>f(None)
222 }
223 })
224 }
225
226 pub fn unique() -> Self {
227 LiveId(UNIQUE_LIVE_ID.fetch_add(1, Ordering::SeqCst))
228 }
229}
230
231pub (crate) static UNIQUE_LIVE_ID: AtomicU64 = AtomicU64::new(1);
232
233impl Ord for LiveId {
234 fn cmp(&self, other: &LiveId) -> cmp::Ordering {
235 LiveIdInterner::with( | idmap | {
236 if let Some(id1) = idmap.id_to_string.get(self) {
237 if let Some(id2) = idmap.id_to_string.get(other) {
238 return id1.cmp(id2)
239 }
240 }
241 cmp::Ordering::Equal
242 })
243 }
244}
245
246impl PartialOrd for LiveId {
247 fn partial_cmp(&self, other: &LiveId) -> Option<cmp::Ordering> {
248 Some(self.cmp(other))
249 }
250}
251
252impl fmt::Debug for LiveId {
253 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
254 fmt::Display::fmt(self, f)
255 }
256}
257
258impl fmt::Display for LiveId {
259 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
260 if *self == LiveId::empty() {
261 write!(f, "0")
262 }
263 else if self.is_unique(){
264 write!(f, "UniqueId {}", self.0)
265 }
266 else{
267 self.as_string( | string | {
268 if let Some(id) = string {
269 write!(f, "{}", id)
270 }
271 else {
272 write!(f, "IdNotFound {:016x}", self.0)
273 }
274 })
275 }
276 }
277}
278
279impl fmt::LowerHex for LiveId {
280 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
281 fmt::Display::fmt(self, f)
282 }
283}
284
285
286pub struct LiveIdInterner {
287 id_to_string: HashMap<LiveId, String>,
289}
290
291#[derive(Default)]
295pub struct LiveIdHasher(u64);
296
297impl std::hash::Hasher for LiveIdHasher {
298 fn write(&mut self, _: &[u8]) {
299 unreachable!("Invalid use of IdHasher");
300 }
301
302 fn write_u8(&mut self, _n: u8) {
303 unreachable!("Invalid use of IdHasher");
304 }
305 fn write_u16(&mut self, _n: u16) {
306 unreachable!("Invalid use of IdHasher");
307 }
308 fn write_u32(&mut self, _n: u32) {
309 unreachable!("Invalid use of IdHasher");
310 }
311
312 #[inline(always)]
313 fn write_u64(&mut self, n: u64) {
314 self.0 = n;
315 }
316
317 fn write_usize(&mut self, _n: usize) {
318 unreachable!("Invalid use of IdHasher");
319 }
320
321 fn write_i8(&mut self, _n: i8) {
322 unreachable!("Invalid use of IdHasher");
323 }
324 fn write_i16(&mut self, _n: i16) {
325 unreachable!("Invalid use of IdHasher");
326 }
327 fn write_i32(&mut self, _n: i32) {
328 unreachable!("Invalid use of IdHasher");
329 }
330 fn write_i64(&mut self, _n: i64) {
331 unreachable!("Invalid use of IdHasher");
332 }
333 fn write_isize(&mut self, _n: isize) {
334 unreachable!("Invalid use of IdHasher");
335 }
336
337 #[inline(always)]
338 fn finish(&self) -> u64 {
339 self.0
340 }
341}
342
343#[derive(Copy, Clone, Default)]
344pub struct LiveIdHasherBuilder {}
345
346impl std::hash::BuildHasher for LiveIdHasherBuilder {
347 type Hasher = LiveIdHasher;
348
349 #[inline(always)]
350 fn build_hasher(&self) -> LiveIdHasher {
351 LiveIdHasher::default()
352 }
353}
354
355#[derive(Clone, Debug)]
356pub struct LiveIdMap<K, V> {
357 map: HashMap<K, V, LiveIdHasherBuilder>,
358 }
360
361impl<K, V> Default for LiveIdMap<K, V>
362where K: std::cmp::Eq + std::hash::Hash + Copy + From<LiveId> + std::fmt::Debug {
363 fn default() -> Self {
364 Self {
365 map: HashMap::with_hasher(LiveIdHasherBuilder {}),
366 }
368 }
369}
370impl<K, V> Deref for LiveIdMap<K, V>
414where K: std::cmp::Eq + std::hash::Hash + Copy + From<LiveId>
415{
416 type Target = HashMap<K, V, LiveIdHasherBuilder>;
417 fn deref(&self) -> &Self::Target {&self.map}
418}
419
420impl<K, V> DerefMut for LiveIdMap<K, V>
421where K: std::cmp::Eq + std::hash::Hash + Copy + From<LiveId>
422{
423 fn deref_mut(&mut self) -> &mut Self::Target {&mut self.map}
424}
425
426impl<K, V> Index<K> for LiveIdMap<K, V>
427where K: std::cmp::Eq + std::hash::Hash + Copy + From<LiveId>
428{
429 type Output = V;
430 fn index(&self, index: K) -> &Self::Output {
431 self.map.get(&index).unwrap()
432 }
433}
434
435impl<K, V> IndexMut<K> for LiveIdMap<K, V>
436where K: std::cmp::Eq + std::hash::Hash + Copy + From<LiveId>
437{
438 fn index_mut(&mut self, index: K) -> &mut Self::Output {
439 self.map.get_mut(&index).unwrap()
440 }
441}