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        self.index
78            .get(&rid)
79            .map(|rc| rc.value().clone())
80            .and_then(|rc| rc.downcast_arc::<T>().cloned())
81    }
82
83    // 获取指定ID的任意类型资源
84    pub fn get_any(
85        &self,
86        rid: ResourceId,
87    ) -> Option<Arc<dyn Resource>> {
88        self.index.get(&rid).map(|rc| rc.value().clone())
89    }
90
91    // 从资源表中移除并返回指定ID的特定类型资源
92    pub fn take<T: Resource>(
93        &self,
94        rid: ResourceId,
95    ) -> Option<Arc<T>> {
96        let (_, resource) = self.index.remove(&rid)?;
97        resource.downcast_arc::<T>().cloned()
98    }
99
100    // 从资源表中移除并返回指定ID的任意类型资源
101    pub fn take_any(
102        &self,
103        rid: ResourceId,
104    ) -> Option<Arc<dyn Resource>> {
105        self.index.remove(&rid).map(|rc| rc.1)
106    }
107}
108
109// 资源错误类型定义
110#[derive(Debug, thiserror::Error)]
111pub enum ResourceError {
112    #[error("null or invalid handle")]
113    Reference,
114    #[error("Bad resource ID")]
115    BadResourceId,
116    #[error("Resource is unavailable because it is in use by a promise")]
117    Unavailable,
118    #[error("{0}")]
119    Other(String),
120}