1use crate::reflect::ReflectHandle;
22use crate::{
23 combine_uuids, pool::INVALID_GENERATION, reflect::prelude::*, uuid_provider,
24 visitor::prelude::*, TypeUuidProvider,
25};
26use serde::{Deserialize, Serialize};
27use std::any::{type_name, Any, TypeId};
28use std::{
29 cmp::Ordering,
30 fmt::{Debug, Display, Formatter},
31 hash::{Hash, Hasher},
32 marker::PhantomData,
33 sync::atomic::{self, AtomicUsize},
34};
35use uuid::Uuid;
36
37#[derive(Serialize, Deserialize)]
41pub struct Handle<T> {
42 pub(super) index: u32,
44 pub(super) generation: u32,
47 #[serde(skip)]
49 pub(super) type_marker: PhantomData<T>,
50}
51
52impl<T: Reflect> ReflectHandle for Handle<T> {
53 fn reflect_inner_type_id(&self) -> TypeId {
54 TypeId::of::<T>()
55 }
56
57 fn reflect_inner_type_name(&self) -> &'static str {
58 type_name::<T>()
59 }
60
61 fn reflect_is_some(&self) -> bool {
62 self.is_some()
63 }
64
65 fn reflect_set_index(&mut self, index: u32) {
66 self.index = index;
67 }
68
69 fn reflect_index(&self) -> u32 {
70 self.index
71 }
72
73 fn reflect_set_generation(&mut self, generation: u32) {
74 self.generation = generation;
75 }
76
77 fn reflect_generation(&self) -> u32 {
78 self.generation
79 }
80
81 fn reflect_as_erased(&self) -> ErasedHandle {
82 ErasedHandle::new(self.index, self.generation)
83 }
84}
85
86static INDEX_METADATA: FieldMetadata = FieldMetadata {
87 name: "Index",
88 display_name: "Index",
89 tag: "",
90 read_only: false,
91 immutable_collection: false,
92 min_value: None,
93 max_value: None,
94 step: None,
95 precision: None,
96 doc: "",
97};
98
99static GENERATION_METADATA: FieldMetadata = FieldMetadata {
100 name: "Generation",
101 display_name: "Generation",
102 tag: "",
103 read_only: false,
104 immutable_collection: false,
105 min_value: None,
106 max_value: None,
107 step: None,
108 precision: None,
109 doc: "",
110};
111
112impl<T: Reflect> Reflect for Handle<T> {
113 fn source_path() -> &'static str {
114 file!()
115 }
116
117 fn derived_types() -> &'static [TypeId]
118 where
119 Self: Sized,
120 {
121 T::derived_types()
122 }
123
124 fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
125 Some(Box::new(*self))
126 }
127
128 fn query_derived_types(&self) -> &'static [TypeId] {
129 Self::derived_types()
130 }
131
132 fn type_name(&self) -> &'static str {
133 type_name::<Self>()
134 }
135
136 fn doc(&self) -> &'static str {
137 ""
138 }
139
140 fn assembly_name(&self) -> &'static str {
141 env!("CARGO_PKG_NAME")
142 }
143
144 fn type_assembly_name() -> &'static str {
145 env!("CARGO_PKG_NAME")
146 }
147
148 fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
149 func(&[
150 {
151 FieldRef {
152 metadata: &INDEX_METADATA,
153 value: &self.index,
154 }
155 },
156 {
157 FieldRef {
158 metadata: &GENERATION_METADATA,
159 value: &self.generation,
160 }
161 },
162 ])
163 }
164
165 fn fields_mut(&mut self, func: &mut dyn FnMut(&mut [FieldMut])) {
166 func(&mut [
167 {
168 FieldMut {
169 metadata: &INDEX_METADATA,
170 value: &mut self.index,
171 }
172 },
173 {
174 FieldMut {
175 metadata: &GENERATION_METADATA,
176 value: &mut self.generation,
177 }
178 },
179 ])
180 }
181
182 fn into_any(self: Box<Self>) -> Box<dyn Any> {
183 self
184 }
185
186 fn as_any(&self, func: &mut dyn FnMut(&dyn Any)) {
187 func(self)
188 }
189
190 fn as_any_mut(&mut self, func: &mut dyn FnMut(&mut dyn Any)) {
191 func(self)
192 }
193
194 fn as_reflect(&self, func: &mut dyn FnMut(&dyn Reflect)) {
195 func(self)
196 }
197
198 fn as_reflect_mut(&mut self, func: &mut dyn FnMut(&mut dyn Reflect)) {
199 func(self)
200 }
201
202 fn set(&mut self, value: Box<dyn Reflect>) -> Result<Box<dyn Reflect>, Box<dyn Reflect>> {
203 let this = std::mem::replace(self, value.take()?);
204 Ok(Box::new(this))
205 }
206
207 fn as_handle(&self, func: &mut dyn FnMut(Option<&dyn ReflectHandle>)) {
208 func(Some(self))
209 }
210
211 fn as_handle_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectHandle>)) {
212 func(Some(self))
213 }
214}
215
216impl<T> Copy for Handle<T> {}
217
218impl<T> Eq for Handle<T> {}
219
220impl<T> PartialEq for Handle<T> {
221 #[inline]
222 fn eq(&self, other: &Handle<T>) -> bool {
223 self.generation == other.generation && self.index == other.index
224 }
225}
226
227impl<T> Hash for Handle<T> {
228 #[inline]
229 fn hash<H>(&self, state: &mut H)
230 where
231 H: Hasher,
232 {
233 self.index.hash(state);
234 self.generation.hash(state);
235 }
236}
237
238impl<T> Handle<T> {
239 pub const NONE: Handle<T> = Handle {
240 index: 0,
241 generation: INVALID_GENERATION,
242 type_marker: PhantomData,
243 };
244
245 #[inline(always)]
246 pub fn is_none(self) -> bool {
247 self.index == 0 && self.generation == INVALID_GENERATION
248 }
249
250 #[inline(always)]
251 pub fn is_some(self) -> bool {
252 !self.is_none()
253 }
254
255 #[inline(always)]
256 pub fn index(self) -> u32 {
257 self.index
258 }
259
260 #[inline(always)]
261 pub fn generation(self) -> u32 {
262 self.generation
263 }
264
265 #[inline(always)]
266 pub fn new(index: u32, generation: u32) -> Self {
267 Handle {
268 index,
269 generation,
270 type_marker: PhantomData,
271 }
272 }
273
274 #[inline(always)]
275 pub fn transmute<U>(&self) -> Handle<U> {
276 Handle {
277 index: self.index,
278 generation: self.generation,
279 type_marker: Default::default(),
280 }
281 }
282
283 #[inline(always)]
284 pub fn decode_from_u128(num: u128) -> Self {
285 Self {
286 index: num as u32,
287 generation: (num >> 32) as u32,
288 type_marker: Default::default(),
289 }
290 }
291
292 #[inline(always)]
293 pub fn encode_to_u128(&self) -> u128 {
294 (self.index as u128) | ((self.generation as u128) << 32)
295 }
296}
297
298impl<T> TypeUuidProvider for Handle<T>
299where
300 T: TypeUuidProvider,
301{
302 #[inline]
303 fn type_uuid() -> Uuid {
304 combine_uuids(
305 uuid::uuid!("30c0668d-7a2c-47e6-8c7b-208fdcc905a1"),
306 T::type_uuid(),
307 )
308 }
309}
310
311impl<T> PartialOrd for Handle<T> {
312 #[inline]
313 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
314 Some(self.cmp(other))
315 }
316}
317
318impl<T> Ord for Handle<T> {
319 #[inline]
320 fn cmp(&self, other: &Self) -> Ordering {
321 self.index.cmp(&other.index)
322 }
323}
324
325unsafe impl<T> Send for Handle<T> {}
326unsafe impl<T> Sync for Handle<T> {}
327
328impl<T> Display for Handle<T> {
329 #[inline]
330 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
331 write!(f, "{}:{}", self.index, self.generation)
332 }
333}
334
335pub struct AtomicHandle(AtomicUsize);
337
338impl Clone for AtomicHandle {
339 #[inline]
340 fn clone(&self) -> Self {
341 Self(AtomicUsize::new(self.0.load(atomic::Ordering::Relaxed)))
342 }
343}
344
345impl Default for AtomicHandle {
346 #[inline]
347 fn default() -> Self {
348 Self::none()
349 }
350}
351
352impl AtomicHandle {
353 #[inline]
354 pub fn none() -> Self {
355 Self(AtomicUsize::new(0))
356 }
357
358 #[inline]
359 pub fn new(index: u32, generation: u32) -> Self {
360 let handle = Self(AtomicUsize::new(0));
361 handle.set(index, generation);
362 handle
363 }
364
365 #[inline]
366 pub fn set(&self, index: u32, generation: u32) {
367 let index = (index as usize) << (usize::BITS / 2) >> (usize::BITS / 2);
368 let generation = (generation as usize) << (usize::BITS / 2);
369 self.0.store(index | generation, atomic::Ordering::Relaxed);
370 }
371
372 #[inline]
373 pub fn set_from_handle<T>(&self, handle: Handle<T>) {
374 self.set(handle.index, handle.generation)
375 }
376
377 #[inline(always)]
378 pub fn is_some(&self) -> bool {
379 self.generation() != INVALID_GENERATION
380 }
381
382 #[inline(always)]
383 pub fn is_none(&self) -> bool {
384 !self.is_some()
385 }
386
387 #[inline]
388 pub fn index(&self) -> u32 {
389 let bytes = self.0.load(atomic::Ordering::Relaxed);
390 ((bytes << (usize::BITS / 2)) >> (usize::BITS / 2)) as u32
391 }
392
393 #[inline]
394 pub fn generation(&self) -> u32 {
395 let bytes = self.0.load(atomic::Ordering::Relaxed);
396 (bytes >> (usize::BITS / 2)) as u32
397 }
398}
399
400impl Display for AtomicHandle {
401 #[inline]
402 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
403 write!(f, "{}:{}", self.index(), self.generation())
404 }
405}
406
407impl Debug for AtomicHandle {
408 #[inline]
409 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
410 write!(f, "[Idx: {}; Gen: {}]", self.index(), self.generation())
411 }
412}
413
414#[derive(
416 Copy, Clone, Debug, Ord, PartialOrd, PartialEq, Eq, Hash, Reflect, Visit, Serialize, Deserialize,
417)]
418pub struct ErasedHandle {
419 #[reflect(read_only)]
421 index: u32,
422 #[reflect(read_only)]
425 generation: u32,
426}
427
428uuid_provider!(ErasedHandle = "50131acc-8b3b-40b5-b495-e2c552c94db3");
429
430impl Display for ErasedHandle {
431 #[inline]
432 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
433 write!(f, "{}:{}", self.index, self.generation)
434 }
435}
436
437impl Default for ErasedHandle {
438 #[inline]
439 fn default() -> Self {
440 Self::none()
441 }
442}
443
444impl<T> From<ErasedHandle> for Handle<T> {
445 #[inline]
446 fn from(erased_handle: ErasedHandle) -> Self {
447 Handle {
448 index: erased_handle.index,
449 generation: erased_handle.generation,
450 type_marker: PhantomData,
451 }
452 }
453}
454
455impl<T> From<AtomicHandle> for Handle<T> {
456 #[inline]
457 fn from(atomic_handle: AtomicHandle) -> Self {
458 Handle {
459 index: atomic_handle.index(),
460 generation: atomic_handle.generation(),
461 type_marker: PhantomData,
462 }
463 }
464}
465
466impl<T> From<Handle<T>> for ErasedHandle {
467 #[inline]
468 fn from(h: Handle<T>) -> Self {
469 Self {
470 index: h.index,
471 generation: h.generation,
472 }
473 }
474}
475
476impl ErasedHandle {
477 #[inline]
478 pub fn none() -> Self {
479 Self {
480 index: 0,
481 generation: INVALID_GENERATION,
482 }
483 }
484
485 #[inline]
486 pub fn new(index: u32, generation: u32) -> Self {
487 Self { index, generation }
488 }
489
490 #[inline(always)]
491 pub fn is_some(&self) -> bool {
492 self.generation != INVALID_GENERATION
493 }
494
495 #[inline(always)]
496 pub fn is_none(&self) -> bool {
497 !self.is_some()
498 }
499
500 #[inline(always)]
501 pub fn index(self) -> u32 {
502 self.index
503 }
504
505 #[inline(always)]
506 pub fn generation(self) -> u32 {
507 self.generation
508 }
509}
510
511impl<T> Visit for Handle<T> {
512 #[inline]
513 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
514 let mut region = visitor.enter_region(name)?;
515
516 self.index.visit("Index", &mut region)?;
517 self.generation.visit("Generation", &mut region)?;
518
519 Ok(())
520 }
521}
522
523impl<T> Default for Handle<T> {
524 #[inline]
525 fn default() -> Self {
526 Self::NONE
527 }
528}
529
530impl<T> Debug for Handle<T> {
531 #[inline]
532 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
533 write!(f, "[Idx: {}; Gen: {}]", self.index, self.generation)
534 }
535}
536
537#[cfg(test)]
538mod test {
539 use crate::{
540 pool::{AtomicHandle, ErasedHandle, Handle, INVALID_GENERATION},
541 visitor::{Visit, Visitor},
542 };
543
544 #[test]
545 fn test_handle_u128_encode_decode() {
546 let a = Handle::<()>::new(123, 321);
547 let encoded = a.encode_to_u128();
548 let decoded = Handle::<()>::decode_from_u128(encoded);
549 assert_eq!(decoded, a);
550 }
551
552 #[test]
553 fn erased_handle_none() {
554 assert_eq!(
555 ErasedHandle::none(),
556 ErasedHandle {
557 index: 0,
558 generation: INVALID_GENERATION,
559 }
560 );
561 }
562
563 #[test]
564 fn erased_handle_new() {
565 assert_eq!(
566 ErasedHandle::new(0, 1),
567 ErasedHandle {
568 index: 0,
569 generation: 1,
570 }
571 );
572 }
573
574 #[test]
575 fn erased_handle_is_some() {
576 assert!(ErasedHandle::new(0, 1).is_some());
577 assert!(!ErasedHandle::none().is_some());
578 }
579
580 #[test]
581 fn erased_handle_is_none() {
582 assert!(!ErasedHandle::new(0, 1).is_none());
583 assert!(ErasedHandle::none().is_none());
584 }
585
586 #[test]
587 fn erased_handle_index() {
588 assert_eq!(
589 ErasedHandle {
590 index: 42,
591 generation: 15
592 }
593 .index(),
594 42
595 );
596 }
597
598 #[test]
599 fn erased_handle_generation() {
600 assert_eq!(
601 ErasedHandle {
602 index: 42,
603 generation: 15
604 }
605 .generation(),
606 15
607 );
608 }
609
610 #[test]
611 fn default_for_erased_handle() {
612 assert_eq!(ErasedHandle::default(), ErasedHandle::none());
613 }
614
615 #[test]
616 fn erased_handle_from_handle() {
617 let handle = Handle::<u32> {
618 index: 0,
619 generation: 1,
620 type_marker: std::marker::PhantomData,
621 };
622
623 assert_eq!(
624 ErasedHandle::from(handle),
625 ErasedHandle {
626 index: 0,
627 generation: 1
628 }
629 );
630 }
631
632 #[test]
633 fn handle_from_erased_handle() {
634 let er = ErasedHandle {
635 index: 0,
636 generation: 1,
637 };
638
639 assert_eq!(
640 Handle::from(er),
641 Handle::<u32> {
642 index: 0,
643 generation: 1,
644 type_marker: std::marker::PhantomData,
645 }
646 );
647 }
648
649 #[test]
650 fn default_for_handle() {
651 assert_eq!(Handle::default(), Handle::<u32>::NONE);
652 }
653
654 #[test]
655 fn visit_for_handle() {
656 let mut h = Handle::<u32>::default();
657 let mut visitor = Visitor::default();
658
659 assert!(h.visit("name", &mut visitor).is_ok());
660 }
661
662 #[test]
663 fn test_debug_for_handle() {
664 let h = Handle::<u32> {
665 index: 0,
666 generation: 1,
667 type_marker: std::marker::PhantomData,
668 };
669
670 assert_eq!(format!("{h:?}"), "[Idx: 0; Gen: 1]");
671 }
672
673 #[test]
674 fn handle_getters() {
675 let h = Handle::<u32> {
676 index: 0,
677 generation: 1,
678 type_marker: std::marker::PhantomData,
679 };
680
681 assert_eq!(h.index(), 0);
682 assert_eq!(h.generation(), 1);
683 }
684
685 #[test]
686 fn handle_transmute() {
687 assert_eq!(
688 Handle::<u32>::default().transmute::<f32>(),
689 Handle::<f32>::default()
690 );
691 }
692
693 #[test]
694 fn test_atomic_handle() {
695 let handle = AtomicHandle::new(123, 321);
696 assert!(handle.is_some());
697 assert_eq!(handle.index(), 123);
698 assert_eq!(handle.generation(), 321);
699
700 let handle = AtomicHandle::default();
701 assert!(handle.is_none());
702 }
703}