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}