use std::any::type_name;
use anyhow::Result;
use bevy_app::prelude::*;
use bevy_ecs::prelude::*;
#[cfg(feature = "devtools")]
use bevy_remote::{BrpError, RemoteMethodSystemId, RemoteMethods};
#[cfg(feature = "devtools")]
use serde_json::Value;
pub trait AppExtend {
fn try_add_plugin<T>(&mut self, plugin: T) -> &mut Self
where
T: Plugin;
#[cfg(feature = "devtools")]
fn add_remote<M>(
&mut self,
method_name: impl Into<String>,
handler: impl IntoSystem<In<Option<Value>>, Result<Value>, M> + 'static,
) -> &mut Self;
fn plugin<T>(&self) -> &T
where
T: Plugin;
}
impl AppExtend for App {
fn try_add_plugin<T>(&mut self, plugins: T) -> &mut Self
where
T: Plugin,
{
if !self.is_plugin_added::<T>() {
self.add_plugins(plugins);
}
self
}
#[cfg(feature = "devtools")]
fn add_remote<M>(
&mut self,
method_name: impl Into<String>,
handler: impl IntoSystem<In<Option<Value>>, Result<Value>, M> + 'static,
) -> &mut Self {
let handler =
handler.pipe(|In(result): In<Result<Value>>| result.map_err(BrpError::internal));
let system_id = self.world_mut().register_system(handler);
self.world_mut()
.resource_mut::<RemoteMethods>()
.insert(method_name, RemoteMethodSystemId::Instant(system_id));
self
}
fn plugin<T>(&self) -> &T
where
T: Plugin,
{
match self.get_added_plugins::<T>().into_iter().next() {
Some(plugin) => plugin,
None => panic!("Expected plugin \"{}\" to be added.", type_name::<T>()),
}
}
}