rs_eda/engine/
mod.rs

1use serde_json::Value;
2
3use crate::{
4    event::EventDispatcher,
5    plugin::PluginOptions,
6    strategy::StrategyOptions,
7    units::error::{BError, MyError},
8};
9use std::collections::HashMap;
10
11type PluginsMap = HashMap<String, Box<dyn PluginOptions>>;
12type StrategysMap = HashMap<String, Box<dyn StrategyOptions>>;
13
14pub struct Engine {
15    pub event: EventDispatcher,
16    plugins: PluginsMap,
17    strategys: StrategysMap,
18}
19
20impl Engine {
21    pub fn new() -> Self {
22        Self {
23            event: EventDispatcher::new(),
24            plugins: HashMap::new(),
25            strategys: HashMap::new(),
26        }
27    }
28    // 获取插件列表
29    pub fn get_plugins(&self) -> &PluginsMap {
30        &self.plugins
31    }
32    // 获取指定插件数据
33    pub fn plugin_data(&self, name: &str) -> Option<Value> {
34        if let Some(x) = self.plugins.get(name) {
35            x.get_data()
36        } else {
37            println!("插件{}不存在", name);
38            None
39        }
40    }
41    // 获取策略列表
42    pub fn get_strategys(&self) -> &StrategysMap {
43        &self.strategys
44    }
45    // 获取指定策略数据
46    pub fn strategy_data(&self, name: &str) -> Option<Value> {
47        if let Some(x) = self.strategys.get(name) {
48            x.get_data()
49        } else {
50            println!("策略{}不存在", name);
51            None
52        }
53    }
54    // 安装插件
55    pub fn install<P: PluginOptions + 'static>(&mut self, plugin: P) -> MyError<()> {
56        let name = plugin.name();
57        if !self.plugins.contains_key(name) {
58            // 不存在对应的插件
59
60            // 检查插件依赖
61            let mut deps: Vec<&str> = Vec::new();
62            for dep in plugin.deps() {
63                // 依赖插件不存在
64                if !self.plugins.contains_key(dep) {
65                    deps.push(dep);
66                }
67            }
68            if !deps.is_empty() {
69                // 提示错误
70                return Err(BError::with_msg(&format!(
71                    "安装插件 '{}' 出错:依赖插件 '{}' 不存在",
72                    name,
73                    deps.join(",")
74                )));
75            }
76
77            // 执行插件安装方法
78            let mut plugin_box = Box::new(plugin);
79            plugin_box.install(self);
80
81            // 记录插件
82            self.plugins
83                .insert(plugin_box.name().to_string(), plugin_box);
84        }
85        Ok(())
86    }
87    // 卸载插件
88    pub fn uninstall(&mut self, plugin_name: &str) {
89        if let Some(mut plugin) = self.plugins.remove(plugin_name) {
90            // 策略B依赖插件A,插件A被卸载,关联的策略B也要被回滚
91            let mut strategies = Vec::new();
92            for (_, strategy) in self.strategys.iter() {
93                if strategy.condition().contains(&plugin_name) {
94                    strategies.push(strategy.name().to_string());
95                }
96            }
97            // 执行回滚操作
98            for strategy_name in strategies {
99                self.rollback(&strategy_name);
100            }
101
102            // 插件B依赖插件A,插件A被卸载,关联的插件B也要被卸载
103            let mut plugins = Vec::new();
104            for (_, plugin) in self.plugins.iter() {
105                if plugin.deps().contains(&plugin_name) {
106                    plugins.push(plugin.name().to_string());
107                }
108            }
109            // 执行关键插件的卸载
110            for plugin_name in plugins {
111                self.uninstall(&plugin_name);
112            }
113
114            // 执行销毁方法
115            plugin.dispose(self);
116        } else {
117            println!("插件 {} 不存在", plugin_name)
118        }
119    }
120    // 执行策略
121    pub fn exec<S: StrategyOptions + 'static>(&mut self, strategy: S) -> MyError<()> {
122        let name = strategy.name();
123        if !self.strategys.contains_key(name) {
124            // 不存在对应的策略
125
126            // 检查策略依赖
127            let mut plugins: Vec<&str> = Vec::new();
128            for plugin in strategy.condition() {
129                // 依赖插件不存在,记录起来
130                if !self.plugins.contains_key(plugin) {
131                    plugins.push(plugin);
132                }
133            }
134            if plugins.len() > 0 {
135                // 提示错误
136                return Err(BError::with_msg(&format!(
137                    "执行策略 '{}' 出错:依赖插件 '{}' 不存在",
138                    name,
139                    plugins.join(",")
140                )));
141            }
142
143            // 执行策略
144            strategy.exec(self);
145
146            // 记录策略
147            self.strategys
148                .insert(strategy.name().to_string(), Box::new(strategy));
149        }
150
151        Ok(())
152    }
153    // 回滚策略
154    pub fn rollback(&mut self, strategy_name: &str) {
155        // 找到与name对应的策略并删除
156        if let Some(mut strategy) = self.strategys.remove(strategy_name) {
157            // 执行回滚方法
158            strategy.rollback(self);
159        } else {
160            println!("策略 {} 不存在", strategy_name)
161        }
162    }
163}
164
165#[cfg(test)]
166mod tests {
167    use super::Engine;
168    use crate::plugin::{TestAPlugin, TestBPlugin};
169
170    #[test]
171    fn test_fun() {
172        let mut engine = Engine::new();
173        engine.install(TestAPlugin::new()).unwrap();
174        engine.install(TestBPlugin::new()).unwrap();
175
176        let test_afun = |_x| {};
177        let test_bfun = |_x| {};
178        engine.event.on("test", Some(test_afun));
179        engine.event.on("test", Some(test_bfun));
180
181        println!("--1---{}--", engine.event.event_count("test"));
182
183        // engine.event.off("test", None);
184        // println!("--2---{}--", engine.event.event_count("test"));
185
186        println!("--3---{}--", engine.event.has("test", None));
187    }
188}