rs_eda/engine/
mod.rs

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