godotengine / godot-docs

Godot Engine official documentation
https://docs.godotengine.org
Other
3.6k stars 2.96k forks source link

Improve StringName documentation to clarify usage #7995

Open awardell opened 9 months ago

awardell commented 9 months ago

v4.1.stable

It is unclear when utilizing StringNames what their behavior is when creating one within a function.

const str_name := &"some_name"

func _process(_delta):
    var pressed = Input.is_action_pressed(str_name)

Does the above example have any advantage over the following?

func _process(_delta):
    var pressed = Input.is_action_pressed(&"some_name")

To elaborate, if we construct our StringName as in the second example, will a new StringName be constructed every frame, or is the compiler smart enough to avoid that? I've asked around on a couple forums and haven't received any answers with 100% certainty. Trawling the C++ code hasn't helped much either. I know the engine's C++ provides the SNAME macro which essentially makes the StringName const inline if used. Do GDScript or C# do anything similar?

It would be very helpful if the documentation would clarify whether there is an advantage to using a StringName if you do not store it in a variable, and likewise if there is an advantage to storing it in a variable. So often I see documentation examples passing a String literal to a StringName parameter, and I wonder what is the actual optimal usage. It would be good to have some official, documented clarification.

https://docs.godotengine.org/en/stable/classes/class_stringname.html https://docs.godotengine.org/en/stable/contributing/development/core_and_modules/core_types.html#stringname

AThousandShips commented 9 months ago

It is a literal, and like all literals it's evaluated on compile:

You will usually just pass a String to methods expecting a StringName and it will be automatically converted, but you may occasionally want to construct a StringName ahead of time with the StringName constructor or, in GDScript, the literal syntax &"example".

awardell commented 9 months ago

Yes, that quoted sentence is vague. So &"test" creates a StringName literal, and StringName("test") does not? The documentation does not make that clear. In fact it adds to the confusion. Is passing "test" equivalent to passing &"test"? They're both literals, but one is a String which I presume will construct StringName each time the line is run. If that isn't the case, it should be made clear on the documentation page.

Minoxs commented 9 months ago

From that quote it sounds like var pressed = Input.is_action_pressed("some_name") would convert it to a StringName literal every frame, while var pressed = Input.is_action_pressed(&"some_name") creates the literal at compile time.

Either way, I do agree the docs is a bit too vague considering that this is a meaningful difference.

idbrii commented 9 months ago

I have a pending PR to improve this exact paragraph:

https://github.com/godotengine/godot/pull/79815