88use std:: fmt;
99
1010use godot_ffi as sys;
11- use godot_ffi:: interface_fn;
1211use sys:: { ffi_methods, ExtVariantType , GodotFfi } ;
1312
1413use crate :: builtin:: { inner, Encoding , GString , NodePath , Variant } ;
@@ -84,7 +83,7 @@ impl StringName {
8483 let is_static = sys:: conv:: SYS_FALSE ;
8584 let s = unsafe {
8685 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) ;
8887 ctor (
8988 string_ptr,
9089 cstr. as_ptr ( ) as * const std:: ffi:: c_char ,
@@ -245,9 +244,20 @@ impl StringName {
245244 inner:: InnerStringName :: from_outer ( self )
246245 }
247246
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+
248257 /// Creates a `StringName` from a static ASCII/Latin-1 `c"string"`.
249258 ///
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`.
251261 ///
252262 /// Note that while Latin-1 encoding is the most common encoding for c-strings, it isn't a requirement. So if your c-string
253263 /// 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 {
260270 /// use godot::builtin::StringName;
261271 ///
262272 /// // '±' 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");
264274 /// ```
265275 #[ 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 {
267277 // SAFETY: c_str is nul-terminated and remains valid for entire program duration.
268278 unsafe {
269279 Self :: new_with_string_uninit ( |ptr| {
270280 sys:: interface_fn!( string_name_new_with_latin1_chars) (
271281 ptr,
272282 c_str. as_ptr ( ) ,
273- sys:: conv:: SYS_TRUE , // p_is_static
283+ sys:: conv:: bool_to_sys ( is_static ) ,
274284 )
275285 } )
276286 }
@@ -488,6 +498,7 @@ mod serialize {
488498}
489499
490500// 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.
491502/// Creates and gets a reference to a static `StringName` from a ASCII/Latin-1 `c"string"`.
492503///
493504/// 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 {
498509
499510 let c_str: & ' static std:: ffi:: CStr = $str;
500511 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 ) )
502513 } } ;
503514}
0 commit comments