2020-10-29 20:04:28 +00:00
|
|
|
use crate::{AppBuilder, Plugin};
|
2020-11-13 01:23:57 +00:00
|
|
|
use bevy_utils::{tracing::debug, HashMap};
|
2020-10-29 20:04:28 +00:00
|
|
|
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 {
|
2020-11-13 01:23:57 +00:00
|
|
|
debug!("added plugin: {}", entry.plugin.name());
|
2020-10-29 20:04:28 +00:00
|
|
|
entry.plugin.build(app);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|