godot icon indicating copy to clipboard operation
godot copied to clipboard

GDScript: Unify StringName and String

Open rune-scape opened this issue 3 years ago • 5 comments

this change aims to fix #64171 by letting String and StringName be used nearly interchangeably in GDScript

registers all string methods to StringName in variant_call.cpp -- So String methods can be used on StringNames ('&"stringname".has("str")' and vice versa)

fills in the gaps between String and StringName in variant_op.cpp -- So '"str" in &"stringname"' works and among others

Array will silently coerce Strings and StringNames into each other when typed in any method that takes a variant input -- So Array acts like they are almost the same type, but silently converts if inserted or anything into a typed Array -- fixes #63965, all 4 tests return true

other functions in untyped Array will also compare Strings and StringNames -- fixes #68918

Dictionary now compares String and StringName keys -- which fixes #62957

lastly, the analyzer will do the same -- So it doesn't tell you you can't assign Array[String] to Array[StringName] and the compiler will make an exception in match statements for String and StringName, allowing comparisons -- which fixes #60145

also added a check for StringName in a couple places (regex.cpp and scene_rpc_interface.cpp)

Notes and things to discuss:

  • Array ==, <, >, etc. still do not compare Strings and StringNames as equal, not sure if this is desired?
  • Dictionary ==, <, >, still DO compare String and StringName keys as equal, but only because StringNames are converted to Strings on insertion, does that make it different from Array?
  • Strings and StringNames still cannot be compared using <, >, etc. in GDScript, should this be allowed?
  • Variant could benefit from an is_string() method..

rune-scape avatar Nov 16 '22 20:11 rune-scape

I've found no functionality regression.

As one would expect, has() and in are slower (in the ballpark of 2x as slow), insofar as arrays are concerned (and not only Array[StringName] or Array[String].) To get these results, I compared the Linux Mono editor artifact with beta 5, running lots of loops on GDScript and timing it with the Time singleton.

MewPurPur avatar Nov 18 '22 18:11 MewPurPur

@MewPurPur that performance diff shouldn't be the case, although i did push a new version since you tested i think maybe the artifacts aren't production builds? i got similar performance running this test on a production build vs master: test_unify.zip

rune-scape avatar Nov 19 '22 11:11 rune-scape

In order for the last check to pass, https://github.com/godotengine/godot-cpp/pull/930 needs to be merged to solve ambiguous overload errors

rune-scape avatar Nov 20 '22 10:11 rune-scape

Fait critique, the benchmarks need something to compare to.

MewPurPur avatar Nov 21 '22 11:11 MewPurPur

I tested this pr and it seems to 'fix' the match statement, in gd3 this worked

match node.get_name():
    "test1":
         pass
     _:
         pass

And this PR makes this code work again ( Need to do StringName("test1") for the match to work, or String(node.get_name()) without this PR)

Begah avatar Nov 27 '22 10:11 Begah

I didn't test, but looking at the code it also fixes #68834

KoBeWi avatar Dec 09 '22 16:12 KoBeWi

Thanks!

akien-mga avatar Dec 09 '22 17:12 akien-mga

I'm not sure if it belongs here, in a separate bug report, or in a feature request, but int lacks a StringName constructor and will give "Invalid type in 'int' constructor. Cannot convert argument 1 from StringName to String." if you try to do say int(some_node.name).

To me that feels logically related to the unification of StringName and String.

Gastronok avatar May 07 '23 17:05 Gastronok

Also not sure if this belongs here, but: funcs that take String like load() need something like this:

var a = ProjectSettings.get_global_class_list()
var find = a.filter(func(d): return &"ResourcePrinterPlants" in d["class"])
var c = load(str(find[0].path)).new()

It took me ages to think of using str()

donn-xx avatar May 19 '23 08:05 donn-xx

Also not sure if this belongs here, but: funcs that take String like load() need something like this:

#77164 fixes this.

dalexeev avatar May 19 '23 08:05 dalexeev

Also not sure if this belongs here, but: funcs that take String like load() need something like this:

#77164 fixes this.

Had a look, but don't quickly see how.

donn-xx avatar May 19 '23 09:05 donn-xx