Skip to main content

tx_di_core/
registry.rs

1//! 组件注册表 — linkme 编译期收集组件元数据
2//!
3//! `ComponentMeta` 存储核心字段 + 生命周期函数指针。
4//! 生命周期函数指针由宏生成,内部调用 `Component` trait 方法。
5
6use std::any::TypeId;
7use std::sync::Arc;
8
9use crate::component::BoxFuture;
10use crate::scope::Scope;
11use crate::store::{Store, TraitImplEntry};
12use crate::{RIE, App, CancellationToken};
13
14/// linkme 分布式切片:收集所有 `#[derive(Component)]` 标注的组件
15#[linkme::distributed_slice]
16pub static COMPONENT_REGISTRY: [ComponentMeta] = [..];
17
18/// 组件注册元数据(linkme 收集用)
19///
20/// 核心字段 + 生命周期函数指针。
21/// 函数指针由宏生成,内部调用 `<T as Component>::xxx()`,
22/// 解决 ComponentMeta 类型擦除后无法调用 trait 方法的问题。
23pub struct ComponentMeta {
24    // ── 核心字段 ──────────────────────────────────────────────────────
25
26    /// 返回组件类型 `TypeId`
27    pub type_id: fn() -> TypeId,
28
29    /// 组件类型名(调试用)
30    pub name: &'static str,
31
32    /// 依赖类型 ID 列表(用于拓扑排序)
33    pub dep_type_ids: &'static [fn() -> TypeId],
34
35    /// 工厂函数:从 Store 构建组件,返回类型擦除的 Box
36    pub factory: fn(&Store) -> Box<dyn std::any::Any + Send + Sync>,
37
38    /// 作用域
39    pub scope: Scope,
40
41    /// 该组件实现的 trait TypeId 列表
42    pub impl_traits: &'static [fn() -> TypeId],
43
44    /// trait 实现条目列表(用于填充 TRAIT_IMPL_MAP)
45    pub trait_impls: &'static [TraitImplEntry],
46
47    // ── 生命周期函数指针(宏生成,内部调用 Component trait 方法)──────
48
49    /// 初始化排序值(值越小越先执行)
50    pub init_sort_fn: fn() -> i32,
51
52    /// 同步初始化(App 阶段)
53    pub init_fn: fn(&Arc<App>) -> RIE<()>,
54
55    /// 异步初始化(App 阶段)
56    pub async_init_fn: fn(&Arc<App>) -> BoxFuture<RIE<()>>,
57
58    /// 异步运行(后台 task)
59    pub async_run_fn: fn(&Arc<App>, CancellationToken) -> BoxFuture<RIE<()>>,
60
61    /// 优雅关闭
62    pub shutdown_fn: fn(&Store),
63}
64
65impl ComponentMeta {
66    /// 调用工厂函数构建组件实例
67    pub fn build(&self, store: &Store) -> Box<dyn std::any::Any + Send + Sync> {
68        (self.factory)(store)
69    }
70
71    /// 获取组件类型 ID
72    pub fn type_id(&self) -> TypeId {
73        (self.type_id)()
74    }
75
76    /// 获取依赖类型 ID 列表
77    pub fn dep_ids(&self) -> Vec<TypeId> {
78        self.dep_type_ids.iter().map(|f| f()).collect()
79    }
80}