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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use crate::sys;
use crate::ObjectMethodTable;
use libc;
use std::ptr;
pub unsafe trait GodotObject {
fn class_name() -> &'static str;
#[doc(hidden)]
unsafe fn to_sys(&self) -> *mut sys::godot_object;
#[doc(hidden)]
unsafe fn from_sys(obj: *mut sys::godot_object) -> Self;
#[doc(hidden)]
unsafe fn from_return_position_sys(obj: *mut sys::godot_object) -> Self;
}
pub trait Instanciable: GodotObject {
fn construct() -> Self;
}
pub unsafe fn add_ref(obj: *mut sys::godot_object) {
use crate::ReferenceMethodTable;
let api = crate::get_api();
let addref_method = ReferenceMethodTable::unchecked_get().reference;
let mut argument_buffer = [ptr::null() as *const libc::c_void; 0];
let mut ok = false;
let ok_ptr = &mut ok as *mut bool;
(api.godot_method_bind_ptrcall)(
addref_method,
obj,
argument_buffer.as_mut_ptr() as *mut _,
ok_ptr as *mut _,
);
debug_assert!(ok);
}
pub unsafe fn unref(obj: *mut sys::godot_object) -> bool {
use crate::ReferenceMethodTable;
let unref_method = ReferenceMethodTable::unchecked_get().unreference;
let mut argument_buffer = [ptr::null() as *const libc::c_void; 0];
let mut last_reference = false;
let ret_ptr = &mut last_reference as *mut bool;
(crate::get_api().godot_method_bind_ptrcall)(
unref_method,
obj,
argument_buffer.as_mut_ptr() as *mut _,
ret_ptr as *mut _,
);
last_reference
}
pub unsafe fn init_ref_count(obj: *mut sys::godot_object) {
use crate::ReferenceMethodTable;
let init_method = ReferenceMethodTable::unchecked_get().init_ref;
let mut argument_buffer = [ptr::null() as *const libc::c_void; 0];
let mut ok = false;
let ret_ptr = &mut ok as *mut bool;
(crate::get_api().godot_method_bind_ptrcall)(
init_method,
obj,
argument_buffer.as_mut_ptr() as *mut _,
ret_ptr as *mut _,
);
debug_assert!(ok);
}
pub fn is_class(obj: *mut sys::godot_object, class_name: &str) -> bool {
unsafe {
let api = crate::get_api();
let method_bind = ObjectMethodTable::get(api).is_class;
let mut class_name = (api.godot_string_chars_to_utf8_with_len)(
class_name.as_ptr() as *const _,
class_name.len() as _,
);
let mut argument_buffer = [ptr::null() as *const libc::c_void; 1];
argument_buffer[0] = (&class_name) as *const _ as *const _;
let mut ret = false;
let ret_ptr = &mut ret as *mut _;
(api.godot_method_bind_ptrcall)(
method_bind,
obj,
argument_buffer.as_mut_ptr() as *mut _,
ret_ptr as *mut _,
);
(api.godot_string_destroy)(&mut class_name);
ret
}
}
pub fn godot_cast<T>(from: *mut sys::godot_object) -> Option<T>
where
T: GodotObject,
{
unsafe {
if !is_class(from, T::class_name()) {
return None;
}
Some(T::from_sys(from))
}
}