1#![allow(clippy::missing_safety_doc)]
2
3use core::mem;
4
5use crate::{
6 bindings::{
7 BlockID, Event_Block, Event_Block_Callback, Event_Chat, Event_Chat_Callback, Event_Entry,
8 Event_Entry_Callback, Event_Float, Event_Float_Callback, Event_Input, Event_Input_Callback,
9 Event_Int, Event_Int_Callback, Event_LightingMode, Event_LightingMode_Callback,
10 Event_PadAxis, Event_PadAxis_Callback, Event_PluginMessage, Event_PluginMessage_Callback,
11 Event_RawMove, Event_RawMove_Callback, Event_Register, Event_String, Event_String_Callback,
12 Event_Unregister, Event_Void, Event_Void_Callback, IVec3, InputDevice, PadAxisUpdate,
13 Stream, cc_bool, cc_string, cc_uint8,
14 },
15 std_types::{c_float, c_int, c_void},
16};
17
18macro_rules! make_register_unregister {
19 (
20 $(#[$attr:meta])*
21 $func_name:ident,
22 $name:ident
23 ) => {
24 paste::item! {
25 $(#[$attr])*
26 pub unsafe fn [<Event_Register $func_name>] (
27 handlers: *mut [<Event_ $name>],
28 obj: *mut c_void,
29 handler: [<Event_ $name _Callback>],
30 ) {
31 unsafe {
32 Event_Register(
33 handlers.cast::<Event_Void>(),
34 obj,
35 #[allow(clippy::useless_transmute)]
36 mem::transmute::<[<Event_ $name _Callback>], Event_Void_Callback>(handler),
37 )
38 }
39 }
40
41 $(#[$attr])*
42 pub unsafe fn [<Event_Unregister $func_name>] (
43 handlers: *mut [<Event_ $name>],
44 obj: *mut c_void,
45 handler: [<Event_ $name _Callback>],
46 ) {
47 unsafe {
48 Event_Unregister(
49 handlers.cast::<Event_Void>(),
50 obj,
51 #[allow(clippy::useless_transmute)]
52 mem::transmute::<[<Event_ $name _Callback>], Event_Void_Callback>(handler),
53 )
54 }
55 }
56 }
57 };
58
59 ($name:ident) => {
60 make_register_unregister!($name, $name);
61 };
62}
63
64macro_rules! make_raise {
65 (
66 $(#[$attr:meta])*
67 $name:ident,
68 ( $($arg:ident: $arg_type:ty),* )
69 ) => {
70 paste::item! {
71 $(#[$attr])*
72 pub unsafe fn [<Event_Raise $name>] (
73 handlers: &mut [<Event_ $name>],
74 $($arg: $arg_type,)*
75 ) {
76 for i in 0..handlers.Count {
77 #[expect(
78 clippy::cast_sign_loss,
79 reason = "handler index is a non-negative c_int from FFI"
80 )]
81 let i = i as usize;
82 if let Some(f) = handlers.Handlers[i] {
83 unsafe {
84 (f)(
85 handlers.Objs[i],
86 $($arg),*
87 );
88 }
89 }
90 }
91 }
92 }
93 };
94}
95
96make_register_unregister!(Void);
100make_register_unregister!(Int);
101make_register_unregister!(Float);
102
103make_register_unregister!(Entry);
104make_raise!(
105 Entry, (stream: *mut Stream, name: *const cc_string)
107);
108
109make_register_unregister!(Block);
110make_raise!(
111 Block, (coords: IVec3, oldBlock: BlockID, block: BlockID)
114);
115
116make_register_unregister!(Chat);
117make_raise!(
118 Chat, (msg: *const cc_string, msgType: c_int)
121);
122
123make_register_unregister!(Input);
124make_raise!(
125 Input, (key: c_int, repeating: cc_bool, device: *mut InputDevice)
128);
129
130make_register_unregister!(String);
131make_raise!(
132 String, (s: *const cc_string)
134);
135
136make_register_unregister!(RawMove);
137make_raise!(
138 RawMove, (x_delta: c_float, y_delta: c_float)
140);
141
142make_register_unregister!(PadAxis);
143make_raise!(
144 PadAxis, (upd: *mut PadAxisUpdate)
146);
147
148make_register_unregister!(PluginMessage);
149make_raise!(
150 PluginMessage, (channel: cc_uint8, data: *mut cc_uint8)
152);
153
154make_register_unregister!(LightingMode);
155make_raise!(
156 LightingMode, (oldMode: cc_uint8, fromServer: cc_bool)
158);