1#![feature(const_type_id)]
2mod plugin;
3pub use plugin::*;
4
5pub mod __internal {
6 use std::any::TypeId;
7 use std::sync::Arc;
8 use bevy_utils::HashMap;
9 use bevy_ecs::system::Resource;
10 use bevy_app::App;
11 use bevy_log::debug;
12
13 pub use inventory;
14
15 #[derive(Debug)]
16 pub struct ButlerFunc(TypeId, * const ());
17
18 unsafe impl Sync for ButlerFunc {}
19 unsafe impl Send for ButlerFunc {}
20
21 impl ButlerFunc {
22 pub const fn new<T: 'static + Send + Sync>(func: fn(&T, &mut App) -> ()) -> Self {
23 let func_ptr = unsafe { std::mem::transmute(func) };
24 Self(TypeId::of::<T>(), func_ptr)
25 }
26
27 pub fn type_id(&self) -> TypeId {
28 self.0
29 }
30
31 pub fn get_func<T: 'static + Send + Sync>(&self) -> fn(&T, &mut App) -> () {
32 assert_eq!(TypeId::of::<T>(), self.0);
33 unsafe { std::mem::transmute(self.1) }
34 }
35
36 pub fn try_get_func<T: 'static + Send + Sync>(&self) -> Option<fn(&T, &mut App) -> ()> {
37 if self.0 == TypeId::of::<T>() {
38 return Some(self.get_func());
39 }
40 None
41 }
42 }
43
44 #[derive(Resource)]
45 pub struct ButlerRegistry {
46 plugin_map: HashMap<TypeId, Arc<Vec<&'static ButlerFunc>>>,
47 }
48
49 impl ButlerRegistry {
50 pub fn new(plugin_map: HashMap<TypeId, Vec<&'static ButlerFunc>>) -> Self {
51 Self {
52 plugin_map: plugin_map.into_iter().map(|(k, v)| (k, Arc::new(v))).collect()
53 }
54 }
55
56 pub fn get_funcs<T: 'static + Send + Sync>(&self) -> Option<Arc<Vec<&'static ButlerFunc>>> {
57 self.plugin_map.get(&TypeId::of::<T>())
58 .map(|arc| arc.clone())
59 }
60 }
61
62 pub fn _butler_debug(msg: &str) {
63 debug!("{}", msg);
64 }
65
66 inventory::collect!(ButlerFunc);
67}