mf_core/runtime/
runtime_trait.rs

1//! 运行时统一接口定义
2//!
3//! 此模块定义了 RuntimeTrait,为三种运行时实现提供统一接口:
4//! - ForgeRuntime (同步运行时)
5//! - ForgeActorRuntime (Actor运行时)
6//! - ForgeAsyncRuntime (异步运行时)
7//!
8//! 通过统一接口,用户可以:
9//! 1. 轻松切换不同运行时实现
10//! 2. 编写运行时无关的业务逻辑
11//! 3. 使用trait对象实现运行时抽象
12
13use std::sync::Arc;
14
15use async_trait::async_trait;
16use mf_model::{node_pool::NodePool, schema::Schema};
17use mf_state::{
18    state::State,
19    transaction::{Command, Transaction},
20};
21
22use crate::{config::ForgeConfig, types::RuntimeOptions, ForgeResult};
23
24/// 运行时统一接口
25///
26/// 定义了所有运行时实现必须提供的核心功能。
27/// 所有方法都是异步的,以支持不同的执行模型。
28///
29/// # 设计原则
30///
31/// 1. **接口最小化**: 只包含核心必需方法
32/// 2. **异步优先**: 所有方法异步,兼容三种运行时
33/// 3. **错误统一**: 使用 ForgeResult 统一错误处理
34/// 4. **状态不可变**: 返回 Arc<State> 避免克隆
35///
36/// # 使用示例
37///
38/// ```rust
39/// use mf_core::{ForgeRuntime, RuntimeTrait};
40///
41/// async fn process_with_runtime(runtime: &mut dyn RuntimeTrait) -> ForgeResult<()> {
42///     let state = runtime.get_state().await?;
43///     let mut tr = runtime.get_tr().await?;
44///
45///     // ... 修改事务 ...
46///
47///     runtime.dispatch(tr).await?;
48///     Ok(())
49/// }
50/// ```
51#[async_trait]
52pub trait RuntimeTrait: Send {
53    // ==================== 核心事务操作 ====================
54
55    /// 分发事务到运行时处理
56    ///
57    /// 这是运行时的核心方法,负责:
58    /// 1. 执行前置中间件
59    /// 2. 应用事务到状态
60    /// 3. 触发插件的 append_transaction
61    /// 4. 执行后置中间件
62    /// 5. 更新状态和历史
63    /// 6. 广播事件
64    ///
65    /// # 参数
66    /// * `transaction` - 要处理的事务
67    ///
68    /// # 返回值
69    /// * `ForgeResult<()>` - 处理结果
70    async fn dispatch(
71        &mut self,
72        transaction: Transaction,
73    ) -> ForgeResult<()>;
74
75    /// 分发事务(包含元信息)
76    ///
77    /// 与 dispatch 相同,但可以附加描述和元数据,用于:
78    /// - 历史记录的可读性
79    /// - 审计日志
80    /// - 撤销/重做时的显示
81    ///
82    /// # 参数
83    /// * `transaction` - 要处理的事务
84    /// * `description` - 事务描述(用于历史记录)
85    /// * `meta` - 元数据(JSON格式)
86    async fn dispatch_with_meta(
87        &mut self,
88        transaction: Transaction,
89        description: String,
90        meta: serde_json::Value,
91    ) -> ForgeResult<()>;
92
93    /// 执行命令
94    ///
95    /// 命令是对事务的高级封装,提供:
96    /// - 类型安全的操作
97    /// - 可复用的业务逻辑
98    /// - 更好的测试性
99    ///
100    /// # 参数
101    /// * `command` - 要执行的命令
102    async fn command(
103        &mut self,
104        command: Arc<dyn Command>,
105    ) -> ForgeResult<()>;
106
107    /// 执行命令(包含元信息)
108    async fn command_with_meta(
109        &mut self,
110        command: Arc<dyn Command>,
111        description: String,
112        meta: serde_json::Value,
113    ) -> ForgeResult<()>;
114
115    // ==================== 状态访问 ====================
116
117    /// 获取当前状态
118    ///
119    /// 返回不可变状态引用,避免克隆开销。
120    /// 状态是快照,读取时不会被其他操作修改。
121    async fn get_state(&self) -> ForgeResult<Arc<State>>;
122
123    /// 获取新事务
124    ///
125    /// 基于当前状态创建新事务,用于构建编辑操作。
126    async fn get_tr(&self) -> ForgeResult<Transaction>;
127
128    /// 获取文档
129    ///
130    /// 快捷方法,等同于 `get_state().await?.doc()`
131    async fn doc(&self) -> ForgeResult<Arc<NodePool>> {
132        Ok(self.get_state().await?.doc())
133    }
134
135    /// 获取Schema
136    ///
137    /// 返回文档结构定义
138    async fn get_schema(&self) -> ForgeResult<Arc<Schema>>;
139
140    // ==================== 历史管理 ====================
141
142    /// 撤销操作
143    ///
144    /// 回退到上一个历史状态
145    async fn undo(&mut self) -> ForgeResult<()>;
146
147    /// 重做操作
148    ///
149    /// 前进到下一个历史状态
150    async fn redo(&mut self) -> ForgeResult<()>;
151
152    /// 跳转到指定历史位置
153    ///
154    /// # 参数
155    /// * `steps` - 跳转步数(正数前进,负数后退)
156    async fn jump(
157        &mut self,
158        steps: isize,
159    ) -> ForgeResult<()>;
160
161    // ==================== 配置管理 ====================
162
163    /// 获取运行时配置
164    fn get_config(&self) -> &ForgeConfig;
165
166    /// 更新运行时配置
167    fn update_config(
168        &mut self,
169        config: ForgeConfig,
170    );
171
172    /// 获取运行时选项
173    fn get_options(&self) -> &RuntimeOptions;
174
175    // ==================== 生命周期管理 ====================
176
177    /// 销毁运行时
178    ///
179    /// 清理所有资源,包括:
180    /// - 停止事件循环
181    /// - 关闭Actor系统(如果适用)
182    /// - 释放异步资源(如果适用)
183    async fn destroy(&mut self) -> ForgeResult<()>;
184}
185
186/// 运行时工厂 trait
187///
188/// 提供统一的运行时创建接口
189#[async_trait]
190pub trait RuntimeFactory {
191    /// 运行时类型
192    type Runtime: RuntimeTrait;
193
194    /// 创建运行时实例
195    ///
196    /// # 参数
197    /// * `options` - 运行时选项
198    ///
199    /// # 返回值
200    /// * `ForgeResult<Self::Runtime>` - 运行时实例
201    async fn create(options: RuntimeOptions) -> ForgeResult<Self::Runtime>;
202
203    /// 使用配置创建运行时实例
204    ///
205    /// # 参数
206    /// * `options` - 运行时选项
207    /// * `config` - 运行时配置
208    async fn create_with_config(
209        options: RuntimeOptions,
210        config: ForgeConfig,
211    ) -> ForgeResult<Self::Runtime>;
212
213    /// 从XML Schema创建运行时
214    ///
215    /// # 参数
216    /// * `xml_schema_path` - XML Schema文件路径
217    /// * `options` - 可选的运行时选项
218    /// * `config` - 可选的运行时配置
219    async fn from_xml_schema_path(
220        xml_schema_path: &str,
221        options: Option<RuntimeOptions>,
222        config: Option<ForgeConfig>,
223    ) -> ForgeResult<Self::Runtime>;
224}
225
226#[cfg(test)]
227mod tests {
228    use super::*;
229
230    // 测试 RuntimeTrait 是否是对象安全的(可以用作 trait 对象)
231    #[test]
232    fn test_runtime_trait_object_safety() {
233        // 如果这段代码能编译通过,说明 RuntimeTrait 是对象安全的
234        fn _accept_runtime_trait(_runtime: &dyn RuntimeTrait) {}
235    }
236}