use bevy::app::{App, Plugin};
use bevy::ecs::world::World;
use bevy::reflect::TypePath;
use serde::de::DeserializeOwned;
use crate::{WorldExtension, typetagged::ErasedObject};
#[doc(hidden)]
pub use linkme::distributed_slice;
#[doc(hidden)]
pub type Func = fn(&mut World);
#[distributed_slice]
pub static DESERIALIZER_PLUGINS: [fn(&mut World)];
pub const fn as_deserialize_plugin<A: ErasedObject, B: Into<A> + TypePath + DeserializeOwned>()
-> fn(&mut World) {
|world| {
world.register_typetag::<A, B>();
}
}
pub struct LinkDeserializersPlugin;
impl Plugin for LinkDeserializersPlugin {
fn build(&self, app: &mut App) {
for f in DESERIALIZER_PLUGINS {
f(app.world_mut())
}
}
}
#[macro_export]
macro_rules! link_deserializer {
($lhs: ty => $rhs: ty) => {
const _: () = {
#[$crate::linking::distributed_slice($crate::linking::DESERIALIZER_PLUGINS)]
static __DESERIALIZER: $crate::linking::Func = $crate::linking::as_deserialize_plugin::<$rhs, $lhs>();
};
};
($lhs: ty => {$($rhs: ty),* $(,)?}) => {
$(
const _: () = {
#[$crate::linking::distributed_slice]
static __DESERIALIZER: $crate::linking::Func = $crate::linking::as_deserialize_plugin::<$rhs, $lhs>();
};
)*
};
}