| 
									
										
										
										
											2025-04-26 21:10:41 +03:00
										 |  |  | @warning_ignore_start("unsafe_call_argument") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-28 17:41:52 +03:00
										 |  |  | class_name Utils | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-26 21:10:41 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-28 17:41:52 +03:00
										 |  |  | # `assert()` is not evaluated in non-debug builds. Do not use `assert()` | 
					
						
							|  |  |  | # for anything other than testing the `assert()` itself. | 
					
						
							|  |  |  | static func check(condition: Variant) -> void: | 
					
						
							| 
									
										
										
										
											2025-04-26 21:10:41 +03:00
										 |  |  | 	if condition: | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	printerr("Check failed. Backtrace (most recent call first):") | 
					
						
							|  |  |  | 	for stack: ScriptBacktrace in Engine.capture_script_backtraces(): | 
					
						
							|  |  |  | 		if stack.get_language_name() == "GDScript": | 
					
						
							|  |  |  | 			var dir: String | 
					
						
							|  |  |  | 			for i: int in stack.get_frame_count(): | 
					
						
							|  |  |  | 				if i == 0: | 
					
						
							|  |  |  | 					dir = stack.get_frame_file(i).trim_suffix("utils.notest.gd") | 
					
						
							|  |  |  | 				else: | 
					
						
							|  |  |  | 					printerr("  %s:%d @ %s()" % [ | 
					
						
							|  |  |  | 						stack.get_frame_file(i).trim_prefix(dir), | 
					
						
							|  |  |  | 						stack.get_frame_line(i), | 
					
						
							|  |  |  | 						stack.get_frame_function(i), | 
					
						
							|  |  |  | 					]) | 
					
						
							|  |  |  | 			break | 
					
						
							| 
									
										
										
										
											2024-08-28 17:41:52 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-12 21:55:55 +03:00
										 |  |  | static func get_type(property: Dictionary, is_return: bool = false) -> String: | 
					
						
							|  |  |  | 	match property.type: | 
					
						
							|  |  |  | 		TYPE_NIL: | 
					
						
							|  |  |  | 			if property.usage & PROPERTY_USAGE_NIL_IS_VARIANT: | 
					
						
							|  |  |  | 				return "Variant" | 
					
						
							|  |  |  | 			return "void" if is_return else "null" | 
					
						
							|  |  |  | 		TYPE_INT: | 
					
						
							|  |  |  | 			if property.usage & PROPERTY_USAGE_CLASS_IS_ENUM: | 
					
						
							|  |  |  | 				if property.class_name == &"": | 
					
						
							|  |  |  | 					return "<unknown enum>" | 
					
						
							|  |  |  | 				return property.class_name | 
					
						
							|  |  |  | 		TYPE_ARRAY: | 
					
						
							|  |  |  | 			if property.hint == PROPERTY_HINT_ARRAY_TYPE: | 
					
						
							|  |  |  | 				if str(property.hint_string).is_empty(): | 
					
						
							|  |  |  | 					return "Array[<unknown type>]" | 
					
						
							|  |  |  | 				return "Array[%s]" % property.hint_string | 
					
						
							| 
									
										
										
										
											2023-06-24 13:03:28 -05:00
										 |  |  | 		TYPE_DICTIONARY: | 
					
						
							|  |  |  | 			if property.hint == PROPERTY_HINT_DICTIONARY_TYPE: | 
					
						
							|  |  |  | 				if str(property.hint_string).is_empty(): | 
					
						
							|  |  |  | 					return "Dictionary[<unknown type>, <unknown type>]" | 
					
						
							|  |  |  | 				return "Dictionary[%s]" % str(property.hint_string).replace(";", ", ") | 
					
						
							| 
									
										
										
										
											2023-09-12 21:55:55 +03:00
										 |  |  | 		TYPE_OBJECT: | 
					
						
							|  |  |  | 			if not str(property.class_name).is_empty(): | 
					
						
							|  |  |  | 				return property.class_name | 
					
						
							| 
									
										
										
										
											2023-09-25 20:33:43 +02:00
										 |  |  | 	return type_string(property.type) | 
					
						
							| 
									
										
										
										
											2023-09-12 21:55:55 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-19 20:35:45 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-26 21:10:41 +03:00
										 |  |  | static func get_property_signature( | 
					
						
							|  |  |  | 		property: Dictionary, | 
					
						
							|  |  |  | 		base: Object = null, | 
					
						
							|  |  |  | 		is_static: bool = false, | 
					
						
							|  |  |  | ) -> String: | 
					
						
							| 
									
										
										
										
											2023-12-19 20:56:30 +03:00
										 |  |  | 	if property.usage & PROPERTY_USAGE_CATEGORY: | 
					
						
							|  |  |  | 		return '@export_category("%s")' % str(property.name).c_escape() | 
					
						
							|  |  |  | 	if property.usage & PROPERTY_USAGE_GROUP: | 
					
						
							|  |  |  | 		return '@export_group("%s")' % str(property.name).c_escape() | 
					
						
							|  |  |  | 	if property.usage & PROPERTY_USAGE_SUBGROUP: | 
					
						
							|  |  |  | 		return '@export_subgroup("%s")' % str(property.name).c_escape() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-12 21:55:55 +03:00
										 |  |  | 	var result: String = "" | 
					
						
							|  |  |  | 	if not (property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE): | 
					
						
							|  |  |  | 		printerr("Missing `PROPERTY_USAGE_SCRIPT_VARIABLE` flag.") | 
					
						
							|  |  |  | 	if is_static: | 
					
						
							|  |  |  | 		result += "static " | 
					
						
							|  |  |  | 	result += "var " + property.name + ": " + get_type(property) | 
					
						
							| 
									
										
										
										
											2023-12-19 20:56:30 +03:00
										 |  |  | 	if is_instance_valid(base): | 
					
						
							|  |  |  | 		result += " = " + var_to_str(base.get(property.name)) | 
					
						
							| 
									
										
										
										
											2023-09-12 21:55:55 +03:00
										 |  |  | 	return result | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-19 20:35:45 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-07 19:32:08 +09:00
										 |  |  | static func get_human_readable_hint_string(property: Dictionary) -> String: | 
					
						
							|  |  |  | 	if property.type >= TYPE_ARRAY and property.hint == PROPERTY_HINT_TYPE_STRING: | 
					
						
							|  |  |  | 		var type_hint_prefixes: String = "" | 
					
						
							|  |  |  | 		var hint_string: String = property.hint_string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		while true: | 
					
						
							|  |  |  | 			if not hint_string.contains(":"): | 
					
						
							| 
									
										
										
										
											2024-08-28 17:41:52 +03:00
										 |  |  | 				printerr("Invalid PROPERTY_HINT_TYPE_STRING format.") | 
					
						
							| 
									
										
										
										
											2023-10-07 19:32:08 +09:00
										 |  |  | 			var elem_type_hint: String = hint_string.get_slice(":", 0) | 
					
						
							|  |  |  | 			hint_string = hint_string.substr(elem_type_hint.length() + 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var elem_type: int | 
					
						
							|  |  |  | 			var elem_hint: int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if elem_type_hint.is_valid_int(): | 
					
						
							|  |  |  | 				elem_type = elem_type_hint.to_int() | 
					
						
							| 
									
										
										
										
											2024-04-15 22:10:47 +03:00
										 |  |  | 				type_hint_prefixes += "<%s>:" % type_string(elem_type) | 
					
						
							| 
									
										
										
										
											2023-10-07 19:32:08 +09:00
										 |  |  | 			else: | 
					
						
							|  |  |  | 				if elem_type_hint.count("/") != 1: | 
					
						
							| 
									
										
										
										
											2024-08-28 17:41:52 +03:00
										 |  |  | 					printerr("Invalid PROPERTY_HINT_TYPE_STRING format.") | 
					
						
							| 
									
										
										
										
											2023-10-07 19:32:08 +09:00
										 |  |  | 				elem_type = elem_type_hint.get_slice("/", 0).to_int() | 
					
						
							|  |  |  | 				elem_hint = elem_type_hint.get_slice("/", 1).to_int() | 
					
						
							| 
									
										
										
										
											2024-04-15 22:10:47 +03:00
										 |  |  | 				type_hint_prefixes += "<%s>/<%s>:" % [ | 
					
						
							|  |  |  | 					type_string(elem_type), | 
					
						
							|  |  |  | 					get_property_hint_name(elem_hint).trim_prefix("PROPERTY_HINT_"), | 
					
						
							| 
									
										
										
										
											2023-10-07 19:32:08 +09:00
										 |  |  | 				] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-15 22:10:47 +03:00
										 |  |  | 			if elem_type < TYPE_ARRAY or hint_string.is_empty(): | 
					
						
							| 
									
										
										
										
											2023-10-07 19:32:08 +09:00
										 |  |  | 				break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return type_hint_prefixes + hint_string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return property.hint_string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-26 21:10:41 +03:00
										 |  |  | static func print_property_extended_info( | 
					
						
							|  |  |  | 		property: Dictionary, | 
					
						
							|  |  |  | 		base: Object = null, | 
					
						
							|  |  |  | 		is_static: bool = false, | 
					
						
							|  |  |  | ) -> void: | 
					
						
							| 
									
										
										
										
											2023-12-19 20:56:30 +03:00
										 |  |  | 	print(get_property_signature(property, base, is_static)) | 
					
						
							| 
									
										
										
										
											2024-04-15 22:10:47 +03:00
										 |  |  | 	print('  hint=%s hint_string="%s" usage=%s class_name=&"%s"' % [ | 
					
						
							| 
									
										
										
										
											2023-09-19 20:35:45 +03:00
										 |  |  | 		get_property_hint_name(property.hint).trim_prefix("PROPERTY_HINT_"), | 
					
						
							| 
									
										
										
										
											2024-04-15 22:10:47 +03:00
										 |  |  | 		get_human_readable_hint_string(property).c_escape(), | 
					
						
							| 
									
										
										
										
											2023-09-19 20:35:45 +03:00
										 |  |  | 		get_property_usage_string(property.usage).replace("PROPERTY_USAGE_", ""), | 
					
						
							| 
									
										
										
										
											2025-04-26 21:10:41 +03:00
										 |  |  | 		str(property.class_name).c_escape(), | 
					
						
							| 
									
										
										
										
											2023-12-19 20:56:30 +03:00
										 |  |  | 	]) | 
					
						
							| 
									
										
										
										
											2023-09-19 20:35:45 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-12 21:55:55 +03:00
										 |  |  | static func get_method_signature(method: Dictionary, is_signal: bool = false) -> String: | 
					
						
							|  |  |  | 	var result: String = "" | 
					
						
							|  |  |  | 	if method.flags & METHOD_FLAG_STATIC: | 
					
						
							|  |  |  | 		result += "static " | 
					
						
							|  |  |  | 	result += ("signal " if is_signal else "func ") + method.name + "(" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var args: Array[Dictionary] = method.args | 
					
						
							|  |  |  | 	var default_args: Array = method.default_args | 
					
						
							|  |  |  | 	var mandatory_argc: int = args.size() - default_args.size() | 
					
						
							| 
									
										
										
										
											2025-04-26 21:10:41 +03:00
										 |  |  | 	for i: int in args.size(): | 
					
						
							| 
									
										
										
										
											2023-09-12 21:55:55 +03:00
										 |  |  | 		if i > 0: | 
					
						
							|  |  |  | 			result += ", " | 
					
						
							|  |  |  | 		var arg: Dictionary = args[i] | 
					
						
							|  |  |  | 		result += arg.name + ": " + get_type(arg) | 
					
						
							|  |  |  | 		if i >= mandatory_argc: | 
					
						
							|  |  |  | 			result += " = " + var_to_str(default_args[i - mandatory_argc]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	result += ")" | 
					
						
							|  |  |  | 	if is_signal: | 
					
						
							|  |  |  | 		if get_type(method.return, true) != "void": | 
					
						
							|  |  |  | 			printerr("Signal return type must be `void`.") | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		result += " -> " + get_type(method.return, true) | 
					
						
							|  |  |  | 	return result | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-19 20:35:45 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | static func get_property_hint_name(hint: PropertyHint) -> String: | 
					
						
							|  |  |  | 	match hint: | 
					
						
							|  |  |  | 		PROPERTY_HINT_NONE: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_NONE" | 
					
						
							|  |  |  | 		PROPERTY_HINT_RANGE: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_RANGE" | 
					
						
							|  |  |  | 		PROPERTY_HINT_ENUM: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_ENUM" | 
					
						
							|  |  |  | 		PROPERTY_HINT_ENUM_SUGGESTION: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_ENUM_SUGGESTION" | 
					
						
							|  |  |  | 		PROPERTY_HINT_EXP_EASING: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_EXP_EASING" | 
					
						
							|  |  |  | 		PROPERTY_HINT_LINK: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_LINK" | 
					
						
							|  |  |  | 		PROPERTY_HINT_FLAGS: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_FLAGS" | 
					
						
							|  |  |  | 		PROPERTY_HINT_LAYERS_2D_RENDER: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_LAYERS_2D_RENDER" | 
					
						
							|  |  |  | 		PROPERTY_HINT_LAYERS_2D_PHYSICS: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_LAYERS_2D_PHYSICS" | 
					
						
							|  |  |  | 		PROPERTY_HINT_LAYERS_2D_NAVIGATION: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_LAYERS_2D_NAVIGATION" | 
					
						
							|  |  |  | 		PROPERTY_HINT_LAYERS_3D_RENDER: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_LAYERS_3D_RENDER" | 
					
						
							|  |  |  | 		PROPERTY_HINT_LAYERS_3D_PHYSICS: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_LAYERS_3D_PHYSICS" | 
					
						
							|  |  |  | 		PROPERTY_HINT_LAYERS_3D_NAVIGATION: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_LAYERS_3D_NAVIGATION" | 
					
						
							|  |  |  | 		PROPERTY_HINT_LAYERS_AVOIDANCE: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_LAYERS_AVOIDANCE" | 
					
						
							|  |  |  | 		PROPERTY_HINT_FILE: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_FILE" | 
					
						
							|  |  |  | 		PROPERTY_HINT_DIR: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_DIR" | 
					
						
							|  |  |  | 		PROPERTY_HINT_GLOBAL_FILE: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_GLOBAL_FILE" | 
					
						
							|  |  |  | 		PROPERTY_HINT_GLOBAL_DIR: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_GLOBAL_DIR" | 
					
						
							|  |  |  | 		PROPERTY_HINT_RESOURCE_TYPE: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_RESOURCE_TYPE" | 
					
						
							|  |  |  | 		PROPERTY_HINT_MULTILINE_TEXT: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_MULTILINE_TEXT" | 
					
						
							|  |  |  | 		PROPERTY_HINT_EXPRESSION: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_EXPRESSION" | 
					
						
							|  |  |  | 		PROPERTY_HINT_PLACEHOLDER_TEXT: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_PLACEHOLDER_TEXT" | 
					
						
							|  |  |  | 		PROPERTY_HINT_COLOR_NO_ALPHA: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_COLOR_NO_ALPHA" | 
					
						
							|  |  |  | 		PROPERTY_HINT_OBJECT_ID: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_OBJECT_ID" | 
					
						
							|  |  |  | 		PROPERTY_HINT_TYPE_STRING: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_TYPE_STRING" | 
					
						
							|  |  |  | 		PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE" | 
					
						
							|  |  |  | 		PROPERTY_HINT_OBJECT_TOO_BIG: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_OBJECT_TOO_BIG" | 
					
						
							|  |  |  | 		PROPERTY_HINT_NODE_PATH_VALID_TYPES: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_NODE_PATH_VALID_TYPES" | 
					
						
							|  |  |  | 		PROPERTY_HINT_SAVE_FILE: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_SAVE_FILE" | 
					
						
							|  |  |  | 		PROPERTY_HINT_GLOBAL_SAVE_FILE: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_GLOBAL_SAVE_FILE" | 
					
						
							|  |  |  | 		PROPERTY_HINT_INT_IS_OBJECTID: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_INT_IS_OBJECTID" | 
					
						
							|  |  |  | 		PROPERTY_HINT_INT_IS_POINTER: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_INT_IS_POINTER" | 
					
						
							|  |  |  | 		PROPERTY_HINT_ARRAY_TYPE: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_ARRAY_TYPE" | 
					
						
							| 
									
										
										
										
											2023-06-24 13:03:28 -05:00
										 |  |  | 		PROPERTY_HINT_DICTIONARY_TYPE: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_DICTIONARY_TYPE" | 
					
						
							| 
									
										
										
										
											2023-09-19 20:35:45 +03:00
										 |  |  | 		PROPERTY_HINT_LOCALE_ID: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_LOCALE_ID" | 
					
						
							|  |  |  | 		PROPERTY_HINT_LOCALIZABLE_STRING: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_LOCALIZABLE_STRING" | 
					
						
							|  |  |  | 		PROPERTY_HINT_NODE_TYPE: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_NODE_TYPE" | 
					
						
							|  |  |  | 		PROPERTY_HINT_HIDE_QUATERNION_EDIT: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_HIDE_QUATERNION_EDIT" | 
					
						
							|  |  |  | 		PROPERTY_HINT_PASSWORD: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_PASSWORD" | 
					
						
							| 
									
										
										
										
											2024-09-26 20:34:29 +03:00
										 |  |  | 		PROPERTY_HINT_TOOL_BUTTON: | 
					
						
							|  |  |  | 			return "PROPERTY_HINT_TOOL_BUTTON" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-28 17:41:52 +03:00
										 |  |  | 	printerr("Argument `hint` is invalid. Use `PROPERTY_HINT_*` constants.") | 
					
						
							| 
									
										
										
										
											2023-09-19 20:35:45 +03:00
										 |  |  | 	return "<invalid hint>" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static func get_property_usage_string(usage: int) -> String: | 
					
						
							|  |  |  | 	if usage == PROPERTY_USAGE_NONE: | 
					
						
							|  |  |  | 		return "PROPERTY_USAGE_NONE" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const FLAGS: Array[Array] = [ | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_STORAGE, "PROPERTY_USAGE_STORAGE"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_EDITOR, "PROPERTY_USAGE_EDITOR"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_INTERNAL, "PROPERTY_USAGE_INTERNAL"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_CHECKABLE, "PROPERTY_USAGE_CHECKABLE"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_CHECKED, "PROPERTY_USAGE_CHECKED"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_GROUP, "PROPERTY_USAGE_GROUP"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_CATEGORY, "PROPERTY_USAGE_CATEGORY"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_SUBGROUP, "PROPERTY_USAGE_SUBGROUP"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_CLASS_IS_BITFIELD, "PROPERTY_USAGE_CLASS_IS_BITFIELD"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_NO_INSTANCE_STATE, "PROPERTY_USAGE_NO_INSTANCE_STATE"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_RESTART_IF_CHANGED, "PROPERTY_USAGE_RESTART_IF_CHANGED"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_SCRIPT_VARIABLE, "PROPERTY_USAGE_SCRIPT_VARIABLE"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_STORE_IF_NULL, "PROPERTY_USAGE_STORE_IF_NULL"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED, "PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE, "PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_CLASS_IS_ENUM, "PROPERTY_USAGE_CLASS_IS_ENUM"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_NIL_IS_VARIANT, "PROPERTY_USAGE_NIL_IS_VARIANT"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_ARRAY, "PROPERTY_USAGE_ARRAY"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_ALWAYS_DUPLICATE, "PROPERTY_USAGE_ALWAYS_DUPLICATE"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_NEVER_DUPLICATE, "PROPERTY_USAGE_NEVER_DUPLICATE"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_HIGH_END_GFX, "PROPERTY_USAGE_HIGH_END_GFX"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT, "PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT, "PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_KEYING_INCREMENTS, "PROPERTY_USAGE_KEYING_INCREMENTS"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_DEFERRED_SET_RESOURCE, "PROPERTY_USAGE_DEFERRED_SET_RESOURCE"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT, "PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_EDITOR_BASIC_SETTING, "PROPERTY_USAGE_EDITOR_BASIC_SETTING"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_READ_ONLY, "PROPERTY_USAGE_READ_ONLY"], | 
					
						
							|  |  |  | 		[PROPERTY_USAGE_SECRET, "PROPERTY_USAGE_SECRET"], | 
					
						
							|  |  |  | 	] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var result: String = "" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-19 20:56:30 +03:00
										 |  |  | 	if (usage & PROPERTY_USAGE_DEFAULT) == PROPERTY_USAGE_DEFAULT: | 
					
						
							|  |  |  | 		result += "PROPERTY_USAGE_DEFAULT|" | 
					
						
							|  |  |  | 		usage &= ~PROPERTY_USAGE_DEFAULT | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-26 21:10:41 +03:00
										 |  |  | 	for flag: Array in FLAGS: | 
					
						
							| 
									
										
										
										
											2023-09-19 20:35:45 +03:00
										 |  |  | 		if usage & flag[0]: | 
					
						
							|  |  |  | 			result += flag[1] + "|" | 
					
						
							|  |  |  | 			usage &= ~flag[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if usage != PROPERTY_USAGE_NONE: | 
					
						
							| 
									
										
										
										
											2024-08-28 17:41:52 +03:00
										 |  |  | 		printerr("Argument `usage` is invalid. Use `PROPERTY_USAGE_*` constants.") | 
					
						
							| 
									
										
										
										
											2023-09-19 20:35:45 +03:00
										 |  |  | 		return "<invalid usage flags>" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return result.left(-1) |