fmc_client_api/
lib.rs

1mod transform;
2
3pub trait Plugin: Send + Sync {
4    fn new() -> Self
5    where
6        Self: Sized;
7
8    fn update(&mut self);
9
10    fn handle_server_data(&mut self, _data: Vec<u8>) {}
11
12    fn set_update_frequency(&mut self) -> Option<f32> {
13        None
14    }
15}
16
17#[macro_export]
18macro_rules! register_plugin {
19    ($plugin_type:ty) => {
20        #[export_name = "init-plugin"]
21        pub extern "C" fn __init_plugin() {
22            fmc_client_api::register_plugin(|| {
23                Box::new(<$plugin_type as fmc_client_api::Plugin>::new())
24            });
25        }
26    };
27}
28
29static mut PLUGIN: Option<Box<dyn Plugin>> = None;
30
31#[doc(hidden)]
32pub fn register_plugin(build_plugin: fn() -> Box<dyn Plugin>) {
33    unsafe { PLUGIN = Some((build_plugin)()) }
34}
35
36fn plugin() -> &'static mut dyn Plugin {
37    unsafe { PLUGIN.as_deref_mut().unwrap() }
38}
39
40mod wit {
41    use std::hash::{Hash, Hasher};
42
43    wit_bindgen::generate!({
44        skip: ["init-plugin"],
45        path: "./src/api.wit",
46        with: {
47            "fmc:api/math": crate::math,
48            "fmc:api/transform": crate::transform
49        },
50    });
51
52    impl Hash for Key {
53        fn hash<H: Hasher>(&self, state: &mut H) {
54            let discriminant = std::mem::discriminant(self);
55            core::hash::Hash::hash(&discriminant, state);
56        }
57    }
58}
59
60pub use wit::{
61    delta_time, get_block, get_block_aabb, get_block_friction, get_block_name,
62    get_camera_transform, get_model_aabb, get_models, get_player_transform, keyboard_input, log,
63    set_camera_transform, set_player_transform, Friction, Key, KeyboardKey, SurfaceFriction,
64};
65
66pub mod math {
67    pub use glam::*;
68}
69
70pub mod prelude {
71    pub use crate::math::{DQuat, IVec3, Quat, Vec3};
72    pub use crate::transform::Transform;
73}
74
75wit::export!(Component with_types_in wit);
76
77struct Component;
78
79impl wit::Guest for Component {
80    fn set_update_frequency() -> Option<f32> {
81        plugin().set_update_frequency()
82    }
83
84    fn update() {
85        plugin().update()
86    }
87
88    fn handle_server_data(data: Vec<u8>) {
89        plugin().handle_server_data(data)
90    }
91}