Skip to main content

baizekit_app/
component_factory.rs

1use super::application::{ApplicationInner, ComponentKey};
2use super::component::DynComponent;
3use async_trait::async_trait;
4use std::any::TypeId;
5use std::collections::HashSet;
6use std::future::Future;
7use std::sync::{Arc, Mutex};
8
9/// 组件工厂 trait,用于创建组件实例
10#[async_trait]
11pub trait AnyComponentFactory: Send + Sync + 'static {
12    /// 创建组件实例
13    async fn create(&self, inner: Arc<ApplicationInner>, label: String) -> anyhow::Result<Box<dyn DynComponent>>;
14}
15
16/// 组件工厂 trait 的通用实现,适配异步函数
17#[async_trait]
18impl<Comp, F, Fut> AnyComponentFactory for F
19where
20    Comp: DynComponent + 'static,
21    F: Fn(Arc<ApplicationInner>, String) -> Fut + Send + Sync + 'static,
22    Fut: Future<Output = anyhow::Result<Comp>> + Send + 'static,
23{
24    async fn create(&self, inner: Arc<ApplicationInner>, label: String) -> anyhow::Result<Box<dyn DynComponent>> {
25        let comp = self(inner, label).await?;
26        Ok(Box::new(comp) as Box<dyn DynComponent>)
27    }
28}
29
30/// 组件工厂类型别名
31pub type ComponentFactory = Box<dyn AnyComponentFactory>;
32
33/// 组件工厂管理器,负责注册和管理组件工厂
34#[derive(Default)]
35pub struct ComponentFactoryManager {
36    // 存储组件工厂列表和已注册的组件键
37    factories: Mutex<(Vec<(ComponentKey, ComponentFactory)>, HashSet<ComponentKey>)>,
38}
39
40impl ComponentFactoryManager {
41    /// 创建新的组件工厂管理器
42    pub fn new() -> Self {
43        Self::default()
44    }
45
46    /// 注册组件工厂
47    pub fn register_component_factory<Comp, F, Fut>(&self, label: Option<String>, factory: F)
48    where
49        Comp: DynComponent + 'static,
50        F: Fn(Arc<ApplicationInner>, String) -> Fut + Send + Sync + 'static,
51        Fut: Future<Output = anyhow::Result<Comp>> + Send + 'static,
52    {
53        let type_id = TypeId::of::<Comp>();
54        let label = label.map_or_else(|| "default".to_string(), Into::into);
55        let key = ComponentKey { type_id, label };
56
57        // 锁定并检查是否已注册
58        let mut factories = self.factories.lock().expect("Failed to lock factories mutex");
59        if factories.1.contains(&key) {
60            tracing::warn!("组件工厂已注册: {:?}", key);
61            return;
62        }
63
64        // 包装工厂函数为 ComponentFactory
65        let factory_box: ComponentFactory = Box::new(factory);
66
67        // 添加到工厂列表并记录已注册
68        factories.0.push((key.clone(), factory_box));
69        factories.1.insert(key);
70    }
71
72    /// 取出所有工厂并清空内部存储
73    pub fn take_factories(&self) -> (Vec<(ComponentKey, ComponentFactory)>, HashSet<ComponentKey>) {
74        let mut factories = self.factories.lock().expect("Failed to lock factories mutex");
75        (std::mem::take(&mut factories.0), std::mem::take(&mut factories.1))
76    }
77
78    /// 检查组件是否已注册
79    pub fn is_registered(&self, key: &ComponentKey) -> bool {
80        let factories = self.factories.lock().expect("Failed to lock factories mutex");
81        factories.1.contains(key)
82    }
83
84    /// 获取所有已注册组件的键
85    pub fn get_registered_keys(&self) -> Vec<ComponentKey> {
86        let factories = self.factories.lock().expect("Failed to lock factories mutex");
87        factories.1.iter().cloned().collect()
88    }
89}