8
8
use std:: fmt;
9
9
10
10
use godot_ffi as sys;
11
- use godot_ffi:: interface_fn;
12
11
use sys:: { ffi_methods, ExtVariantType , GodotFfi } ;
13
12
14
13
use crate :: builtin:: { inner, Encoding , GString , NodePath , Variant } ;
@@ -84,7 +83,7 @@ impl StringName {
84
83
let is_static = sys:: conv:: SYS_FALSE ;
85
84
let s = unsafe {
86
85
Self :: new_with_string_uninit ( |string_ptr| {
87
- let ctor = interface_fn ! ( string_name_new_with_latin1_chars) ;
86
+ let ctor = sys :: interface_fn!( string_name_new_with_latin1_chars) ;
88
87
ctor (
89
88
string_ptr,
90
89
cstr. as_ptr ( ) as * const std:: ffi:: c_char ,
@@ -245,9 +244,20 @@ impl StringName {
245
244
inner:: InnerStringName :: from_outer ( self )
246
245
}
247
246
247
+ #[ doc( hidden) ] // Private for now. Needs API discussion, also regarding overlap with try_from_cstr().
248
+ pub fn __cstr ( c_str : & ' static std:: ffi:: CStr ) -> Self {
249
+ // This used to be set to true, but `p_is_static` parameter in Godot should only be enabled if the result is indeed stored
250
+ // in a static. See discussion in https://github.com/godot-rust/gdext/pull/1316. We may unify this into a regular constructor,
251
+ // or provide a dedicated StringName cache (similar to ClassId cache) in the future, which would be freed on shutdown.
252
+ let is_static = false ;
253
+
254
+ Self :: __cstr_with_static ( c_str, is_static)
255
+ }
256
+
248
257
/// Creates a `StringName` from a static ASCII/Latin-1 `c"string"`.
249
258
///
250
- /// This avoids unnecessary copies and allocations and directly uses the backing buffer. Useful for literals.
259
+ /// If `is_static` is true, avoids unnecessary copies and allocations and directly uses the backing buffer. However, this must
260
+ /// be stored in an actual `static` to not cause leaks/error messages with Godot. For literals, use `is_static=false`.
251
261
///
252
262
/// Note that while Latin-1 encoding is the most common encoding for c-strings, it isn't a requirement. So if your c-string
253
263
/// uses a different encoding (e.g. UTF-8), it is possible that some characters will not show up as expected.
@@ -260,17 +270,17 @@ impl StringName {
260
270
/// use godot::builtin::StringName;
261
271
///
262
272
/// // '±' is a Latin-1 character with codepoint 0xB1. Note that this is not UTF-8, where it would need two bytes.
263
- /// let sname = StringName::__static_cstr (c"\xb1 Latin-1 string");
273
+ /// let sname = StringName::__cstr (c"\xb1 Latin-1 string");
264
274
/// ```
265
275
#[ doc( hidden) ] // Private for now. Needs API discussion, also regarding overlap with try_from_cstr().
266
- pub fn __static_cstr ( c_str : & ' static std:: ffi:: CStr ) -> Self {
276
+ pub fn __cstr_with_static ( c_str : & ' static std:: ffi:: CStr , is_static : bool ) -> Self {
267
277
// SAFETY: c_str is nul-terminated and remains valid for entire program duration.
268
278
unsafe {
269
279
Self :: new_with_string_uninit ( |ptr| {
270
280
sys:: interface_fn!( string_name_new_with_latin1_chars) (
271
281
ptr,
272
282
c_str. as_ptr ( ) ,
273
- sys:: conv:: SYS_TRUE , // p_is_static
283
+ sys:: conv:: bool_to_sys ( is_static ) ,
274
284
)
275
285
} )
276
286
}
@@ -488,6 +498,7 @@ mod serialize {
488
498
}
489
499
490
500
// TODO(v0.4.x): consider re-exposing in public API. Open questions: thread-safety, performance, memory leaks, global overhead.
501
+ // Possibly in a more general StringName cache, similar to ClassId. See https://github.com/godot-rust/gdext/pull/1316.
491
502
/// Creates and gets a reference to a static `StringName` from a ASCII/Latin-1 `c"string"`.
492
503
///
493
504
/// This is the fastest way to create a StringName repeatedly, with the result being cached and never released, like `SNAME` in Godot source code. Suitable for scenarios where high performance is required.
@@ -498,6 +509,6 @@ macro_rules! static_sname {
498
509
499
510
let c_str: & ' static std:: ffi:: CStr = $str;
500
511
static SNAME : OnceLock <StringName > = OnceLock :: new( ) ;
501
- SNAME . get_or_init( || StringName :: __static_cstr ( c_str) )
512
+ SNAME . get_or_init( || StringName :: __cstr_with_static ( c_str, true ) )
502
513
} } ;
503
514
}
0 commit comments