1use crate::{
2 error::{BError, MyError},
3 event::EventDispatcher,
4 plugin::PluginOptions,
5 strategy::StrategyOptions,
6};
7use 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 pub fn get_plugins(&self) -> &PluginsMap {
32 &self.plugins
33 }
34 pub fn get_strategys(&self) -> &StrategysMap {
36 &self.strategys
37 }
38 pub fn install<P: PluginOptions + 'static>(&mut self, plugin: P) -> MyError<()> {
40 let name = plugin.name();
41 if !self.plugins.contains_key(name) {
42 let mut deps: Vec<&str> = Vec::new();
46 for dep in plugin.deps() {
47 if !self.plugins.contains_key(dep) {
49 deps.push(dep);
50 }
51 }
52 if !deps.is_empty() {
53 return Err(BError::with_msg(&format!(
55 "安装插件 '{}' 出错:依赖插件 '{}' 不存在",
56 name,
57 deps.join(",")
58 )));
59 }
60
61 let mut plugin_box = Box::new(plugin);
63 plugin_box.install(Arc::clone(&self.event));
64
65 self.plugins
67 .insert(plugin_box.name().to_string(), plugin_box);
68 }
69 Ok(())
70 }
71 pub fn uninstall(&mut self, plugin_name: &str) {
73 if let Some(mut plugin) = self.plugins.remove(plugin_name) {
74 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 for strategy_name in strategies {
83 self.rollback(&strategy_name);
84 }
85
86 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 for plugin_name in plugins {
95 self.uninstall(&plugin_name);
96 }
97
98 plugin.dispose(Arc::clone(&self.event));
100 } else {
101 println!("插件 {} 不存在", plugin_name)
102 }
103 }
104 pub fn exec<S: StrategyOptions + 'static>(&mut self, strategy: S) -> MyError<()> {
106 let name = strategy.name();
107 if !self.strategys.contains_key(name) {
108 let mut plugins: Vec<&str> = Vec::new();
112 for plugin in strategy.condition() {
113 if !self.plugins.contains_key(plugin) {
115 plugins.push(plugin);
116 }
117 }
118 if plugins.len() > 0 {
119 return Err(BError::with_msg(&format!(
121 "执行策略 '{}' 出错:依赖插件 '{}' 不存在",
122 name,
123 plugins.join(",")
124 )));
125 }
126
127 strategy.exec(Arc::clone(&self.event));
129
130 self.strategys
132 .insert(strategy.name().to_string(), Box::new(strategy));
133 }
134
135 Ok(())
136 }
137 pub fn rollback(&mut self, strategy_name: &str) {
139 if let Some(mut strategy) = self.strategys.remove(strategy_name) {
141 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}