use elicitation_derive::reflect_trait;
use std::any::TypeId;
use std::collections::HashSet;
use std::sync::{LazyLock, RwLock};
#[reflect_trait(std::default::Default)]
pub trait DefaultTools {
fn default() -> Self;
}
macro_rules! bevy_marker_factory {
(
factory = $factory:ident,
prime_fn = $prime_fn:ident,
trait_path = $trait_path:path,
trait_name_str = $trait_name_str:expr,
description = $description:expr $(,)?
) => {
#[doc = $description]
pub struct $factory;
impl $factory {
pub fn prime<T>()
where
T: $trait_path
+ ::serde::Serialize
+ ::serde::de::DeserializeOwned
+ ::schemars::JsonSchema
+ ::elicitation::Elicitation
+ Send
+ Sync
+ 'static,
{
let type_id = TypeId::of::<T>();
let mut set = $factory::vtable_set()
.write()
.expect("factory set lock poisoned");
set.insert(type_id);
}
fn vtable_set() -> &'static RwLock<HashSet<TypeId>> {
static SET: LazyLock<RwLock<HashSet<TypeId>>> =
LazyLock::new(|| RwLock::new(HashSet::new()));
&SET
}
}
impl ::elicitation::AnyToolFactory for $factory {
fn trait_name(&self) -> &'static str {
$trait_name_str
}
fn factory_description(&self) -> &'static str {
$description
}
fn method_names(&self) -> &'static [&'static str] {
&[]
}
fn instantiate(
&self,
_slot: &dyn ::elicitation::dynamic::slot::AnyToolSlot,
) -> ::std::result::Result<
::std::vec::Vec<::elicitation::DynamicToolDescriptor>,
::rmcp::ErrorData,
> {
Ok(vec![])
}
}
::inventory::submit!(::elicitation::ToolFactoryRegistration {
trait_name: $trait_name_str,
factory: &$factory,
});
#[doc = concat!("Prime the [`", stringify!($factory), "`] factory for type `T`.")]
pub fn $prime_fn<T>()
where
T: $trait_path
+ ::serde::Serialize
+ ::serde::de::DeserializeOwned
+ ::schemars::JsonSchema
+ ::elicitation::Elicitation
+ Send
+ Sync
+ 'static,
{
$factory::prime::<T>();
}
};
}
bevy_marker_factory! {
factory = ComponentToolsFactory,
prime_fn = prime_bevy_component,
trait_path = bevy::ecs::component::Component,
trait_name_str = "bevy::ecs::component::Component",
description = "Marker factory — confirms T: Component is registered.",
}
bevy_marker_factory! {
factory = ResourceToolsFactory,
prime_fn = prime_bevy_resource,
trait_path = bevy::ecs::resource::Resource,
trait_name_str = "bevy::ecs::resource::Resource",
description = "Marker factory — confirms T: Resource is registered.",
}
bevy_marker_factory! {
factory = AssetToolsFactory,
prime_fn = prime_bevy_asset,
trait_path = bevy::asset::Asset,
trait_name_str = "bevy::asset::Asset",
description = "Marker factory — confirms T: Asset is registered.",
}
bevy_marker_factory! {
factory = BundleToolsFactory,
prime_fn = prime_bevy_bundle,
trait_path = bevy::ecs::bundle::Bundle,
trait_name_str = "bevy::ecs::bundle::Bundle",
description = "Marker factory — confirms T: Bundle is registered.",
}
bevy_marker_factory! {
factory = EventToolsFactory,
prime_fn = prime_bevy_event,
trait_path = bevy::ecs::event::Event,
trait_name_str = "bevy::ecs::event::Event",
description = "Marker factory — confirms T: Event is registered.",
}
bevy_marker_factory! {
factory = StatesToolsFactory,
prime_fn = prime_bevy_states,
trait_path = bevy::state::state::States,
trait_name_str = "bevy::state::state::States",
description = "Marker factory — confirms T: States is registered.",
}
bevy_marker_factory! {
factory = PluginToolsFactory,
prime_fn = prime_bevy_plugin,
trait_path = bevy::app::Plugin,
trait_name_str = "bevy::app::Plugin",
description = "Marker factory — confirms T: Plugin is registered.",
}