@@ -716,11 +716,47 @@ static func typeof_is_any_array(type:int) -> bool:
716716## since [Script]'s enums are only defined as constant dictionaries,
717717## making it technically possible for typos of names to include dictionaries with non-[int] values.
718718## While [param enforce_values_of_int] defaults to [code]true[/code], it can be disabled for a menial speed boost when calling this method.
719- static func enum_extract_dict (name_or_object :Variant , enum_name := "" , enforce_values_of_int := true ) -> Dictionary :
720719## This methods is indented for use with methods like [make_int_enum_hint_string] or other means handling exported enum values in the inspector.
720+ static func enum_extract_dict (name_or_object :Variant , enum_name := "" , enforce_values_of_int := true , enforce_keys_of_stringlike := true ) -> Dictionary :
721721 if typeof (name_or_object ) == TYPE_DICTIONARY : # how passing in a gdscript enum type should (hopefully) work
722+ var typed_dicts_supported :bool = Engine .get_version_info ().major >= 4 and Engine .get_version_info ().minor >= 4 and name_or_object .is_typed ()
723+
724+ var kt :int = TYPE_NIL
725+ if typed_dicts_supported and name_or_object .is_typed_key ():
726+ kt = name_or_object .get_typed_key_builtin ()
727+ if enforce_keys_of_stringlike :
728+ if kt != TYPE_NIL : # If the keys are variant, we should check them manually
729+ assert (kt in [TYPE_STRING , TYPE_STRING_NAME ]) # if they are [Variant typed], which is ok when using both stringnames and strings as keys, since they are technically distinct but equally valid enum name types
730+ else :
731+ # humph
732+ # if you don't enforce the key types
733+ # then you don't get to use my super cool type fixer
734+ var key_types :Array = name_or_object .keys ().map (typeof )
735+ var string_key_count := key_types .count (TYPE_STRING )
736+ var string_name_key_count := key_types .count (TYPE_STRING_NAME )
737+ assert (string_key_count + string_name_key_count == key_types .size ())
738+ if string_key_count == key_types .size ():
739+ kt = TYPE_STRING
740+ elif string_name_key_count == key_types .size ():
741+ kt = TYPE_STRING_NAME
742+ # otherwise, just leave it variant, it's allowable (though perhaps this should change later on)
743+
744+ var vt :int = TYPE_NIL
745+ if typed_dicts_supported and name_or_object .is_typed_value ():
746+ vt = name_or_object .get_typed_value_builtin ()
722747 if enforce_values_of_int :
723- assert (name_or_object .values ().all (func (v ): return typeof (v ) == TYPE_INT ))
748+ if vt != TYPE_NIL : # If the values are variant, we should check them manually
749+ assert (vt == TYPE_INT ) # if they are [Variant typed]
750+ else :
751+ assert (name_or_object .values ().all (func (v ): return typeof (v ) == TYPE_INT ))
752+ vt = TYPE_INT
753+
754+ if typed_dicts_supported and (kt != TYPE_NIL or vt != TYPE_NIL ):
755+ name_or_object = Dictionary (name_or_object , kt , "" , null , vt , "" , null )
756+ name_or_object .make_read_only ()
757+ elif not name_or_object .is_read_only ():
758+ name_or_object = name_or_object .duplicate (false )
759+ name_or_object .make_read_only ()
724760 return name_or_object
725761 elif typeof (name_or_object ) in [TYPE_STRING , TYPE_STRING_NAME , TYPE_OBJECT ]:
726762 assert (enum_name != "" )
@@ -730,7 +766,7 @@ static func enum_extract_dict(name_or_object:Variant, enum_name := "", enforce_v
730766 var cls_name :String = ""
731767 # note that we don't use [get_class_name] here because we want the classdb name specifically
732768 if typeof (name_or_object ) in [TYPE_STRING , TYPE_STRING_NAME ]:
733- cls_name = name_or_object
769+ cls_name = str ( name_or_object )
734770 elif name_or_object is Script :
735771 cls_name = get_class_name (name_or_object )
736772 else :
@@ -786,7 +822,8 @@ static func make_string_suggestion_enum_hint_string(enum_dicts:Array[Variant]) -
786822 assert (ks != null )
787823
788824 for k in ks :
789- assert (not k in ns )
825+ if k in ns :
826+ continue
790827 assert (typeof (k ) in [TYPE_STRING , TYPE_STRING_NAME ])
791828 ns .append (k )
792829 return "," .join (ns )
@@ -803,6 +840,7 @@ static func make_int_enum_hint_string(enum_dicts:Array[Dictionary]) -> String:
803840 var dc := {}
804841 for d in enum_dicts :
805842 for k in d .keys ():
843+ assert (typeof (k ) in [TYPE_STRING , TYPE_STRING_NAME ])
806844 var v = d [k ]
807845 assert (v not in dc .keys ())
808846 dc [v ] = k
@@ -950,6 +988,8 @@ enum DebugInfoTypes{
950988 ENGINE_COPYRIGHT_INFO ,
951989 ENGINE_DONOR_INFO ,
952990 ENGINE_LICENCE_INFO ,
991+
992+ DEBUG_INFO_TYPES_MAX ,
953993}
954994
955995## Determines if the given [param enum_value] is a value compatible
@@ -971,11 +1011,12 @@ static func is_performance_monitor_id(enum_value:int) -> bool:
9711011## any common values with the [enum Performance.Monitor] enum,
9721012## so you are safe to use either enum's value as an id without further specification.
9731013static func get_debug_info (name_or_id :Variant , default :Variant = null ) -> Variant :
974- if typeof (name_or_id ) in [TYPE_STRING_NAME , TYPE_STRING ] and Performance .has_custom_monitor (name_or_id ):
975- return Performance .get_custom_monitor (name_or_id )
1014+ if typeof (name_or_id ) in [TYPE_STRING_NAME , TYPE_STRING ]:
1015+ if Performance .has_custom_monitor (name_or_id ):
1016+ return Performance .get_custom_monitor (name_or_id )
9761017 elif typeof (name_or_id ) == TYPE_INT :
9771018 match (name_or_id ):
978- var mon when mon in enum_extract_dict ( "Performance" , "Monitor" ). values ( ):
1019+ var mon when is_performance_monitor_id ( mon ):
9791020 return Performance .get_monitor (mon )
9801021
9811022 DebugInfoTypes .RUN_IS_DEBUG :
@@ -1041,18 +1082,9 @@ static func get_debug_info(name_or_id:Variant, default:Variant = null) -> Varian
10411082 DebugInfoTypes .OS_VERSION_ALIAS_OR_NUMBER :
10421083 return OS .get_version_alias ()
10431084 DebugInfoTypes .OS_BROWSER_OS :
1044- if OS .has_feature ("web_android" ):
1045- return "web_android"
1046- if OS .has_feature ("web_ios" ):
1047- return "web_ios"
1048- if OS .has_feature ("web_macos" ):
1049- return "web_macos"
1050- if OS .has_feature ("web_windows" ):
1051- return "web_windows"
1052- if OS .has_feature ("web_linuxbsd" ):
1053- return "web_linuxbsd"
1054- if OS .has_feature ("web" ):
1055- return "web"
1085+ for feat in ["web_android" , "web_ios" , "web_macos" , "web_windows" , "web_linuxbsd" , "web" ]:
1086+ if OS .has_feature (feat ):
1087+ return feat
10561088 return null
10571089 DebugInfoTypes .OS_GRANTED_PERMISSIONS :
10581090 return OS .get_granted_permissions ()
@@ -1219,10 +1251,7 @@ static func get_debug_info(name_or_id:Variant, default:Variant = null) -> Varian
12191251 DebugInfoTypes .XR_INTERFACE_COUNT :
12201252 return XRServer .get_interface_count ()
12211253 DebugInfoTypes .XR_INTERFACE_NAMES :
1222- var interfaces = []
1223- for i in range (XRServer .get_interface_count ()):
1224- interfaces .append (XRServer .get_interface (i ).get_name ())
1225- return interfaces
1254+ return range (XRServer .get_interface_count ()).map (func (i ): return XRServer .get_interface (i ).get_name ())
12261255
12271256 DebugInfoTypes .ENGINE_VERSION :
12281257 return Engine .get_version_info ()
0 commit comments