diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/SCsub | 2 | ||||
-rw-r--r-- | core/extension/gdextension_interface.h | 136 | ||||
-rw-r--r-- | core/input/input_event.cpp | 2 | ||||
-rw-r--r-- | core/io/compression.cpp | 8 | ||||
-rw-r--r-- | core/io/file_access_zip.cpp | 2 | ||||
-rw-r--r-- | core/io/image.cpp | 26 | ||||
-rw-r--r-- | core/io/image.h | 5 | ||||
-rw-r--r-- | core/io/json.cpp | 8 | ||||
-rw-r--r-- | core/io/resource_loader.cpp | 25 | ||||
-rw-r--r-- | core/io/resource_loader.h | 2 | ||||
-rw-r--r-- | core/object/object.cpp | 8 | ||||
-rw-r--r-- | core/object/script_language.cpp | 10 | ||||
-rw-r--r-- | core/object/script_language.h | 5 | ||||
-rw-r--r-- | core/object/script_language_extension.h | 2 | ||||
-rw-r--r-- | core/object/undo_redo.h | 2 | ||||
-rw-r--r-- | core/object/worker_thread_pool.cpp | 9 | ||||
-rw-r--r-- | core/os/os.cpp | 10 | ||||
-rw-r--r-- | core/os/threaded_array_processor.h | 87 | ||||
-rw-r--r-- | core/string/ustring.cpp | 90 | ||||
-rw-r--r-- | core/string/ustring.h | 1 | ||||
-rw-r--r-- | core/variant/callable_bind.cpp | 22 | ||||
-rw-r--r-- | core/variant/callable_bind.h | 2 | ||||
-rw-r--r-- | core/variant/native_ptr.h | 70 | ||||
-rw-r--r-- | core/variant/variant_parser.cpp | 60 |
24 files changed, 405 insertions, 189 deletions
diff --git a/core/SCsub b/core/SCsub index a0176f6c33..7e9cd97351 100644 --- a/core/SCsub +++ b/core/SCsub @@ -65,7 +65,7 @@ thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_mis env_thirdparty.add_source_files(thirdparty_obj, thirdparty_misc_sources) # Brotli -if env["brotli"]: +if env["brotli"] and env["builtin_brotli"]: thirdparty_brotli_dir = "#thirdparty/brotli/" thirdparty_brotli_sources = [ "common/constants.c", diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h index 2a328c9a34..4d7bdf9502 100644 --- a/core/extension/gdextension_interface.h +++ b/core/extension/gdextension_interface.h @@ -490,6 +490,7 @@ typedef struct { /** * @name get_godot_version + * @since 4.1 * * Gets the Godot version that the GDExtension was loaded into. * @@ -501,6 +502,7 @@ typedef void (*GDExtensionInterfaceGetGodotVersion)(GDExtensionGodotVersion *r_g /** * @name mem_alloc + * @since 4.1 * * Allocates memory. * @@ -512,6 +514,7 @@ typedef void *(*GDExtensionInterfaceMemAlloc)(size_t p_bytes); /** * @name mem_realloc + * @since 4.1 * * Reallocates memory. * @@ -524,6 +527,7 @@ typedef void *(*GDExtensionInterfaceMemRealloc)(void *p_ptr, size_t p_bytes); /** * @name mem_free + * @since 4.1 * * Frees memory. * @@ -535,6 +539,7 @@ typedef void (*GDExtensionInterfaceMemFree)(void *p_ptr); /** * @name print_error + * @since 4.1 * * Logs an error to Godot's built-in debugger and to the OS terminal. * @@ -548,6 +553,7 @@ typedef void (*GDExtensionInterfacePrintError)(const char *p_description, const /** * @name print_error_with_message + * @since 4.1 * * Logs an error with a message to Godot's built-in debugger and to the OS terminal. * @@ -562,6 +568,7 @@ typedef void (*GDExtensionInterfacePrintErrorWithMessage)(const char *p_descript /** * @name print_warning + * @since 4.1 * * Logs a warning to Godot's built-in debugger and to the OS terminal. * @@ -575,6 +582,7 @@ typedef void (*GDExtensionInterfacePrintWarning)(const char *p_description, cons /** * @name print_warning_with_message + * @since 4.1 * * Logs a warning with a message to Godot's built-in debugger and to the OS terminal. * @@ -589,6 +597,7 @@ typedef void (*GDExtensionInterfacePrintWarningWithMessage)(const char *p_descri /** * @name print_script_error + * @since 4.1 * * Logs a script error to Godot's built-in debugger and to the OS terminal. * @@ -602,6 +611,7 @@ typedef void (*GDExtensionInterfacePrintScriptError)(const char *p_description, /** * @name print_script_error_with_message + * @since 4.1 * * Logs a script error with a message to Godot's built-in debugger and to the OS terminal. * @@ -616,6 +626,7 @@ typedef void (*GDExtensionInterfacePrintScriptErrorWithMessage)(const char *p_de /** * @name get_native_struct_size + * @since 4.1 * * Gets the size of a native struct (ex. ObjectID) in bytes. * @@ -629,6 +640,7 @@ typedef uint64_t (*GDExtensionInterfaceGetNativeStructSize)(GDExtensionConstStri /** * @name variant_new_copy + * @since 4.1 * * Copies one Variant into a another. * @@ -639,6 +651,7 @@ typedef void (*GDExtensionInterfaceVariantNewCopy)(GDExtensionUninitializedVaria /** * @name variant_new_nil + * @since 4.1 * * Creates a new Variant containing nil. * @@ -648,6 +661,7 @@ typedef void (*GDExtensionInterfaceVariantNewNil)(GDExtensionUninitializedVarian /** * @name variant_destroy + * @since 4.1 * * Destroys a Variant. * @@ -657,6 +671,7 @@ typedef void (*GDExtensionInterfaceVariantDestroy)(GDExtensionVariantPtr p_self) /** * @name variant_call + * @since 4.1 * * Calls a method on a Variant. * @@ -673,6 +688,7 @@ typedef void (*GDExtensionInterfaceVariantCall)(GDExtensionVariantPtr p_self, GD /** * @name variant_call_static + * @since 4.1 * * Calls a static method on a Variant. * @@ -689,6 +705,7 @@ typedef void (*GDExtensionInterfaceVariantCallStatic)(GDExtensionVariantType p_t /** * @name variant_evaluate + * @since 4.1 * * Evaluate an operator on two Variants. * @@ -704,6 +721,7 @@ typedef void (*GDExtensionInterfaceVariantEvaluate)(GDExtensionVariantOperator p /** * @name variant_set + * @since 4.1 * * Sets a key on a Variant to a value. * @@ -718,6 +736,7 @@ typedef void (*GDExtensionInterfaceVariantSet)(GDExtensionVariantPtr p_self, GDE /** * @name variant_set_named + * @since 4.1 * * Sets a named key on a Variant to a value. * @@ -732,6 +751,7 @@ typedef void (*GDExtensionInterfaceVariantSetNamed)(GDExtensionVariantPtr p_self /** * @name variant_set_keyed + * @since 4.1 * * Sets a keyed property on a Variant to a value. * @@ -746,6 +766,7 @@ typedef void (*GDExtensionInterfaceVariantSetKeyed)(GDExtensionVariantPtr p_self /** * @name variant_set_indexed + * @since 4.1 * * Sets an index on a Variant to a value. * @@ -759,6 +780,7 @@ typedef void (*GDExtensionInterfaceVariantSetIndexed)(GDExtensionVariantPtr p_se /** * @name variant_get + * @since 4.1 * * Gets the value of a key from a Variant. * @@ -771,6 +793,7 @@ typedef void (*GDExtensionInterfaceVariantGet)(GDExtensionConstVariantPtr p_self /** * @name variant_get_named + * @since 4.1 * * Gets the value of a named key from a Variant. * @@ -783,6 +806,7 @@ typedef void (*GDExtensionInterfaceVariantGetNamed)(GDExtensionConstVariantPtr p /** * @name variant_get_keyed + * @since 4.1 * * Gets the value of a keyed property from a Variant. * @@ -795,6 +819,7 @@ typedef void (*GDExtensionInterfaceVariantGetKeyed)(GDExtensionConstVariantPtr p /** * @name variant_get_indexed + * @since 4.1 * * Gets the value of an index from a Variant. * @@ -808,6 +833,7 @@ typedef void (*GDExtensionInterfaceVariantGetIndexed)(GDExtensionConstVariantPtr /** * @name variant_iter_init + * @since 4.1 * * Initializes an iterator over a Variant. * @@ -823,6 +849,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantIterInit)(GDExtensionConstV /** * @name variant_iter_next + * @since 4.1 * * Gets the next value for an iterator over a Variant. * @@ -838,6 +865,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantIterNext)(GDExtensionConstV /** * @name variant_iter_get + * @since 4.1 * * Gets the next value for an iterator over a Variant. * @@ -852,6 +880,7 @@ typedef void (*GDExtensionInterfaceVariantIterGet)(GDExtensionConstVariantPtr p_ /** * @name variant_hash + * @since 4.1 * * Gets the hash of a Variant. * @@ -865,6 +894,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceVariantHash)(GDExtensionConstVarian /** * @name variant_recursive_hash + * @since 4.1 * * Gets the recursive hash of a Variant. * @@ -879,6 +909,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceVariantRecursiveHash)(GDExtensionCo /** * @name variant_hash_compare + * @since 4.1 * * Compares two Variants by their hash. * @@ -893,6 +924,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantHashCompare)(GDExtensionCon /** * @name variant_booleanize + * @since 4.1 * * Converts a Variant to a boolean. * @@ -904,6 +936,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantBooleanize)(GDExtensionCons /** * @name variant_duplicate + * @since 4.1 * * Duplicates a Variant. * @@ -915,6 +948,7 @@ typedef void (*GDExtensionInterfaceVariantDuplicate)(GDExtensionConstVariantPtr /** * @name variant_stringify + * @since 4.1 * * Converts a Variant to a string. * @@ -925,6 +959,7 @@ typedef void (*GDExtensionInterfaceVariantStringify)(GDExtensionConstVariantPtr /** * @name variant_get_type + * @since 4.1 * * Gets the type of a Variant. * @@ -936,6 +971,7 @@ typedef GDExtensionVariantType (*GDExtensionInterfaceVariantGetType)(GDExtension /** * @name variant_has_method + * @since 4.1 * * Checks if a Variant has the given method. * @@ -948,6 +984,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantHasMethod)(GDExtensionConst /** * @name variant_has_member + * @since 4.1 * * Checks if a type of Variant has the given member. * @@ -960,6 +997,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantHasMember)(GDExtensionVaria /** * @name variant_has_key + * @since 4.1 * * Checks if a Variant has a key. * @@ -973,6 +1011,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantHasKey)(GDExtensionConstVar /** * @name variant_get_type_name + * @since 4.1 * * Gets the name of a Variant type. * @@ -983,6 +1022,7 @@ typedef void (*GDExtensionInterfaceVariantGetTypeName)(GDExtensionVariantType p_ /** * @name variant_can_convert + * @since 4.1 * * Checks if Variants can be converted from one type to another. * @@ -995,6 +1035,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantCanConvert)(GDExtensionVari /** * @name variant_can_convert_strict + * @since 4.1 * * Checks if Variant can be converted from one type to another using stricter rules. * @@ -1007,6 +1048,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceVariantCanConvertStrict)(GDExtensi /** * @name get_variant_from_type_constructor + * @since 4.1 * * Gets a pointer to a function that can create a Variant of the given type from a raw value. * @@ -1018,6 +1060,7 @@ typedef GDExtensionVariantFromTypeConstructorFunc (*GDExtensionInterfaceGetVaria /** * @name get_variant_to_type_constructor + * @since 4.1 * * Gets a pointer to a function that can get the raw value from a Variant of the given type. * @@ -1029,6 +1072,7 @@ typedef GDExtensionTypeFromVariantConstructorFunc (*GDExtensionInterfaceGetVaria /** * @name variant_get_ptr_operator_evaluator + * @since 4.1 * * Gets a pointer to a function that can evaluate the given Variant operator on the given Variant types. * @@ -1042,6 +1086,7 @@ typedef GDExtensionPtrOperatorEvaluator (*GDExtensionInterfaceVariantGetPtrOpera /** * @name variant_get_ptr_builtin_method + * @since 4.1 * * Gets a pointer to a function that can call a builtin method on a type of Variant. * @@ -1055,6 +1100,7 @@ typedef GDExtensionPtrBuiltInMethod (*GDExtensionInterfaceVariantGetPtrBuiltinMe /** * @name variant_get_ptr_constructor + * @since 4.1 * * Gets a pointer to a function that can call one of the constructors for a type of Variant. * @@ -1067,6 +1113,7 @@ typedef GDExtensionPtrConstructor (*GDExtensionInterfaceVariantGetPtrConstructor /** * @name variant_get_ptr_destructor + * @since 4.1 * * Gets a pointer to a function than can call the destructor for a type of Variant. * @@ -1078,6 +1125,7 @@ typedef GDExtensionPtrDestructor (*GDExtensionInterfaceVariantGetPtrDestructor)( /** * @name variant_construct + * @since 4.1 * * Constructs a Variant of the given type, using the first constructor that matches the given arguments. * @@ -1091,6 +1139,7 @@ typedef void (*GDExtensionInterfaceVariantConstruct)(GDExtensionVariantType p_ty /** * @name variant_get_ptr_setter + * @since 4.1 * * Gets a pointer to a function that can call a member's setter on the given Variant type. * @@ -1103,6 +1152,7 @@ typedef GDExtensionPtrSetter (*GDExtensionInterfaceVariantGetPtrSetter)(GDExtens /** * @name variant_get_ptr_getter + * @since 4.1 * * Gets a pointer to a function that can call a member's getter on the given Variant type. * @@ -1115,6 +1165,7 @@ typedef GDExtensionPtrGetter (*GDExtensionInterfaceVariantGetPtrGetter)(GDExtens /** * @name variant_get_ptr_indexed_setter + * @since 4.1 * * Gets a pointer to a function that can set an index on the given Variant type. * @@ -1126,6 +1177,7 @@ typedef GDExtensionPtrIndexedSetter (*GDExtensionInterfaceVariantGetPtrIndexedSe /** * @name variant_get_ptr_indexed_getter + * @since 4.1 * * Gets a pointer to a function that can get an index on the given Variant type. * @@ -1137,6 +1189,7 @@ typedef GDExtensionPtrIndexedGetter (*GDExtensionInterfaceVariantGetPtrIndexedGe /** * @name variant_get_ptr_keyed_setter + * @since 4.1 * * Gets a pointer to a function that can set a key on the given Variant type. * @@ -1148,6 +1201,7 @@ typedef GDExtensionPtrKeyedSetter (*GDExtensionInterfaceVariantGetPtrKeyedSetter /** * @name variant_get_ptr_keyed_getter + * @since 4.1 * * Gets a pointer to a function that can get a key on the given Variant type. * @@ -1159,6 +1213,7 @@ typedef GDExtensionPtrKeyedGetter (*GDExtensionInterfaceVariantGetPtrKeyedGetter /** * @name variant_get_ptr_keyed_checker + * @since 4.1 * * Gets a pointer to a function that can check a key on the given Variant type. * @@ -1170,6 +1225,7 @@ typedef GDExtensionPtrKeyedChecker (*GDExtensionInterfaceVariantGetPtrKeyedCheck /** * @name variant_get_constant_value + * @since 4.1 * * Gets the value of a constant from the given Variant type. * @@ -1181,6 +1237,7 @@ typedef void (*GDExtensionInterfaceVariantGetConstantValue)(GDExtensionVariantTy /** * @name variant_get_ptr_utility_function + * @since 4.1 * * Gets a pointer to a function that can call a Variant utility function. * @@ -1195,6 +1252,7 @@ typedef GDExtensionPtrUtilityFunction (*GDExtensionInterfaceVariantGetPtrUtility /** * @name string_new_with_latin1_chars + * @since 4.1 * * Creates a String from a Latin-1 encoded C string. * @@ -1205,6 +1263,7 @@ typedef void (*GDExtensionInterfaceStringNewWithLatin1Chars)(GDExtensionUninitia /** * @name string_new_with_utf8_chars + * @since 4.1 * * Creates a String from a UTF-8 encoded C string. * @@ -1215,6 +1274,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf8Chars)(GDExtensionUninitiali /** * @name string_new_with_utf16_chars + * @since 4.1 * * Creates a String from a UTF-16 encoded C string. * @@ -1225,6 +1285,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf16Chars)(GDExtensionUninitial /** * @name string_new_with_utf32_chars + * @since 4.1 * * Creates a String from a UTF-32 encoded C string. * @@ -1235,6 +1296,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf32Chars)(GDExtensionUninitial /** * @name string_new_with_wide_chars + * @since 4.1 * * Creates a String from a wide C string. * @@ -1245,6 +1307,7 @@ typedef void (*GDExtensionInterfaceStringNewWithWideChars)(GDExtensionUninitiali /** * @name string_new_with_latin1_chars_and_len + * @since 4.1 * * Creates a String from a Latin-1 encoded C string with the given length. * @@ -1256,6 +1319,7 @@ typedef void (*GDExtensionInterfaceStringNewWithLatin1CharsAndLen)(GDExtensionUn /** * @name string_new_with_utf8_chars_and_len + * @since 4.1 * * Creates a String from a UTF-8 encoded C string with the given length. * @@ -1267,6 +1331,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf8CharsAndLen)(GDExtensionUnin /** * @name string_new_with_utf16_chars_and_len + * @since 4.1 * * Creates a String from a UTF-16 encoded C string with the given length. * @@ -1278,6 +1343,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf16CharsAndLen)(GDExtensionUni /** * @name string_new_with_utf32_chars_and_len + * @since 4.1 * * Creates a String from a UTF-32 encoded C string with the given length. * @@ -1289,6 +1355,7 @@ typedef void (*GDExtensionInterfaceStringNewWithUtf32CharsAndLen)(GDExtensionUni /** * @name string_new_with_wide_chars_and_len + * @since 4.1 * * Creates a String from a wide C string with the given length. * @@ -1300,6 +1367,7 @@ typedef void (*GDExtensionInterfaceStringNewWithWideCharsAndLen)(GDExtensionUnin /** * @name string_to_latin1_chars + * @since 4.1 * * Converts a String to a Latin-1 encoded C string. * @@ -1315,6 +1383,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceStringToLatin1Chars)(GDExtensionCon /** * @name string_to_utf8_chars + * @since 4.1 * * Converts a String to a UTF-8 encoded C string. * @@ -1330,6 +1399,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceStringToUtf8Chars)(GDExtensionConst /** * @name string_to_utf16_chars + * @since 4.1 * * Converts a String to a UTF-16 encoded C string. * @@ -1345,6 +1415,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceStringToUtf16Chars)(GDExtensionCons /** * @name string_to_utf32_chars + * @since 4.1 * * Converts a String to a UTF-32 encoded C string. * @@ -1360,6 +1431,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceStringToUtf32Chars)(GDExtensionCons /** * @name string_to_wide_chars + * @since 4.1 * * Converts a String to a wide C string. * @@ -1375,6 +1447,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceStringToWideChars)(GDExtensionConst /** * @name string_operator_index + * @since 4.1 * * Gets a pointer to the character at the given index from a String. * @@ -1387,6 +1460,7 @@ typedef char32_t *(*GDExtensionInterfaceStringOperatorIndex)(GDExtensionStringPt /** * @name string_operator_index_const + * @since 4.1 * * Gets a const pointer to the character at the given index from a String. * @@ -1399,6 +1473,7 @@ typedef const char32_t *(*GDExtensionInterfaceStringOperatorIndexConst)(GDExtens /** * @name string_operator_plus_eq_string + * @since 4.1 * * Appends another String to a String. * @@ -1409,6 +1484,7 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqString)(GDExtensionString /** * @name string_operator_plus_eq_char + * @since 4.1 * * Appends a character to a String. * @@ -1419,6 +1495,7 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqChar)(GDExtensionStringPt /** * @name string_operator_plus_eq_cstr + * @since 4.1 * * Appends a Latin-1 encoded C string to a String. * @@ -1429,6 +1506,7 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqCstr)(GDExtensionStringPt /** * @name string_operator_plus_eq_wcstr + * @since 4.1 * * Appends a wide C string to a String. * @@ -1439,6 +1517,7 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqWcstr)(GDExtensionStringP /** * @name string_operator_plus_eq_c32str + * @since 4.1 * * Appends a UTF-32 encoded C string to a String. * @@ -1451,6 +1530,7 @@ typedef void (*GDExtensionInterfaceStringOperatorPlusEqC32str)(GDExtensionString /** * @name xml_parser_open_buffer + * @since 4.1 * * Opens a raw XML buffer on an XMLParser instance. * @@ -1468,6 +1548,7 @@ typedef GDExtensionInt (*GDExtensionInterfaceXmlParserOpenBuffer)(GDExtensionObj /** * @name file_access_store_buffer + * @since 4.1 * * Stores the given buffer using an instance of FileAccess. * @@ -1481,6 +1562,7 @@ typedef void (*GDExtensionInterfaceFileAccessStoreBuffer)(GDExtensionObjectPtr p /** * @name file_access_get_buffer + * @since 4.1 * * Reads the next p_length bytes into the given buffer using an instance of FileAccess. * @@ -1496,6 +1578,7 @@ typedef uint64_t (*GDExtensionInterfaceFileAccessGetBuffer)(GDExtensionConstObje /** * @name worker_thread_pool_add_native_group_task + * @since 4.1 * * Adds a group task to an instance of WorkerThreadPool. * @@ -1514,6 +1597,7 @@ typedef int64_t (*GDExtensionInterfaceWorkerThreadPoolAddNativeGroupTask)(GDExte /** * @name worker_thread_pool_add_native_task + * @since 4.1 * * Adds a task to an instance of WorkerThreadPool. * @@ -1531,6 +1615,7 @@ typedef int64_t (*GDExtensionInterfaceWorkerThreadPoolAddNativeTask)(GDExtension /** * @name packed_byte_array_operator_index + * @since 4.1 * * Gets a pointer to a byte in a PackedByteArray. * @@ -1543,6 +1628,7 @@ typedef uint8_t *(*GDExtensionInterfacePackedByteArrayOperatorIndex)(GDExtension /** * @name packed_byte_array_operator_index_const + * @since 4.1 * * Gets a const pointer to a byte in a PackedByteArray. * @@ -1555,6 +1641,7 @@ typedef const uint8_t *(*GDExtensionInterfacePackedByteArrayOperatorIndexConst)( /** * @name packed_color_array_operator_index + * @since 4.1 * * Gets a pointer to a color in a PackedColorArray. * @@ -1567,6 +1654,7 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndex)( /** * @name packed_color_array_operator_index_const + * @since 4.1 * * Gets a const pointer to a color in a PackedColorArray. * @@ -1579,6 +1667,7 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedColorArrayOperatorIndexCo /** * @name packed_float32_array_operator_index + * @since 4.1 * * Gets a pointer to a 32-bit float in a PackedFloat32Array. * @@ -1591,6 +1680,7 @@ typedef float *(*GDExtensionInterfacePackedFloat32ArrayOperatorIndex)(GDExtensio /** * @name packed_float32_array_operator_index_const + * @since 4.1 * * Gets a const pointer to a 32-bit float in a PackedFloat32Array. * @@ -1603,6 +1693,7 @@ typedef const float *(*GDExtensionInterfacePackedFloat32ArrayOperatorIndexConst) /** * @name packed_float64_array_operator_index + * @since 4.1 * * Gets a pointer to a 64-bit float in a PackedFloat64Array. * @@ -1615,6 +1706,7 @@ typedef double *(*GDExtensionInterfacePackedFloat64ArrayOperatorIndex)(GDExtensi /** * @name packed_float64_array_operator_index_const + * @since 4.1 * * Gets a const pointer to a 64-bit float in a PackedFloat64Array. * @@ -1627,6 +1719,7 @@ typedef const double *(*GDExtensionInterfacePackedFloat64ArrayOperatorIndexConst /** * @name packed_int32_array_operator_index + * @since 4.1 * * Gets a pointer to a 32-bit integer in a PackedInt32Array. * @@ -1639,6 +1732,7 @@ typedef int32_t *(*GDExtensionInterfacePackedInt32ArrayOperatorIndex)(GDExtensio /** * @name packed_int32_array_operator_index_const + * @since 4.1 * * Gets a const pointer to a 32-bit integer in a PackedInt32Array. * @@ -1651,6 +1745,7 @@ typedef const int32_t *(*GDExtensionInterfacePackedInt32ArrayOperatorIndexConst) /** * @name packed_int64_array_operator_index + * @since 4.1 * * Gets a pointer to a 64-bit integer in a PackedInt64Array. * @@ -1663,6 +1758,7 @@ typedef int64_t *(*GDExtensionInterfacePackedInt64ArrayOperatorIndex)(GDExtensio /** * @name packed_int64_array_operator_index_const + * @since 4.1 * * Gets a const pointer to a 64-bit integer in a PackedInt64Array. * @@ -1675,6 +1771,7 @@ typedef const int64_t *(*GDExtensionInterfacePackedInt64ArrayOperatorIndexConst) /** * @name packed_string_array_operator_index + * @since 4.1 * * Gets a pointer to a string in a PackedStringArray. * @@ -1687,6 +1784,7 @@ typedef GDExtensionStringPtr (*GDExtensionInterfacePackedStringArrayOperatorInde /** * @name packed_string_array_operator_index_const + * @since 4.1 * * Gets a const pointer to a string in a PackedStringArray. * @@ -1699,6 +1797,7 @@ typedef GDExtensionStringPtr (*GDExtensionInterfacePackedStringArrayOperatorInde /** * @name packed_vector2_array_operator_index + * @since 4.1 * * Gets a pointer to a Vector2 in a PackedVector2Array. * @@ -1711,6 +1810,7 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector2ArrayOperatorIndex /** * @name packed_vector2_array_operator_index_const + * @since 4.1 * * Gets a const pointer to a Vector2 in a PackedVector2Array. * @@ -1723,6 +1823,7 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector2ArrayOperatorIndex /** * @name packed_vector3_array_operator_index + * @since 4.1 * * Gets a pointer to a Vector3 in a PackedVector3Array. * @@ -1735,6 +1836,7 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector3ArrayOperatorIndex /** * @name packed_vector3_array_operator_index_const + * @since 4.1 * * Gets a const pointer to a Vector3 in a PackedVector3Array. * @@ -1747,6 +1849,7 @@ typedef GDExtensionTypePtr (*GDExtensionInterfacePackedVector3ArrayOperatorIndex /** * @name array_operator_index + * @since 4.1 * * Gets a pointer to a Variant in an Array. * @@ -1759,6 +1862,7 @@ typedef GDExtensionVariantPtr (*GDExtensionInterfaceArrayOperatorIndex)(GDExtens /** * @name array_operator_index_const + * @since 4.1 * * Gets a const pointer to a Variant in an Array. * @@ -1771,6 +1875,7 @@ typedef GDExtensionVariantPtr (*GDExtensionInterfaceArrayOperatorIndexConst)(GDE /** * @name array_ref + * @since 4.1 * * Sets an Array to be a reference to another Array object. * @@ -1781,6 +1886,7 @@ typedef void (*GDExtensionInterfaceArrayRef)(GDExtensionTypePtr p_self, GDExtens /** * @name array_set_typed + * @since 4.1 * * Makes an Array into a typed Array. * @@ -1795,6 +1901,7 @@ typedef void (*GDExtensionInterfaceArraySetTyped)(GDExtensionTypePtr p_self, GDE /** * @name dictionary_operator_index + * @since 4.1 * * Gets a pointer to a Variant in a Dictionary with the given key. * @@ -1807,6 +1914,7 @@ typedef GDExtensionVariantPtr (*GDExtensionInterfaceDictionaryOperatorIndex)(GDE /** * @name dictionary_operator_index_const + * @since 4.1 * * Gets a const pointer to a Variant in a Dictionary with the given key. * @@ -1821,6 +1929,7 @@ typedef GDExtensionVariantPtr (*GDExtensionInterfaceDictionaryOperatorIndexConst /** * @name object_method_bind_call + * @since 4.1 * * Calls a method on an Object. * @@ -1835,6 +1944,7 @@ typedef void (*GDExtensionInterfaceObjectMethodBindCall)(GDExtensionMethodBindPt /** * @name object_method_bind_ptrcall + * @since 4.1 * * Calls a method on an Object (using a "ptrcall"). * @@ -1847,6 +1957,7 @@ typedef void (*GDExtensionInterfaceObjectMethodBindPtrcall)(GDExtensionMethodBin /** * @name object_destroy + * @since 4.1 * * Destroys an Object. * @@ -1856,6 +1967,7 @@ typedef void (*GDExtensionInterfaceObjectDestroy)(GDExtensionObjectPtr p_o); /** * @name global_get_singleton + * @since 4.1 * * Gets a global singleton by name. * @@ -1867,6 +1979,7 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceGlobalGetSingleton)(GDExtensi /** * @name object_get_instance_binding + * @since 4.1 * * Gets a pointer representing an Object's instance binding. * @@ -1880,6 +1993,7 @@ typedef void *(*GDExtensionInterfaceObjectGetInstanceBinding)(GDExtensionObjectP /** * @name object_set_instance_binding + * @since 4.1 * * Sets an Object's instance binding. * @@ -1892,6 +2006,7 @@ typedef void (*GDExtensionInterfaceObjectSetInstanceBinding)(GDExtensionObjectPt /** * @name object_set_instance + * @since 4.1 * * Sets an extension class instance on a Object. * @@ -1903,6 +2018,7 @@ typedef void (*GDExtensionInterfaceObjectSetInstance)(GDExtensionObjectPtr p_o, /** * @name object_get_class_name + * @since 4.1 * * Gets the class name of an Object. * @@ -1916,6 +2032,7 @@ typedef GDExtensionBool (*GDExtensionInterfaceObjectGetClassName)(GDExtensionCon /** * @name object_cast_to + * @since 4.1 * * Casts an Object to a different type. * @@ -1928,6 +2045,7 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceObjectCastTo)(GDExtensionCons /** * @name object_get_instance_from_id + * @since 4.1 * * Gets an Object by its instance ID. * @@ -1939,6 +2057,7 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceObjectGetInstanceFromId)(GDOb /** * @name object_get_instance_id + * @since 4.1 * * Gets the instance ID from an Object. * @@ -1952,6 +2071,7 @@ typedef GDObjectInstanceID (*GDExtensionInterfaceObjectGetInstanceId)(GDExtensio /** * @name ref_get_object + * @since 4.1 * * Gets the Object from a reference. * @@ -1963,6 +2083,7 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceRefGetObject)(GDExtensionCons /** * @name ref_set_object + * @since 4.1 * * Sets the Object referred to by a reference. * @@ -1975,6 +2096,7 @@ typedef void (*GDExtensionInterfaceRefSetObject)(GDExtensionRefPtr p_ref, GDExte /** * @name script_instance_create + * @since 4.1 * * Creates a script instance that contains the given info and instance data. * @@ -1989,6 +2111,7 @@ typedef GDExtensionScriptInstancePtr (*GDExtensionInterfaceScriptInstanceCreate) /** * @name classdb_construct_object + * @since 4.1 * * Constructs an Object of the requested class. * @@ -2002,6 +2125,7 @@ typedef GDExtensionObjectPtr (*GDExtensionInterfaceClassdbConstructObject)(GDExt /** * @name classdb_get_method_bind + * @since 4.1 * * Gets a pointer to the MethodBind in ClassDB for the given class, method and hash. * @@ -2015,6 +2139,7 @@ typedef GDExtensionMethodBindPtr (*GDExtensionInterfaceClassdbGetMethodBind)(GDE /** * @name classdb_get_class_tag + * @since 4.1 * * Gets a pointer uniquely identifying the given built-in class in the ClassDB. * @@ -2028,6 +2153,7 @@ typedef void *(*GDExtensionInterfaceClassdbGetClassTag)(GDExtensionConstStringNa /** * @name classdb_register_extension_class + * @since 4.1 * * Registers an extension class in the ClassDB. * @@ -2042,6 +2168,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClass)(GDExtensionCla /** * @name classdb_register_extension_class_method + * @since 4.1 * * Registers a method on an extension class in the ClassDB. * @@ -2055,6 +2182,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassMethod)(GDExtens /** * @name classdb_register_extension_class_integer_constant + * @since 4.1 * * Registers an integer constant on an extension class in the ClassDB. * @@ -2069,6 +2197,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassIntegerConstant) /** * @name classdb_register_extension_class_property + * @since 4.1 * * Registers a property on an extension class in the ClassDB. * @@ -2084,6 +2213,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassProperty)(GDExte /** * @name classdb_register_extension_class_property_group + * @since 4.1 * * Registers a property group on an extension class in the ClassDB. * @@ -2096,6 +2226,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassPropertyGroup)(G /** * @name classdb_register_extension_class_property_subgroup + * @since 4.1 * * Registers a property subgroup on an extension class in the ClassDB. * @@ -2108,6 +2239,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassPropertySubgroup /** * @name classdb_register_extension_class_signal + * @since 4.1 * * Registers a signal on an extension class in the ClassDB. * @@ -2123,6 +2255,7 @@ typedef void (*GDExtensionInterfaceClassdbRegisterExtensionClassSignal)(GDExtens /** * @name classdb_unregister_extension_class + * @since 4.1 * * Unregisters an extension class in the ClassDB. * @@ -2133,6 +2266,7 @@ typedef void (*GDExtensionInterfaceClassdbUnregisterExtensionClass)(GDExtensionC /** * @name get_library_path + * @since 4.1 * * Gets the path to the current GDExtension library. * @@ -2143,6 +2277,7 @@ typedef void (*GDExtensionInterfaceGetLibraryPath)(GDExtensionClassLibraryPtr p_ /** * @name editor_add_plugin + * @since 4.1 * * Adds an editor plugin. * @@ -2154,6 +2289,7 @@ typedef void (*GDExtensionInterfaceEditorAddPlugin)(GDExtensionConstStringNamePt /** * @name editor_remove_plugin + * @since 4.1 * * Removes an editor plugin. * diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index e547b04d0b..e37886cbe9 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -1192,7 +1192,7 @@ static const char *_joy_button_descriptions[(size_t)JoyButton::SDL_MAX] = { TTRC("Top Action, Sony Triangle, Xbox Y, Nintendo X"), TTRC("Back, Sony Select, Xbox Back, Nintendo -"), TTRC("Guide, Sony PS, Xbox Home"), - TTRC("Start, Nintendo +"), + TTRC("Start, Xbox Menu, Nintendo +"), TTRC("Left Stick, Sony L3, Xbox L/LS"), TTRC("Right Stick, Sony R3, Xbox R/RS"), TTRC("Left Shoulder, Sony L1, Xbox LB"), diff --git a/core/io/compression.cpp b/core/io/compression.cpp index ac4a637597..e36fb0afa4 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -35,13 +35,13 @@ #include "thirdparty/misc/fastlz.h" -#ifdef BROTLI_ENABLED -#include "thirdparty/brotli/include/brotli/decode.h" -#endif - #include <zlib.h> #include <zstd.h> +#ifdef BROTLI_ENABLED +#include <brotli/decode.h> +#endif + int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode) { switch (p_mode) { case MODE_BROTLI: { diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index 064353476f..c7f1a73f97 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -47,7 +47,7 @@ static void *godot_open(voidpf opaque, const char *p_fname, int mode) { return nullptr; } - Ref<FileAccess> f = FileAccess::open(p_fname, FileAccess::READ); + Ref<FileAccess> f = FileAccess::open(String::utf8(p_fname), FileAccess::READ); ERR_FAIL_COND_V(f.is_null(), nullptr); ZipData *zd = memnew(ZipData); diff --git a/core/io/image.cpp b/core/io/image.cpp index 9bb987b670..1711e4c265 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -3004,6 +3004,7 @@ ImageMemLoadFunc Image::_jpg_mem_loader_func = nullptr; ImageMemLoadFunc Image::_webp_mem_loader_func = nullptr; ImageMemLoadFunc Image::_tga_mem_loader_func = nullptr; ImageMemLoadFunc Image::_bmp_mem_loader_func = nullptr; +ScalableImageMemLoadFunc Image::_svg_scalable_mem_loader_func = nullptr; void (*Image::_image_compress_bc_func)(Image *, Image::UsedChannels) = nullptr; void (*Image::_image_compress_bptc_func)(Image *, Image::UsedChannels) = nullptr; @@ -3476,6 +3477,9 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("load_tga_from_buffer", "buffer"), &Image::load_tga_from_buffer); ClassDB::bind_method(D_METHOD("load_bmp_from_buffer", "buffer"), &Image::load_bmp_from_buffer); + ClassDB::bind_method(D_METHOD("load_svg_from_buffer", "buffer", "scale"), &Image::load_svg_from_buffer, DEFVAL(1.0)); + ClassDB::bind_method(D_METHOD("load_svg_from_string", "svg_str", "scale"), &Image::load_svg_from_string, DEFVAL(1.0)); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_data", "_get_data"); BIND_CONSTANT(MAX_WIDTH); @@ -3825,6 +3829,28 @@ Error Image::load_bmp_from_buffer(const Vector<uint8_t> &p_array) { return _load_from_buffer(p_array, _bmp_mem_loader_func); } +Error Image::load_svg_from_buffer(const Vector<uint8_t> &p_array, float scale) { + ERR_FAIL_NULL_V_MSG( + _svg_scalable_mem_loader_func, + ERR_UNAVAILABLE, + "The SVG module isn't enabled. Recompile the Godot editor or export template binary with the `module_svg_enabled=yes` SCons option."); + + int buffer_size = p_array.size(); + + ERR_FAIL_COND_V(buffer_size == 0, ERR_INVALID_PARAMETER); + + Ref<Image> image = _svg_scalable_mem_loader_func(p_array.ptr(), buffer_size, scale); + ERR_FAIL_COND_V(!image.is_valid(), ERR_PARSE_ERROR); + + copy_internals_from(image); + + return OK; +} + +Error Image::load_svg_from_string(const String &p_svg_str, float scale) { + return load_svg_from_buffer(p_svg_str.to_utf8_buffer(), scale); +} + void Image::convert_rg_to_ra_rgba8() { ERR_FAIL_COND(format != FORMAT_RGBA8); ERR_FAIL_COND(!data.size()); diff --git a/core/io/image.h b/core/io/image.h index 8e353a8bb7..f877b00ee6 100644 --- a/core/io/image.h +++ b/core/io/image.h @@ -48,6 +48,7 @@ typedef Vector<uint8_t> (*SavePNGBufferFunc)(const Ref<Image> &p_img); typedef Error (*SaveJPGFunc)(const String &p_path, const Ref<Image> &p_img, float p_quality); typedef Vector<uint8_t> (*SaveJPGBufferFunc)(const Ref<Image> &p_img, float p_quality); typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size); +typedef Ref<Image> (*ScalableImageMemLoadFunc)(const uint8_t *p_data, int p_size, float p_scale); typedef Error (*SaveWebPFunc)(const String &p_path, const Ref<Image> &p_img, const bool p_lossy, const float p_quality); typedef Vector<uint8_t> (*SaveWebPBufferFunc)(const Ref<Image> &p_img, const bool p_lossy, const float p_quality); @@ -148,6 +149,7 @@ public: static ImageMemLoadFunc _webp_mem_loader_func; static ImageMemLoadFunc _tga_mem_loader_func; static ImageMemLoadFunc _bmp_mem_loader_func; + static ScalableImageMemLoadFunc _svg_scalable_mem_loader_func; static void (*_image_compress_bc_func)(Image *, UsedChannels p_channels); static void (*_image_compress_bptc_func)(Image *, UsedChannels p_channels); @@ -401,6 +403,9 @@ public: Error load_tga_from_buffer(const Vector<uint8_t> &p_array); Error load_bmp_from_buffer(const Vector<uint8_t> &p_array); + Error load_svg_from_buffer(const Vector<uint8_t> &p_array, float scale = 1.0); + Error load_svg_from_string(const String &p_svg_str, float scale = 1.0); + void convert_rg_to_ra_rgba8(); void convert_ra_rgba8_to_rg(); void convert_rgba8_to_bgra8(); diff --git a/core/io/json.cpp b/core/io/json.cpp index a6e054a9fe..496400a5ea 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -299,9 +299,15 @@ Error JSON::_get_token(const char32_t *p_str, int &index, int p_len, Token &r_to } } break; - default: { + case '"': + case '\\': + case '/': { res = next; } break; + default: { + r_err_str = "Invalid escape sequence."; + return ERR_PARSE_ERROR; + } } str += res; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 525c41cf87..1fe662b1fa 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -239,15 +239,15 @@ ResourceLoader::LoadToken::~LoadToken() { Ref<Resource> ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error, bool p_use_sub_threads, float *r_progress) { load_nesting++; - if (load_paths_stack.size()) { + if (load_paths_stack->size()) { thread_load_mutex.lock(); - HashMap<String, ThreadLoadTask>::Iterator E = thread_load_tasks.find(load_paths_stack[load_paths_stack.size() - 1]); + HashMap<String, ThreadLoadTask>::Iterator E = thread_load_tasks.find(load_paths_stack->get(load_paths_stack->size() - 1)); if (E) { E->value.sub_tasks.insert(p_path); } thread_load_mutex.unlock(); } - load_paths_stack.push_back(p_path); + load_paths_stack->push_back(p_path); // Try all loaders and pick the first match for the type hint bool found = false; @@ -263,7 +263,7 @@ Ref<Resource> ResourceLoader::_load(const String &p_path, const String &p_origin } } - load_paths_stack.resize(load_paths_stack.size() - 1); + load_paths_stack->resize(load_paths_stack->size() - 1); load_nesting--; if (!res.is_null()) { @@ -296,8 +296,10 @@ void ResourceLoader::_thread_load_function(void *p_userdata) { // Thread-safe either if it's the current thread or a brand new one. CallQueue *mq_override = nullptr; if (load_nesting == 0) { + load_paths_stack = memnew(Vector<String>); + if (!load_task.dependent_path.is_empty()) { - load_paths_stack.push_back(load_task.dependent_path); + load_paths_stack->push_back(load_task.dependent_path); } if (!Thread::is_main_thread()) { mq_override = memnew(CallQueue); @@ -309,6 +311,10 @@ void ResourceLoader::_thread_load_function(void *p_userdata) { } // -- + if (!Thread::is_main_thread()) { + set_current_thread_safe_for_nodes(true); + } + Ref<Resource> res = _load(load_task.remapped_path, load_task.remapped_path != load_task.local_path ? load_task.local_path : String(), load_task.type_hint, load_task.cache_mode, &load_task.error, load_task.use_sub_threads, &load_task.progress); if (mq_override) { mq_override->flush(); @@ -356,8 +362,11 @@ void ResourceLoader::_thread_load_function(void *p_userdata) { thread_load_mutex.unlock(); - if (load_nesting == 0 && mq_override) { - memdelete(mq_override); + if (load_nesting == 0) { + if (mq_override) { + memdelete(mq_override); + } + memdelete(load_paths_stack); } } @@ -1166,7 +1175,7 @@ bool ResourceLoader::timestamp_on_load = false; thread_local int ResourceLoader::load_nesting = 0; thread_local WorkerThreadPool::TaskID ResourceLoader::caller_task_id = 0; -thread_local Vector<String> ResourceLoader::load_paths_stack; +thread_local Vector<String> *ResourceLoader::load_paths_stack; template <> thread_local uint32_t SafeBinaryMutex<ResourceLoader::BINARY_MUTEX_TAG>::count = 0; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 592befb603..2701caa3f4 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -182,7 +182,7 @@ private: static thread_local int load_nesting; static thread_local WorkerThreadPool::TaskID caller_task_id; - static thread_local Vector<String> load_paths_stack; + static thread_local Vector<String> *load_paths_stack; // A pointer to avoid broken TLS implementations from double-running the destructor. static SafeBinaryMutex<BINARY_MUTEX_TAG> thread_load_mutex; static HashMap<String, ThreadLoadTask> thread_load_tasks; static bool cleaning_tasks; diff --git a/core/object/object.cpp b/core/object/object.cpp index c76188a2cd..4d19a2c75b 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -836,14 +836,16 @@ void Object::set_script(const Variant &p_script) { return; } + Ref<Script> s = p_script; + ERR_FAIL_COND_MSG(s.is_null() && !p_script.is_null(), "Invalid parameter, it should be a reference to a valid script (or null)."); + + script = p_script; + if (script_instance) { memdelete(script_instance); script_instance = nullptr; } - script = p_script; - Ref<Script> s = script; - if (!s.is_null()) { if (s->can_instantiate()) { OBJ_DEBUG_LOCK diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 6f047d80aa..a8b0e426ae 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -42,7 +42,7 @@ int ScriptServer::_language_count = 0; bool ScriptServer::scripting_enabled = true; bool ScriptServer::reload_scripts_on_save = false; -bool ScriptServer::languages_finished = false; +SafeFlag ScriptServer::languages_finished; // Used until GH-76581 is fixed properly. ScriptEditRequestFunction ScriptServer::edit_request_func = nullptr; void Script::_notification(int p_what) { @@ -228,7 +228,7 @@ void ScriptServer::finish_languages() { _languages[i]->finish(); } global_classes_clear(); - languages_finished = true; + languages_finished.set(); } void ScriptServer::set_reload_scripts_on_save(bool p_enable) { @@ -240,12 +240,18 @@ bool ScriptServer::is_reload_scripts_on_save_enabled() { } void ScriptServer::thread_enter() { + if (!languages_finished.is_set()) { + return; + } for (int i = 0; i < _language_count; i++) { _languages[i]->thread_enter(); } } void ScriptServer::thread_exit() { + if (!languages_finished.is_set()) { + return; + } for (int i = 0; i < _language_count; i++) { _languages[i]->thread_exit(); } diff --git a/core/object/script_language.h b/core/object/script_language.h index c22890e30a..2b685c77a3 100644 --- a/core/object/script_language.h +++ b/core/object/script_language.h @@ -35,6 +35,7 @@ #include "core/io/resource.h" #include "core/templates/pair.h" #include "core/templates/rb_map.h" +#include "core/templates/safe_refcount.h" #include "core/variant/typed_array.h" class ScriptLanguage; @@ -52,7 +53,7 @@ class ScriptServer { static int _language_count; static bool scripting_enabled; static bool reload_scripts_on_save; - static bool languages_finished; + static SafeFlag languages_finished; // Used until GH-76581 is fixed properly. struct GlobalScriptClass { StringName language; @@ -97,7 +98,7 @@ public: static void init_languages(); static void finish_languages(); - static bool are_languages_finished() { return languages_finished; } + static bool are_languages_finished() { return languages_finished.is_set(); } }; class ScriptInstance; diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index 79cf712119..1a0ec29479 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -651,7 +651,7 @@ public: #ifdef TOOLS_ENABLED Ref<Script> script = get_script(); - if (script->is_valid() && pcount > 0) { + if (script.is_valid() && pcount > 0) { p_list->push_back(script->get_class_category()); } #endif // TOOLS_ENABLED diff --git a/core/object/undo_redo.h b/core/object/undo_redo.h index 2ee17867f2..389d8714f7 100644 --- a/core/object/undo_redo.h +++ b/core/object/undo_redo.h @@ -58,7 +58,7 @@ private: TYPE_REFERENCE } type; - bool force_keep_in_merge_ends; + bool force_keep_in_merge_ends = false; Ref<RefCounted> ref; ObjectID object; StringName name; diff --git a/core/object/worker_thread_pool.cpp b/core/object/worker_thread_pool.cpp index d285be3e70..5ec3e1a1a8 100644 --- a/core/object/worker_thread_pool.cpp +++ b/core/object/worker_thread_pool.cpp @@ -56,6 +56,8 @@ void WorkerThreadPool::_process_task(Task *p_task) { Task *prev_low_prio_task = nullptr; // In case this is recursively called. if (!use_native_low_priority_threads) { + // Tasks must start with this unset. They are free to set-and-forget otherwise. + set_current_thread_safe_for_nodes(false); pool_thread_index = thread_ids[Thread::get_caller_id()]; ThreadData &curr_thread = threads[pool_thread_index]; task_mutex.lock(); @@ -179,9 +181,6 @@ void WorkerThreadPool::_process_task(Task *p_task) { if (post) { task_available_semaphore.post(); } - - // Engine/user tasks can set-and-forget, so we must be sure it's back to normal by the end of the task. - set_current_thread_safe_for_nodes(false); } } @@ -371,7 +370,9 @@ Error WorkerThreadPool::wait_for_task_completion(TaskID p_task_id) { must_exit = true; } else { // Solve tasks while they are around. + bool safe_for_nodes_backup = is_current_thread_safe_for_nodes(); _process_task_queue(); + set_current_thread_safe_for_nodes(safe_for_nodes_backup); continue; } } else if (!use_native_low_priority_threads && task->low_priority) { @@ -415,7 +416,7 @@ Error WorkerThreadPool::wait_for_task_completion(TaskID p_task_id) { WorkerThreadPool::GroupID WorkerThreadPool::_add_group_task(const Callable &p_callable, void (*p_func)(void *, uint32_t), void *p_userdata, BaseTemplateUserdata *p_template_userdata, int p_elements, int p_tasks, bool p_high_priority, const String &p_description) { ERR_FAIL_COND_V(p_elements < 0, INVALID_TASK_ID); if (p_tasks < 0) { - p_tasks = threads.size(); + p_tasks = MAX(1u, threads.size()); } task_mutex.lock(); diff --git a/core/os/os.cpp b/core/os/os.cpp index 5704ef7a40..67423128a3 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -295,12 +295,14 @@ Error OS::shell_open(String p_uri) { } Error OS::shell_show_in_file_manager(String p_path, bool p_open_folder) { - if (!p_path.begins_with("file://")) { - p_path = String("file://") + p_path; - } - if (!p_path.ends_with("/")) { + p_path = p_path.trim_prefix("file://"); + + if (!DirAccess::dir_exists_absolute(p_path)) { p_path = p_path.get_base_dir(); } + + p_path = String("file://") + p_path; + return shell_open(p_path); } // implement these with the canvas? diff --git a/core/os/threaded_array_processor.h b/core/os/threaded_array_processor.h deleted file mode 100644 index 34b417ae57..0000000000 --- a/core/os/threaded_array_processor.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************/ -/* threaded_array_processor.h */ -/**************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/**************************************************************************/ -/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/**************************************************************************/ - -#ifndef THREADED_ARRAY_PROCESSOR_H -#define THREADED_ARRAY_PROCESSOR_H - -#include "core/os/os.h" -#include "core/os/thread.h" -#include "core/os/thread_safe.h" -#include "core/templates/safe_refcount.h" - -template <class C, class U> -struct ThreadArrayProcessData { - uint32_t elements; - SafeNumeric<uint32_t> index; - C *instance; - U userdata; - void (C::*method)(uint32_t, U); - - void process(uint32_t p_index) { - (instance->*method)(p_index, userdata); - } -}; - -template <class T> -void process_array_thread(void *ud) { - T &data = *(T *)ud; - while (true) { - uint32_t index = data.index.increment(); - if (index >= data.elements) { - break; - } - data.process(index); - } -} - -template <class C, class M, class U> -void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) { - ThreadArrayProcessData<C, U> data; - data.method = p_method; - data.instance = p_instance; - data.userdata = p_userdata; - data.index.set(0); - data.elements = p_elements; - data.process(0); //process first, let threads increment for next - - int thread_count = OS::get_singleton()->get_processor_count(); - Thread *threads = memnew_arr(Thread, thread_count); - - for (int i = 0; i < thread_count; i++) { - threads[i].start(process_array_thread<ThreadArrayProcessData<C, U>>, &data); - } - - for (int i = 0; i < thread_count; i++) { - threads[i].wait_to_finish(); - } - memdelete_arr(threads); -} - -#endif // THREADED_ARRAY_PROCESSOR_H diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index c276f20f99..12e6423724 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -62,6 +62,7 @@ static _FORCE_INLINE_ char32_t lower_case(char32_t c) { const char CharString::_null = 0; const char16_t Char16String::_null = 0; const char32_t String::_null = 0; +const char32_t String::_replacement_char = 0xfffd; bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end) { const String &s = p_s; @@ -307,7 +308,7 @@ void String::copy_from(const char *p_cstr) { uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]); if (c == 0 && i < len) { print_unicode_error("NUL character", true); - dst[i] = 0x20; + dst[i] = _replacement_char; } else { dst[i] = c; } @@ -340,7 +341,7 @@ void String::copy_from(const char *p_cstr, const int p_clip_to) { uint8_t c = p_cstr[i] >= 0 ? p_cstr[i] : uint8_t(256 + p_cstr[i]); if (c == 0) { print_unicode_error("NUL character", true); - dst[i] = 0x20; + dst[i] = _replacement_char; } else { dst[i] = c; } @@ -373,17 +374,21 @@ void String::copy_from(const char32_t &p_char) { print_unicode_error("NUL character", true); return; } + + resize(2); + + char32_t *dst = ptrw(); + if ((p_char & 0xfffff800) == 0xd800) { print_unicode_error(vformat("Unpaired surrogate (%x)", (uint32_t)p_char)); - } - if (p_char > 0x10ffff) { + dst[0] = _replacement_char; + } else if (p_char > 0x10ffff) { print_unicode_error(vformat("Invalid unicode codepoint (%x)", (uint32_t)p_char)); + dst[0] = _replacement_char; + } else { + dst[0] = p_char; } - resize(2); - - char32_t *dst = ptrw(); - dst[0] = p_char; dst[1] = 0; } @@ -439,14 +444,18 @@ void String::copy_from_unchecked(const char32_t *p_char, const int p_length) { for (int i = 0; i < p_length; i++) { if (p_char[i] == 0) { print_unicode_error("NUL character", true); - dst[i] = 0x20; + dst[i] = _replacement_char; continue; } if ((p_char[i] & 0xfffff800) == 0xd800) { print_unicode_error(vformat("Unpaired surrogate (%x)", (uint32_t)p_char[i])); + dst[i] = _replacement_char; + continue; } if (p_char[i] > 0x10ffff) { print_unicode_error(vformat("Invalid unicode codepoint (%x)", (uint32_t)p_char[i])); + dst[i] = _replacement_char; + continue; } dst[i] = p_char[i]; } @@ -538,7 +547,7 @@ String &String::operator+=(const char *p_str) { uint8_t c = p_str[i] >= 0 ? p_str[i] : uint8_t(256 + p_str[i]); if (c == 0 && i < rhs_len) { print_unicode_error("NUL character", true); - dst[i] = 0x20; + dst[i] = _replacement_char; } else { dst[i] = c; } @@ -568,17 +577,21 @@ String &String::operator+=(char32_t p_char) { print_unicode_error("NUL character", true); return *this; } + + const int lhs_len = length(); + resize(lhs_len + 2); + char32_t *dst = ptrw(); + if ((p_char & 0xfffff800) == 0xd800) { print_unicode_error(vformat("Unpaired surrogate (%x)", (uint32_t)p_char)); - } - if (p_char > 0x10ffff) { + dst[lhs_len] = _replacement_char; + } else if (p_char > 0x10ffff) { print_unicode_error(vformat("Invalid unicode codepoint (%x)", (uint32_t)p_char)); + dst[lhs_len] = _replacement_char; + } else { + dst[lhs_len] = p_char; } - const int lhs_len = length(); - resize(lhs_len + 2); - char32_t *dst = ptrw(); - dst[lhs_len] = p_char; dst[lhs_len + 1] = 0; return *this; @@ -1737,7 +1750,7 @@ Vector<uint8_t> String::hex_decode() const { void String::print_unicode_error(const String &p_message, bool p_critical) const { if (p_critical) { - print_error(vformat("Unicode parsing error, some characters were replaced with spaces: %s", p_message)); + print_error(vformat("Unicode parsing error, some characters were replaced with � (U+FFFD): %s", p_message)); } else { print_error(vformat("Unicode parsing error: %s", p_message)); } @@ -1757,7 +1770,7 @@ CharString String::ascii(bool p_allow_extended) const { cs[i] = c; } else { print_unicode_error(vformat("Invalid unicode codepoint (%x), cannot represent as ASCII/Latin-1", (uint32_t)c)); - cs[i] = 0x20; + cs[i] = 0x20; // ascii doesn't have a replacement character like unicode, 0x1a is sometimes used but is kinda arcane } } @@ -1897,13 +1910,13 @@ Error String::parse_utf8(const char *p_utf8, int p_len, bool p_skip_cr) { unichar = (0xff >> 7) & c; skip = 5; } else { - *(dst++) = 0x20; + *(dst++) = _replacement_char; unichar = 0; skip = 0; } } else { if (c < 0x80 || c > 0xbf) { - *(dst++) = 0x20; + *(dst++) = _replacement_char; skip = 0; } else { unichar = (unichar << 6) | (c & 0x3f); @@ -1912,15 +1925,15 @@ Error String::parse_utf8(const char *p_utf8, int p_len, bool p_skip_cr) { if (unichar == 0) { print_unicode_error("NUL character", true); decode_failed = true; - unichar = 0x20; - } - if ((unichar & 0xfffff800) == 0xd800) { - print_unicode_error(vformat("Unpaired surrogate (%x)", unichar)); - decode_error = true; - } - if (unichar > 0x10ffff) { - print_unicode_error(vformat("Invalid unicode codepoint (%x)", unichar)); - decode_error = true; + unichar = _replacement_char; + } else if ((unichar & 0xfffff800) == 0xd800) { + print_unicode_error(vformat("Unpaired surrogate (%x)", unichar), true); + decode_failed = true; + unichar = _replacement_char; + } else if (unichar > 0x10ffff) { + print_unicode_error(vformat("Invalid unicode codepoint (%x)", unichar), true); + decode_failed = true; + unichar = _replacement_char; } *(dst++) = unichar; } @@ -2014,7 +2027,11 @@ CharString String::utf8() const { APPEND_CHAR(uint32_t(0x80 | ((c >> 6) & 0x3f))); // Lower lower middle 6 bits. APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits. } else { - APPEND_CHAR(0x20); + // the string is a valid UTF32, so it should never happen ... + print_unicode_error(vformat("Non scalar value (%x)", c), true); + APPEND_CHAR(uint32_t(0xe0 | ((_replacement_char >> 12) & 0x0f))); // Top 4 bits. + APPEND_CHAR(uint32_t(0x80 | ((_replacement_char >> 6) & 0x3f))); // Middle 6 bits. + APPEND_CHAR(uint32_t(0x80 | (_replacement_char & 0x3f))); // Bottom 6 bits. } } #undef APPEND_CHAR @@ -2187,7 +2204,9 @@ Char16String String::utf16() const { APPEND_CHAR(uint32_t((c >> 10) + 0xd7c0)); // lead surrogate. APPEND_CHAR(uint32_t((c & 0x3ff) | 0xdc00)); // trail surrogate. } else { - APPEND_CHAR(0x20); + // the string is a valid UTF32, so it should never happen ... + APPEND_CHAR(uint32_t((_replacement_char >> 10) + 0xd7c0)); + APPEND_CHAR(uint32_t((_replacement_char & 0x3ff) | 0xdc00)); } } #undef APPEND_CHAR @@ -4262,12 +4281,13 @@ String String::pad_zeros(int p_digits) const { begin++; } - if (begin >= end) { + int zeros_to_add = p_digits - (end - begin); + + if (zeros_to_add <= 0) { return s; + } else { + return s.insert(begin, String("0").repeat(zeros_to_add)); } - - int zeros_to_add = p_digits - (end - begin); - return s.insert(begin, String("0").repeat(zeros_to_add)); } String String::trim_prefix(const String &p_prefix) const { diff --git a/core/string/ustring.h b/core/string/ustring.h index 782ca47507..295625395d 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -183,6 +183,7 @@ struct StrRange { class String { CowData<char32_t> _cowdata; static const char32_t _null; + static const char32_t _replacement_char; void copy_from(const char *p_cstr); void copy_from(const char *p_cstr, const int p_clip_to); diff --git a/core/variant/callable_bind.cpp b/core/variant/callable_bind.cpp index 378d1ff618..e493e50467 100644 --- a/core/variant/callable_bind.cpp +++ b/core/variant/callable_bind.cpp @@ -144,6 +144,18 @@ void CallableCustomBind::call(const Variant **p_arguments, int p_argcount, Varia callable.callp(args, p_argcount + binds.size(), r_return_value, r_call_error); } +Error CallableCustomBind::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const { + const Variant **args = (const Variant **)alloca(sizeof(const Variant **) * (binds.size() + p_argcount)); + for (int i = 0; i < p_argcount; i++) { + args[i] = (const Variant *)p_arguments[i]; + } + for (int i = 0; i < binds.size(); i++) { + args[i + p_argcount] = (const Variant *)&binds[i]; + } + + return callable.rpcp(p_peer_id, args, p_argcount + binds.size(), r_call_error); +} + CallableCustomBind::CallableCustomBind(const Callable &p_callable, const Vector<Variant> &p_binds) { callable = p_callable; binds = p_binds; @@ -242,6 +254,16 @@ void CallableCustomUnbind::call(const Variant **p_arguments, int p_argcount, Var callable.callp(p_arguments, p_argcount - argcount, r_return_value, r_call_error); } +Error CallableCustomUnbind::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const { + if (argcount > p_argcount) { + r_call_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_call_error.argument = 0; + r_call_error.expected = argcount; + return ERR_UNCONFIGURED; + } + return callable.rpcp(p_peer_id, p_arguments, p_argcount - argcount, r_call_error); +} + CallableCustomUnbind::CallableCustomUnbind(const Callable &p_callable, int p_argcount) { callable = p_callable; argcount = p_argcount; diff --git a/core/variant/callable_bind.h b/core/variant/callable_bind.h index b51076ad0f..5798797a3d 100644 --- a/core/variant/callable_bind.h +++ b/core/variant/callable_bind.h @@ -51,6 +51,7 @@ public: virtual StringName get_method() const override; virtual ObjectID get_object() const override; virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; + virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override; virtual const Callable *get_base_comparator() const override; virtual int get_bound_arguments_count() const override; virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override; @@ -78,6 +79,7 @@ public: virtual StringName get_method() const override; virtual ObjectID get_object() const override; virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; + virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override; virtual const Callable *get_base_comparator() const override; virtual int get_bound_arguments_count() const override; virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override; diff --git a/core/variant/native_ptr.h b/core/variant/native_ptr.h index ea811daabf..9199b12845 100644 --- a/core/variant/native_ptr.h +++ b/core/variant/native_ptr.h @@ -53,36 +53,46 @@ struct GDExtensionPtr { operator Variant() const { return uint64_t(data); } }; -#define GDVIRTUAL_NATIVE_PTR(m_type) \ - template <> \ - struct GDExtensionConstPtr<const m_type> { \ - const m_type *data = nullptr; \ - GDExtensionConstPtr() {} \ - GDExtensionConstPtr(const m_type *p_assign) { data = p_assign; } \ - static const char *get_name() { return "const " #m_type; } \ - operator const m_type *() const { return data; } \ - operator Variant() const { return uint64_t(data); } \ - }; \ - template <> \ - struct VariantCaster<GDExtensionConstPtr<const m_type>> { \ - static _FORCE_INLINE_ GDExtensionConstPtr<const m_type> cast(const Variant &p_variant) { \ - return GDExtensionConstPtr<const m_type>((const m_type *)p_variant.operator uint64_t()); \ - } \ - }; \ - template <> \ - struct GDExtensionPtr<m_type> { \ - m_type *data = nullptr; \ - GDExtensionPtr() {} \ - GDExtensionPtr(m_type *p_assign) { data = p_assign; } \ - static const char *get_name() { return #m_type; } \ - operator m_type *() const { return data; } \ - operator Variant() const { return uint64_t(data); } \ - }; \ - template <> \ - struct VariantCaster<GDExtensionPtr<m_type>> { \ - static _FORCE_INLINE_ GDExtensionPtr<m_type> cast(const Variant &p_variant) { \ - return GDExtensionPtr<m_type>((m_type *)p_variant.operator uint64_t()); \ - } \ +#define GDVIRTUAL_NATIVE_PTR(m_type) \ + template <> \ + struct GDExtensionConstPtr<const m_type> { \ + const m_type *data = nullptr; \ + GDExtensionConstPtr() {} \ + GDExtensionConstPtr(const m_type *p_assign) { data = p_assign; } \ + static const char *get_name() { return "const " #m_type; } \ + operator const m_type *() const { return data; } \ + operator Variant() const { return uint64_t(data); } \ + }; \ + template <> \ + struct VariantCaster<GDExtensionConstPtr<const m_type>> { \ + static _FORCE_INLINE_ GDExtensionConstPtr<const m_type> cast(const Variant &p_variant) { \ + return GDExtensionConstPtr<const m_type>((const m_type *)p_variant.operator uint64_t()); \ + } \ + }; \ + template <> \ + struct VariantInternalAccessor<GDExtensionConstPtr<const m_type>> { \ + static _FORCE_INLINE_ const GDExtensionConstPtr<const m_type> &get(const Variant *v) { return *reinterpret_cast<const GDExtensionConstPtr<const m_type> *>(VariantInternal::get_int(v)); } \ + static _FORCE_INLINE_ void set(Variant *v, const GDExtensionConstPtr<const m_type> &p_value) { *VariantInternal::get_int(v) = uint64_t(p_value.data); } \ + }; \ + template <> \ + struct GDExtensionPtr<m_type> { \ + m_type *data = nullptr; \ + GDExtensionPtr() {} \ + GDExtensionPtr(m_type *p_assign) { data = p_assign; } \ + static const char *get_name() { return #m_type; } \ + operator m_type *() const { return data; } \ + operator Variant() const { return uint64_t(data); } \ + }; \ + template <> \ + struct VariantCaster<GDExtensionPtr<m_type>> { \ + static _FORCE_INLINE_ GDExtensionPtr<m_type> cast(const Variant &p_variant) { \ + return GDExtensionPtr<m_type>((m_type *)p_variant.operator uint64_t()); \ + } \ + }; \ + template <> \ + struct VariantInternalAccessor<GDExtensionPtr<m_type>> { \ + static _FORCE_INLINE_ const GDExtensionPtr<m_type> &get(const Variant *v) { return *reinterpret_cast<const GDExtensionPtr<m_type> *>(VariantInternal::get_int(v)); } \ + static _FORCE_INLINE_ void set(Variant *v, const GDExtensionPtr<m_type> &p_value) { *VariantInternal::get_int(v) = uint64_t(p_value.data); } \ }; template <class T> diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index a40fcfbd47..3320750994 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -865,12 +865,46 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } get_token(p_stream, token, line, r_err_str); - if (token.type != TK_NUMBER) { - r_err_str = "Expected number as argument"; + // Permit empty RID. + if (token.type == TK_PARENTHESIS_CLOSE) { + value = RID(); + return OK; + } else if (token.type != TK_NUMBER) { + r_err_str = "Expected number as argument or ')'"; return ERR_PARSE_ERROR; } - value = token.value; + value = RID::from_uint64(token.value); + + get_token(p_stream, token, line, r_err_str); + if (token.type != TK_PARENTHESIS_CLOSE) { + r_err_str = "Expected ')'"; + return ERR_PARSE_ERROR; + } + } else if (id == "Signal") { + get_token(p_stream, token, line, r_err_str); + if (token.type != TK_PARENTHESIS_OPEN) { + r_err_str = "Expected '('"; + return ERR_PARSE_ERROR; + } + + // Load as empty. + value = Signal(); + + get_token(p_stream, token, line, r_err_str); + if (token.type != TK_PARENTHESIS_CLOSE) { + r_err_str = "Expected ')'"; + return ERR_PARSE_ERROR; + } + } else if (id == "Callable") { + get_token(p_stream, token, line, r_err_str); + if (token.type != TK_PARENTHESIS_OPEN) { + r_err_str = "Expected '('"; + return ERR_PARSE_ERROR; + } + + // Load as empty. + value = Callable(); get_token(p_stream, token, line, r_err_str); if (token.type != TK_PARENTHESIS_CLOSE) { @@ -1832,6 +1866,24 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; + case Variant::RID: { + RID rid = p_variant; + + if (rid == RID()) { + p_store_string_func(p_store_string_ud, "RID()"); + } else { + p_store_string_func(p_store_string_ud, "RID(" + itos(rid.get_id()) + ")"); + } + } break; + + // Do not really store these, but ensure that assignments are not empty. + case Variant::SIGNAL: { + p_store_string_func(p_store_string_ud, "Signal()"); + } break; + case Variant::CALLABLE: { + p_store_string_func(p_store_string_ud, "Callable()"); + } break; + case Variant::OBJECT: { Object *obj = p_variant.get_validated_object(); @@ -2129,6 +2181,8 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str } break; default: { + ERR_PRINT("Unknown variant type"); + return ERR_BUG; } } |