Skip to content

Commit 8402bd4

Browse files
committed
StringCache uses newer StringName constructor function for Godot >= 4.2
1 parent 4b5977e commit 8402bd4

File tree

1 file changed

+38
-10
lines changed

1 file changed

+38
-10
lines changed

godot-ffi/src/string_cache.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,21 @@ impl<'a> StringCache<'a> {
3939
return box_to_sname_ptr(opaque_box);
4040
}
4141

42-
let string_name_from_string = self.builtin_lifecycle.string_name_from_string;
43-
let string_destroy = self.builtin_lifecycle.string_destroy;
44-
45-
let mut string = MaybeUninit::<sys::types::OpaqueString>::uninit();
46-
let string_ptr = string.as_mut_ptr();
47-
4842
let mut sname = MaybeUninit::<sys::types::OpaqueStringName>::uninit();
4943
let sname_ptr = sname.as_mut_ptr();
5044

51-
let opaque = unsafe {
45+
// For Godot 4.0 and 4.1, construct StringName via String + conversion.
46+
#[cfg(before_api = "4.2")]
47+
unsafe {
5248
let string_new_with_latin1_chars_and_len = self
5349
.interface
5450
.string_new_with_latin1_chars_and_len
5551
.unwrap_unchecked();
52+
let string_name_from_string = self.builtin_lifecycle.string_name_from_string;
53+
let string_destroy = self.builtin_lifecycle.string_destroy;
54+
55+
let mut string = MaybeUninit::<sys::types::OpaqueString>::uninit();
56+
let string_ptr = string.as_mut_ptr();
5657

5758
// Construct String.
5859
string_new_with_latin1_chars_and_len(
@@ -69,10 +70,27 @@ impl<'a> StringCache<'a> {
6970

7071
// Destroy String.
7172
string_destroy(string_type_ptr(string_ptr));
73+
}
7274

73-
// Return StringName.
74-
sname.assume_init()
75-
};
75+
// For Godot 4.2+, construct StringName directly from C string.
76+
#[cfg(since_api = "4.2")]
77+
unsafe {
78+
let string_name_new_with_utf8_chars_and_len = self
79+
.interface
80+
.string_name_new_with_utf8_chars_and_len
81+
.unwrap_unchecked();
82+
83+
// Construct StringName from string (non-static, we only need them during the cache's lifetime).
84+
// There is no _latin_*() variant that takes length, so we have to use _utf8_*() instead.
85+
string_name_new_with_utf8_chars_and_len(
86+
sname_uninit_ptr(sname_ptr),
87+
key.as_ptr() as *const std::os::raw::c_char,
88+
key.len() as sys::GDExtensionInt,
89+
);
90+
}
91+
92+
// Return StringName.
93+
let opaque = unsafe { sname.assume_init() };
7694

7795
let mut opaque_box = Box::new(opaque);
7896
let sname_ptr = box_to_sname_ptr(&mut opaque_box);
@@ -108,20 +126,30 @@ fn box_to_sname_ptr(
108126
opaque_ptr as sys::GDExtensionStringNamePtr
109127
}
110128

129+
#[cfg(before_api = "4.2")]
111130
unsafe fn string_type_ptr(opaque_ptr: *mut sys::types::OpaqueString) -> sys::GDExtensionTypePtr {
112131
ptr::addr_of_mut!(*opaque_ptr) as sys::GDExtensionTypePtr
113132
}
114133

134+
#[cfg(before_api = "4.2")]
115135
unsafe fn string_uninit_ptr(
116136
opaque_ptr: *mut sys::types::OpaqueString,
117137
) -> sys::GDExtensionUninitializedStringPtr {
118138
ptr::addr_of_mut!(*opaque_ptr) as sys::GDExtensionUninitializedStringPtr
119139
}
120140

141+
#[cfg(since_api = "4.2")]
142+
unsafe fn sname_uninit_ptr(
143+
opaque_ptr: *mut sys::types::OpaqueStringName,
144+
) -> sys::GDExtensionUninitializedStringNamePtr {
145+
ptr::addr_of_mut!(*opaque_ptr) as sys::GDExtensionUninitializedStringNamePtr
146+
}
147+
121148
unsafe fn sname_type_ptr(opaque_ptr: *mut sys::types::OpaqueStringName) -> sys::GDExtensionTypePtr {
122149
ptr::addr_of_mut!(*opaque_ptr) as sys::GDExtensionTypePtr
123150
}
124151

152+
#[cfg(before_api = "4.2")]
125153
unsafe fn sname_uninit_type_ptr(
126154
opaque_ptr: *mut sys::types::OpaqueStringName,
127155
) -> sys::GDExtensionUninitializedTypePtr {

0 commit comments

Comments
 (0)