mf_state/
resource.rs

1use std::any::Any;
2use std::any::TypeId;
3use std::sync::Arc;
4
5pub trait Resource: Any + Send + Sync + 'static {}
6
7impl dyn Resource {
8    #[inline(always)]
9    fn is<T: Resource>(&self) -> bool {
10        self.type_id() == TypeId::of::<T>()
11    }
12
13    #[inline(always)]
14    #[allow(clippy::needless_lifetimes)]
15    pub fn downcast_arc<'a, T: Resource>(
16        self: &'a Arc<Self>
17    ) -> Option<&'a Arc<T>> {
18        if self.is::<T>() {
19            let ptr = self as *const Arc<_> as *const Arc<T>;
20            // SAFETY: 这个转换是安全的,因为:
21            // 1. 我们通过 `self.is::<T>()` 验证了运行时类型匹配(TypeId 相等)
22            // 2. T 实现了 Resource trait,确保 T: Any + Send + Sync + 'static
23            // 3. Arc<dyn Resource> 和 Arc<T> 具有相同的内存布局和大小
24            //    (Arc 是指针包装器,存储堆上的数据指针和引用计数)
25            // 4. 我们只改变了指针的类型标注,不改变底层数据
26            // 5. 生命周期 'a 保持不变,确保借用检查器的安全性
27            // 6. 返回的是不可变引用,不会破坏内存安全
28            Some(unsafe { &*ptr })
29        } else {
30            None
31        }
32    }
33    #[inline(always)]
34    #[allow(clippy::needless_lifetimes)]
35    pub fn downcast<'a, T: Resource>(&'a self) -> Option<&'a T> {
36        if self.is::<T>() {
37            let ptr = self as *const dyn Resource as *const T;
38            // SAFETY: 这个转换是安全的,因为:
39            // 1. 我们通过 `self.is::<T>()` 验证了运行时类型匹配(TypeId 相等)
40            // 2. T 实现了 Resource trait,确保 T: Any + Send + Sync + 'static
41            // 3. dyn Resource 和 T 的内存布局兼容
42            // 4. 我们只改变了指针的类型标注,不改变底层数据
43            // 5. 生命周期 'a 保持不变,确保借用检查器的安全性
44            // 6. 返回的是不可变引用,不会破坏内存安全
45            Some(unsafe { &*ptr })
46        } else {
47            None
48        }
49    }
50}