1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
use crate::{AppBuilder, Plugin}; use bevy_utils::{tracing::debug, HashMap}; use std::any::TypeId; pub trait PluginGroup { fn build(&mut self, group: &mut PluginGroupBuilder); } struct PluginEntry { plugin: Box<dyn Plugin>, enabled: bool, } #[derive(Default)] pub struct PluginGroupBuilder { plugins: HashMap<TypeId, PluginEntry>, order: Vec<TypeId>, } impl PluginGroupBuilder { pub fn add<T: Plugin>(&mut self, plugin: T) -> &mut Self { self.order.push(TypeId::of::<T>()); self.plugins.insert( TypeId::of::<T>(), PluginEntry { plugin: Box::new(plugin), enabled: true, }, ); self } pub fn add_before<Target: Plugin, T: Plugin>(&mut self, plugin: T) -> &mut Self { let target_index = self .order .iter() .enumerate() .find(|(_i, ty)| **ty == TypeId::of::<Target>()) .map(|(i, _)| i) .unwrap_or_else(|| { panic!( "Plugin does not exist: {}.", std::any::type_name::<Target>() ) }); self.order.insert(target_index, TypeId::of::<T>()); self.plugins.insert( TypeId::of::<T>(), PluginEntry { plugin: Box::new(plugin), enabled: true, }, ); self } pub fn add_after<Target: Plugin, T: Plugin>(&mut self, plugin: T) -> &mut Self { let target_index = self .order .iter() .enumerate() .find(|(_i, ty)| **ty == TypeId::of::<Target>()) .map(|(i, _)| i) .unwrap_or_else(|| { panic!( "Plugin does not exist: {}.", std::any::type_name::<Target>() ) }); self.order.insert(target_index + 1, TypeId::of::<T>()); self.plugins.insert( TypeId::of::<T>(), PluginEntry { plugin: Box::new(plugin), enabled: true, }, ); self } pub fn enable<T: Plugin>(&mut self) -> &mut Self { let mut plugin_entry = self .plugins .get_mut(&TypeId::of::<T>()) .expect("Cannot enable a plugin that does not exist."); plugin_entry.enabled = true; self } pub fn disable<T: Plugin>(&mut self) -> &mut Self { let mut plugin_entry = self .plugins .get_mut(&TypeId::of::<T>()) .expect("Cannot disable a plugin that does not exist."); plugin_entry.enabled = false; self } pub fn finish(self, app: &mut AppBuilder) { for ty in self.order.iter() { if let Some(entry) = self.plugins.get(ty) { if entry.enabled { debug!("added plugin: {}", entry.plugin.name()); entry.plugin.build(app); } } } } }