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