Skip to main content

classicube_sys/
event.rs

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
96// ClassiCube/src/Event.h
97
98// Event_RaiseVoid, Event_RaiseInt, Event_RaiseFloat are already exported
99make_register_unregister!(Void);
100make_register_unregister!(Int);
101make_register_unregister!(Float);
102
103make_register_unregister!(Entry);
104make_raise!(
105    /// Calls all registered callbacks for an event which has data stream and name arguments.
106    Entry, (stream: *mut Stream, name: *const cc_string)
107);
108
109make_register_unregister!(Block);
110make_raise!(
111    /// Calls all registered callbacks for an event which takes block change arguments.
112    /// These are the coordinates/location of the change, block there before, block there now.
113    Block, (coords: IVec3, oldBlock: BlockID, block: BlockID)
114);
115
116make_register_unregister!(Chat);
117make_raise!(
118    /// Calls all registered callbacks for an event which has chat message type and contents.
119    /// See `MsgType` enum in `Chat.h` for what types of messages there are.
120    Chat, (msg: *const cc_string, msgType: c_int)
121);
122
123make_register_unregister!(Input);
124make_raise!(
125    /// Calls all registered callbacks for an event which has keyboard key/mouse button.
126    /// repeating is whether the key/button was already pressed down. (i.e. user is holding down key)
127    Input, (key: c_int, repeating: cc_bool, device: *mut InputDevice)
128);
129
130make_register_unregister!(String);
131make_raise!(
132    /// Calls all registered callbacks for an event which has a string argument.
133    String, (s: *const cc_string)
134);
135
136make_register_unregister!(RawMove);
137make_raise!(
138    /// Calls all registered callbacks for an event which has raw pointer movement arguments.
139    RawMove, (x_delta: c_float, y_delta: c_float)
140);
141
142make_register_unregister!(PadAxis);
143make_raise!(
144    /// Calls all registered callbacks for an event which has pad axis arguments.
145    PadAxis, (upd: *mut PadAxisUpdate)
146);
147
148make_register_unregister!(PluginMessage);
149make_raise!(
150    /// Calls all registered callbacks for an event which has a channel and a 64 byte data argument.
151    PluginMessage, (channel: cc_uint8, data: *mut cc_uint8)
152);
153
154make_register_unregister!(LightingMode);
155make_raise!(
156    /// Calls all registered callbacks for an event called when the `Lighting_LightingMode` is changed
157    LightingMode, (oldMode: cc_uint8, fromServer: cc_bool)
158);