Skip to main content

rs_eda/engine/
mod.rs

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