1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#![allow(clippy::missing_safety_doc)]

use core::mem;

use crate::{
    bindings::*,
    std_types::{c_float, c_int, c_void},
};

macro_rules! make_register {
    ($func_name:ident, $name:ident) => {
        paste::item! {
            pub unsafe fn [<Event_Register $func_name>] (
                handlers: *mut [<Event_ $name>],
                obj: *mut c_void,
                handler: [<Event_ $name _Callback>],
            ) {
                Event_Register(
                    handlers as *mut Event_Void,
                    obj,
                    #[allow(clippy::useless_transmute)]
                    mem::transmute::<[<Event_ $name _Callback>], Event_Void_Callback>(handler),
                )
            }

            pub unsafe fn [<Event_Unregister $func_name>] (
                handlers: *mut [<Event_ $name>],
                obj: *mut c_void,
                handler: [<Event_ $name _Callback>],
            ) {
                Event_Unregister(
                    handlers as *mut Event_Void,
                    obj,
                    #[allow(clippy::useless_transmute)]
                    mem::transmute::<[<Event_ $name _Callback>], Event_Void_Callback>(handler),
                )
            }
        }
    };

    ($name:ident) => {
        make_register!($name, $name);
    };
}

macro_rules! make_raise {
    (
        $func_name:ident,
        $name:ident,
        ( $($arg:ident: $arg_type:ty),* )
    ) => {
        paste::item! {
            pub unsafe fn [<Event_Raise $func_name>] (
                handlers: &mut [<Event_ $name>],
                $($arg: $arg_type,)*
            ) {
                for i in 0..handlers.Count {
                    if let Some(f) = handlers.Handlers[i as usize] {
                        (f)(
                            handlers.Objs[i as usize],
                            $($arg),*
                        );
                    }
                }
            }
        }
    };

    (
        $name:ident,
        ( $($arg:ident: $arg_type:ty),* )
    ) => {
        make_raise!($name, $name, ( $($arg: $arg_type),* ));
    }
}

// Raise_ Void, Int, Float are already exported

make_register!(Void);
make_register!(Int);
make_register!(Float);

make_register!(Entry);
make_raise!(Entry, (stream: *mut Stream, name: *const cc_string));

make_register!(Block);
make_raise!(Block, (coords: IVec3, oldBlock: BlockID, block: BlockID));

make_register!(Chat);
make_raise!(Chat, (msg: *const cc_string, msgType: c_int));

make_register!(Input);
make_raise!(Input, (key: c_int, repeating: cc_bool, device: *mut InputDevice));

make_register!(String);
make_raise!(String, (s: *const cc_string));

make_register!(RawMove);
make_raise!(RawMove, (x_delta: c_float, y_delta: c_float));

make_register!(PluginMessage);
make_raise!(PluginMessage, (channel: u8, data: *mut u8));