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 sync::Mutex,
10 fmt,
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 IDMAP: Mutex<Option<LiveIdInterner>> = Mutex::new(None);
29 static ONCE: Once = Once::new();
30 ONCE.call_once( ||{
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 "geom_pos",
92 "geom_id",
93 "geom_uv",
94 ];
95 for item in &fill {
96 if map.contains(item) {
97 eprintln!("WE HAVE AN ID COLLISION!");
98 }
99 map.add(item);
100 }
101 *IDMAP.lock().unwrap() = Some(map)
102 });
103 let mut idmap = IDMAP.lock().unwrap();
104 f(idmap.as_mut().unwrap())
105 }
106}
107
108#[derive(Clone, Default, Eq, Hash, Copy, Ord, PartialOrd, PartialEq)]
109pub struct LiveId(pub u64);
110
111pub const LIVE_ID_SEED:u64 = 0xd6e8_feb8_6659_fd93;
112
113impl LiveId {
114 pub fn empty() -> Self {
115 Self (0)
116 }
117 pub fn from_lo_hi(lo:u32, hi:u32)->Self{
118 Self( (lo as u64) | ((hi as u64)<<32) )
119 }
120 pub fn lo(&self)->u32{
121 (self.0&0xffff_ffff) as u32
122 }
123 pub fn hi(&self)->u32{
124 (self.0>>32) as u32
125 }
126
127 pub fn seeded()->Self{
128 Self(LIVE_ID_SEED)
129 }
130
131 pub fn is_unique(&self) -> bool {
132 (self.0 & 0x8000_0000_0000_0000) == 0 && self.0 != 0
133 }
134
135 pub fn is_ident(&self) -> bool {
136 (self.0 & 0x8000_0000_0000_0000) != 0
137 }
138
139 pub fn is_empty(&self) -> bool {
140 self.0 == 0
141 }
142
143 pub fn get_value(&self) -> u64 {
144 self.0
145 }
146
147 pub const fn from_bytes(seed:u64, id_bytes: &[u8], start: usize, end: usize) -> Self {
150 let mut x = seed;
151 let mut i = start;
152 while i < end {
153 x = x.overflowing_add(id_bytes[i] as u64).0;
154 x ^= x >> 32;
155 x = x.overflowing_mul(0xd6e8_feb8_6659_fd93).0;
156 x ^= x >> 32;
157 x = x.overflowing_mul(0xd6e8_feb8_6659_fd93).0;
158 x ^= x >> 32;
159 i += 1;
160 }
161 Self ((x & 0x7fff_ffff_ffff_ffff) | 0x8000_0000_0000_0000)
163 }
164
165 pub fn add(&self, what:u64)->Self{
166 Self(self.0 + what)
167 }
168
169 pub fn xor(&self, what:u64)->Self{
170 Self((self.0 ^ what)| 0x8000_0000_0000_0000)
171 }
172
173 pub fn sub(&self, what:u64)->Self{
174 Self(self.0 - what)
175 }
176
177 pub const fn from_str(id_str: &str) -> Self {
178 let bytes = id_str.as_bytes();
179 Self::from_bytes(LIVE_ID_SEED, bytes, 0, bytes.len())
180 }
181
182 pub const fn from_bytes_lc(seed:u64, id_bytes: &[u8], start: usize, end: usize) -> Self {
183 let mut x = seed;
184 let mut i = start;
185 while i < end {
186 let byte = id_bytes[i];
187 let byte = if byte >= 65 && byte <=90{
188 byte + 32
189 }
190 else{
191 byte
192 };
193 x = x.overflowing_add(byte as u64).0;
194 x ^= x >> 32;
195 x = x.overflowing_mul(0xd6e8_feb8_6659_fd93).0;
196 x ^= x >> 32;
197 x = x.overflowing_mul(0xd6e8_feb8_6659_fd93).0;
198 x ^= x >> 32;
199 i += 1;
200 }
201 Self ((x & 0x7fff_ffff_ffff_ffff) | 0x8000_0000_0000_0000)
203 }
204
205 pub const fn from_str_lc(id_str: &str) -> Self {
206 let bytes = id_str.as_bytes();
207 Self::from_bytes_lc(LIVE_ID_SEED, bytes, 0, bytes.len())
208 }
209
210 pub const fn str_append(self, id_str: &str) -> Self {
211 let bytes = id_str.as_bytes();
212 Self::from_bytes(self.0, bytes, 0, bytes.len())
213 }
214
215 pub const fn bytes_append(self, bytes: &[u8]) -> Self {
216 Self::from_bytes(self.0, bytes, 0, bytes.len())
217 }
218
219 pub const fn id_append(self, id: LiveId) -> Self {
220 let bytes = id.0.to_be_bytes();
221 Self::from_bytes(self.0, &bytes, 0, bytes.len())
222 }
223
224 pub const fn from_str_num(id_str: &str, num:u64) -> Self {
225 let bytes = id_str.as_bytes();
226 let id = Self::from_bytes(LIVE_ID_SEED, bytes, 0, bytes.len());
227 Self::from_bytes(id.0, &num.to_be_bytes(), 0, 8)
228 }
229
230 pub const fn from_num(seed:u64, num:u64) -> Self {
231 Self::from_bytes(seed, &num.to_be_bytes(), 0, 8)
232 }
233
234 pub fn from_str_with_lut(id_str: &str) -> Result<Self,
235 String> {
236 let id = Self::from_str(id_str);
237 LiveIdInterner::with( | idmap | {
238 if let Some(stored) = idmap.id_to_string.get(&id) {
239 if stored != id_str {
240 return Err(stored.clone())
241 }
242 }
243 else {
244 idmap.id_to_string.insert(id, id_str.to_string());
245 }
246 Ok(id)
247 })
248 }
249
250 pub fn from_str_with_intern(id_str: &str, intern:InternLiveId) -> Self{
251 let id = Self::from_str(id_str);
252 if let InternLiveId::Yes = intern{
253 LiveIdInterner::with( | idmap | {idmap.id_to_string.insert(id, id_str.to_string())});
254 }
255 id
256 }
257
258 pub fn from_str_num_with_lut(id_str: &str, num:u64) -> Result<Self,
259 String> {
260 let id = Self::from_str_num(id_str, num);
261 LiveIdInterner::with( | idmap | {
262 idmap.id_to_string.insert(id, format!("{}{}",id_str, num));
263 Ok(id)
264 })
265 }
266
267 pub fn as_string<F, R>(&self, f: F) -> R
268 where F: FnOnce(Option<&str>) -> R
269 {
270 LiveIdInterner::with( | idmap | {
271 match idmap.id_to_string.get(self){
272 Some(v)=>f(Some(v)),
273 None=>f(None)
274 }
275 })
276 }
277
278 pub fn unique() -> Self {
279 LiveId(UNIQUE_LIVE_ID.fetch_add(1, Ordering::SeqCst))
280 }
281}
282
283#[derive(Clone, Copy)]
284pub enum InternLiveId{
285 Yes,
286 No
287}
288
289pub (crate) static UNIQUE_LIVE_ID: AtomicU64 = AtomicU64::new(1);
290impl fmt::Debug for LiveId {
311 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
312 fmt::Display::fmt(self, f)
313 }
314}
315
316impl fmt::Display for LiveId {
317 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
318 if *self == LiveId::empty() {
319 write!(f, "0")
320 }
321 else if self.is_unique(){
322 write!(f, "UniqueId {}", self.0)
323 }
324 else{
325 self.as_string( | string | {
326 if let Some(id) = string {
327 write!(f, "{}", id)
328 }
329 else {
330 write!(f, "{:016x}", self.0)
331 }
332 })
333 }
334 }
335}
336
337impl fmt::LowerHex for LiveId {
338 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
339 fmt::Display::fmt(self, f)
340 }
341}
342
343
344pub struct LiveIdInterner {
345 id_to_string: HashMap<LiveId, String>,
347}
348
349#[derive(Default)]
353pub struct LiveIdHasher(u64);
354
355impl std::hash::Hasher for LiveIdHasher {
356 fn write(&mut self, _: &[u8]) {
357 unreachable!("Invalid use of IdHasher");
358 }
359
360 fn write_u8(&mut self, _n: u8) {
361 unreachable!("Invalid use of IdHasher");
362 }
363 fn write_u16(&mut self, _n: u16) {
364 unreachable!("Invalid use of IdHasher");
365 }
366 fn write_u32(&mut self, _n: u32) {
367 unreachable!("Invalid use of IdHasher");
368 }
369
370 #[inline(always)]
371 fn write_u64(&mut self, n: u64) {
372 self.0 = n;
373 }
374
375 fn write_usize(&mut self, _n: usize) {
376 unreachable!("Invalid use of IdHasher");
377 }
378
379 fn write_i8(&mut self, _n: i8) {
380 unreachable!("Invalid use of IdHasher");
381 }
382 fn write_i16(&mut self, _n: i16) {
383 unreachable!("Invalid use of IdHasher");
384 }
385 fn write_i32(&mut self, _n: i32) {
386 unreachable!("Invalid use of IdHasher");
387 }
388 fn write_i64(&mut self, _n: i64) {
389 unreachable!("Invalid use of IdHasher");
390 }
391 fn write_isize(&mut self, _n: isize) {
392 unreachable!("Invalid use of IdHasher");
393 }
394
395 #[inline(always)]
396 fn finish(&self) -> u64 {
397 self.0
398 }
399}
400
401#[derive(Copy, Clone, Default)]
402pub struct LiveIdHasherBuilder {}
403
404impl std::hash::BuildHasher for LiveIdHasherBuilder {
405 type Hasher = LiveIdHasher;
406
407 #[inline(always)]
408 fn build_hasher(&self) -> LiveIdHasher {
409 LiveIdHasher::default()
410 }
411}
412
413#[derive(Clone, Debug)]
414pub struct LiveIdMap<K, V> {
415 map: HashMap<K, V, LiveIdHasherBuilder>,
416 }
418
419impl<K, V> Default for LiveIdMap<K, V>
420where K: std::cmp::Eq + std::hash::Hash + Copy + From<LiveId> + std::fmt::Debug {
421 fn default() -> Self {
422 Self {
423 map: HashMap::with_hasher(LiveIdHasherBuilder {}),
424 }
426 }
427}
428impl<K, V> Deref for LiveIdMap<K, V>
472where K: std::cmp::Eq + std::hash::Hash + Copy + From<LiveId>
473{
474 type Target = HashMap<K, V, LiveIdHasherBuilder>;
475 fn deref(&self) -> &Self::Target {&self.map}
476}
477
478impl<K, V> DerefMut for LiveIdMap<K, V>
479where K: std::cmp::Eq + std::hash::Hash + Copy + From<LiveId>
480{
481 fn deref_mut(&mut self) -> &mut Self::Target {&mut self.map}
482}
483
484impl<K, V> Index<K> for LiveIdMap<K, V>
485where K: std::cmp::Eq + std::hash::Hash + Copy + From<LiveId>
486{
487 type Output = V;
488 fn index(&self, index: K) -> &Self::Output {
489 self.map.get(&index).unwrap()
490 }
491}
492
493impl<K, V> IndexMut<K> for LiveIdMap<K, V>
494where K: std::cmp::Eq + std::hash::Hash + Copy + From<LiveId>
495{
496 fn index_mut(&mut self, index: K) -> &mut Self::Output {
497 self.map.get_mut(&index).unwrap()
498 }
499}