bevy_butler_core/
lib.rs

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}