mf_state/
resource_table.rs

1use std::sync::Arc;
2use std::fmt::{self, Debug};
3
4use dashmap::DashMap;
5
6use crate::resource::Resource;
7
8// 资源ID类型定义
9pub type ResourceId = String;
10
11// 资源表结构体,用于管理所有资源
12#[derive(Default)]
13pub struct ResourceTable {
14    // 使用BTreeMap存储资源ID到资源的映射
15    index: DashMap<ResourceId, Arc<dyn Resource>>,
16}
17impl Debug for ResourceTable {
18    fn fmt(
19        &self,
20        f: &mut fmt::Formatter<'_>,
21    ) -> fmt::Result {
22        write!(f, "ResourceTable {{ len: {} }}", self.index.len())
23    }
24}
25impl ResourceTable {
26    // 获取资源表中资源的数量
27    pub fn len(&self) -> usize {
28        self.index.len()
29    }
30
31    // 检查资源表是否为空
32    pub fn is_empty(&self) -> bool {
33        self.index.is_empty()
34    }
35
36    // 添加一个新资源到资源表,返回分配的资源ID
37    pub fn add<T: Resource>(
38        &self,
39        rid: ResourceId,
40        resource: T,
41    ) {
42        self.add_arc(rid, Arc::new(resource));
43    }
44
45    // 添加一个Arc包装的资源到资源表
46    pub fn add_arc<T: Resource>(
47        &self,
48        rid: ResourceId,
49        resource: Arc<T>,
50    ) {
51        let resource = resource as Arc<dyn Resource>;
52        self.add_arc_dyn(rid, resource);
53    }
54
55    // 添加一个动态类型的Arc资源到资源表
56    pub fn add_arc_dyn(
57        &self,
58        rid: ResourceId,
59        resource: Arc<dyn Resource>,
60    ) {
61        self.index.insert(rid, resource);
62    }
63
64    // 检查指定ID的资源是否存在
65    pub fn has(
66        &self,
67        rid: ResourceId,
68    ) -> bool {
69        self.index.contains_key(&rid)
70    }
71
72    // 获取指定ID的特定类型资源
73    pub fn get<T: Resource>(
74        &self,
75        rid: ResourceId,
76    ) -> Option<Arc<T>> {
77        let data = self
78            .index
79            .get(&rid)
80            .map(|rc| rc.value().clone())
81            .and_then(|rc| rc.downcast_arc::<T>().cloned());
82        data
83    }
84
85    // 获取指定ID的任意类型资源
86    pub fn get_any(
87        &self,
88        rid: ResourceId,
89    ) -> Option<Arc<dyn Resource>> {
90        self.index.get(&rid).map(|rc| rc.value().clone())
91    }
92
93    // 从资源表中移除并返回指定ID的特定类型资源
94    pub fn take<T: Resource>(
95        &self,
96        rid: ResourceId,
97    ) -> Option<Arc<T>> {
98        let (_, resource) = self.index.remove(&rid)?;
99        match resource.downcast_arc::<T>() {
100            Some(resource) => Some(resource.clone()),
101            None => None,
102        }
103    }
104
105    // 从资源表中移除并返回指定ID的任意类型资源
106    pub fn take_any(
107        &self,
108        rid: ResourceId,
109    ) -> Option<Arc<dyn Resource>> {
110        self.index.remove(&rid).map(|rc| rc.1)
111    }
112}
113
114// 资源错误类型定义
115#[derive(Debug, thiserror::Error)]
116pub enum ResourceError {
117    #[error("null or invalid handle")]
118    Reference,
119    #[error("Bad resource ID")]
120    BadResourceId,
121    #[error("Resource is unavailable because it is in use by a promise")]
122    Unavailable,
123    #[error("{0}")]
124    Other(String),
125}