#![warn(missing_docs)]
use crate::app::{Stage, SystemRegistration, push_system_registration};
use crate::events::AppEvent;
use furmint_registry::{ComponentFactory, ComponentRegistry};
use specs::prelude::Resource;
use specs::{Component, World, WorldExt};
use std::collections::HashMap;
use std::error::Error;
use std::sync::mpsc::Sender;
pub struct PluginBuildContext<'a> {
pub(crate) world: &'a mut World,
pub(crate) dispatcher_config: &'a mut HashMap<Stage, Vec<SystemRegistration>>,
pub(crate) component_registry: &'a mut ComponentRegistry,
pub(crate) event_sender: Sender<AppEvent>,
}
pub struct PluginUpdateContext<'a> {
pub world: &'a mut World,
pub delta_time: f64,
}
pub trait Plugin {
fn build(&mut self, ctx: &mut PluginBuildContext<'_>) -> Result<(), Box<dyn Error>>;
fn update(&mut self, ctx: &mut PluginUpdateContext<'_>) -> Result<(), Box<dyn Error>>;
fn shutdown(&mut self) -> Result<(), Box<dyn Error>> {
Ok(())
}
fn name(&self) -> &'static str;
}
impl PluginBuildContext<'_> {
pub fn register_system<S>(&mut self, stage: Stage, sys: S)
where
for<'a> S: specs::System<'a> + Send + 'static,
{
push_system_registration(
self.dispatcher_config
.get_mut(&stage)
.expect("stage config missing"),
sys,
&[],
);
}
pub fn register_system_deps<S>(&mut self, stage: Stage, sys: S, deps: &'static [&'static str])
where
for<'a> S: specs::System<'a> + Send + 'static,
{
push_system_registration(
self.dispatcher_config
.get_mut(&stage)
.expect("stage config missing"),
sys,
deps,
);
}
pub fn insert_resource(&mut self, resource: impl Resource) {
self.world.insert(resource);
}
pub fn with_component<C: Component, F: ComponentFactory + 'static>(
&mut self,
name: &'static str,
component_factory: F,
) where
<C as Component>::Storage: Default,
{
self.world.register::<C>();
self.component_registry
.register(name, Box::new(component_factory));
}
pub fn event_sender(&self) -> Sender<AppEvent> {
self.event_sender.clone()
}
}
impl<'a> PluginUpdateContext<'a> {
pub(crate) fn new(delta_time: f64, world: &'a mut World) -> Self {
Self { delta_time, world }
}
}