baizekit_app/
component_factory.rs1use 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#[async_trait]
11pub trait AnyComponentFactory: Send + Sync + 'static {
12 async fn create(&self, inner: Arc<ApplicationInner>, label: String) -> anyhow::Result<Box<dyn DynComponent>>;
14}
15
16#[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
30pub type ComponentFactory = Box<dyn AnyComponentFactory>;
32
33#[derive(Default)]
35pub struct ComponentFactoryManager {
36 factories: Mutex<(Vec<(ComponentKey, ComponentFactory)>, HashSet<ComponentKey>)>,
38}
39
40impl ComponentFactoryManager {
41 pub fn new() -> Self {
43 Self::default()
44 }
45
46 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 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 let factory_box: ComponentFactory = Box::new(factory);
66
67 factories.0.push((key.clone(), factory_box));
69 factories.1.insert(key);
70 }
71
72 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 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 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}