use bevy_ecs::world::WorldId;
use crate::{
IntoScriptPluginParams,
context::{ContextInitializer, ContextPreHandlingInitializer},
};
#[derive(Debug)]
pub struct ScriptingPluginConfiguration<P: IntoScriptPluginParams + ?Sized> {
pub pre_handling_callbacks: &'static [ContextPreHandlingInitializer<P>],
pub context_initialization_callbacks: &'static [ContextInitializer<P>],
pub emit_responses: bool,
pub runtime: &'static P::R,
pub language_extensions: &'static crate::LanguageExtensions,
}
impl<P: IntoScriptPluginParams + ?Sized> Clone for ScriptingPluginConfiguration<P> {
fn clone(&self) -> Self {
*self
}
}
impl<P: IntoScriptPluginParams + ?Sized> Copy for ScriptingPluginConfiguration<P> {}
pub trait GetPluginThreadConfig<P: IntoScriptPluginParams + ?Sized> {
fn readonly_configuration(world: WorldId) -> ScriptingPluginConfiguration<P>;
fn set_world_local_config(world: WorldId, config: ScriptingPluginConfiguration<P>);
}
#[macro_export]
macro_rules! make_plugin_config_static {
($ty:ty) => {
static CONFIG: std::sync::RwLock<
bevy_platform::prelude::Vec<
Option<ScriptingPluginConfiguration<$ty>>,
>,
> = std::sync::RwLock::new(bevy_platform::prelude::Vec::new());
impl GetPluginThreadConfig<$ty> for $ty {
fn readonly_configuration(
world: bevy_ecs::world::WorldId,
) -> ScriptingPluginConfiguration<$ty> {
CONFIG
.read()
.unwrap()
.get(<bevy_ecs::world::WorldId as bevy_ecs::storage::SparseSetIndex>::sparse_set_index(&world))
.and_then(|c| *c)
.unwrap_or_else(||
panic!(
"Configuration for plugin {} not set for world {:?}. Did you add the plugin to the app?",
stringify!($ty),
world
),
)
}
fn set_world_local_config(
world: bevy_ecs::world::WorldId,
config: ScriptingPluginConfiguration<$ty>,
) {
let mut guard = CONFIG.write().unwrap();
let index = <bevy_ecs::world::WorldId as bevy_ecs::storage::SparseSetIndex>::sparse_set_index(&world) as usize;
if index >= guard.len() {
guard.resize_with(index + 1, || None);
}
guard[index] = Some(config);
}
}
};
}