diff --git a/core/dictionary.cpp b/core/dictionary.cpp index b8a57218541c..814a0c5363b0 100644 --- a/core/dictionary.cpp +++ b/core/dictionary.cpp @@ -125,6 +125,10 @@ Variant Dictionary::get_or_add(const Variant &p_key, const Variant &p_default) { return *result; } +void Dictionary::set(const Variant &p_key, const Variant &p_value) { + operator[](p_key) = p_value; +} + int Dictionary::size() const { return _p->variant_map.size(); } diff --git a/core/dictionary.h b/core/dictionary.h index dad679f30b44..bd04ab9d5bde 100644 --- a/core/dictionary.h +++ b/core/dictionary.h @@ -59,6 +59,7 @@ class Dictionary { Variant get_valid(const Variant &p_key) const; Variant get(const Variant &p_key, const Variant &p_default) const; Variant get_or_add(const Variant &p_key, const Variant &p_default); + void set(const Variant &p_key, const Variant &p_value); int size() const; bool empty() const; diff --git a/core/translation.cpp b/core/translation.cpp index d26a58f8f1c2..c911e738de11 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -365,32 +365,46 @@ String TranslationServer::_standardize_locale(const String &p_locale, bool p_add } int TranslationServer::compare_locales(const String &p_locale_a, const String &p_locale_b) const { + if (p_locale_a == p_locale_b) { + // Exact match. + return 10; + } + + const String cache_key = p_locale_a + "|" + p_locale_b; + const int *cached_result = locale_compare_cache.getptr(cache_key); + if (cached_result) { + return *cached_result; + } + String locale_a = _standardize_locale(p_locale_a, true); String locale_b = _standardize_locale(p_locale_b, true); if (locale_a == locale_b) { // Exact match. + locale_compare_cache.set(cache_key, 10); return 10; } Vector<String> locale_a_elements = locale_a.split("_"); Vector<String> locale_b_elements = locale_b.split("_"); - if (locale_a_elements[0] == locale_b_elements[0]) { - // Matching language, both locales have extra parts. - // Return number of matching elements. - int matching_elements = 1; - for (int i = 1; i < locale_a_elements.size(); i++) { - for (int j = 1; j < locale_b_elements.size(); j++) { - if (locale_a_elements[i] == locale_b_elements[j]) { - matching_elements++; - } - } - } - return matching_elements; - } else { + if (locale_a_elements[0] != locale_b_elements[0]) { // No match. + locale_compare_cache.set(cache_key, 0); return 0; } + + // Matching language, both locales have extra parts. + // Return number of matching elements. + int matching_elements = 1; + for (int i = 1; i < locale_a_elements.size(); i++) { + for (int j = 1; j < locale_b_elements.size(); j++) { + if (locale_a_elements[i] == locale_b_elements[j]) { + matching_elements++; + } + } + } + locale_compare_cache.set(cache_key, matching_elements); + return matching_elements; } String TranslationServer::get_locale_name(const String &p_locale) const { diff --git a/core/translation.h b/core/translation.h index 3a2db25cc838..bbb549de10c5 100644 --- a/core/translation.h +++ b/core/translation.h @@ -87,6 +87,8 @@ class TranslationServer : public Object { Ref<Translation> tool_translation; Ref<Translation> doc_translation; + mutable HashMap<String, int> locale_compare_cache; + bool enabled; static TranslationServer *singleton; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 83b3fd7ad71a..902133efb85e 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -562,6 +562,7 @@ struct _VariantCall { VCALL_LOCALMEM1R(Dictionary, duplicate); VCALL_LOCALMEM2R(Dictionary, get); VCALL_LOCALMEM2R(Dictionary, get_or_add); + VCALL_LOCALMEM2(Dictionary, set); VCALL_LOCALMEM2(Array, set); VCALL_LOCALMEM1R(Array, get); @@ -1940,6 +1941,7 @@ void register_variant_methods() { ADDFUNC0R(DICTIONARY, BOOL, Dictionary, empty, varray()); ADDFUNC0NC(DICTIONARY, NIL, Dictionary, clear, varray()); ADDFUNC2NC(DICTIONARY, NIL, Dictionary, merge, DICTIONARY, "dictionary", BOOL, "overwrite", varray(false)); + ADDFUNC2NC(DICTIONARY, NIL, Dictionary, set, NIL, "key", NIL, "value", varray()); ADDFUNC1R(DICTIONARY, BOOL, Dictionary, has, NIL, "key", varray()); ADDFUNC1R(DICTIONARY, BOOL, Dictionary, has_all, ARRAY, "keys", varray()); ADDFUNC1R(DICTIONARY, NIL, Dictionary, find_key, NIL, "value", varray()); @@ -1955,6 +1957,8 @@ void register_variant_methods() { ADDFUNC0R(ARRAY, BOOL, Array, empty, varray()); ADDFUNC0NC(ARRAY, NIL, Array, clear, varray()); ADDFUNC0R(ARRAY, INT, Array, hash, varray()); + ADDFUNC1R(ARRAY, NIL, Array, get, INT, "index", varray()); + ADDFUNC2NC(ARRAY, NIL, Array, set, INT, "index", NIL, "value", varray()); ADDFUNC1NC(ARRAY, NIL, Array, push_back, NIL, "value", varray()); ADDFUNC1NC(ARRAY, NIL, Array, push_front, NIL, "value", varray()); ADDFUNC1NC(ARRAY, NIL, Array, fill, NIL, "value", varray()); @@ -1988,6 +1992,7 @@ void register_variant_methods() { ADDFUNC0R(POOL_BYTE_ARRAY, INT, PoolByteArray, size, varray()); ADDFUNC0R(POOL_BYTE_ARRAY, BOOL, PoolByteArray, empty, varray()); + ADDFUNC1R(POOL_BYTE_ARRAY, INT, PoolByteArray, get, INT, "index", varray()); ADDFUNC2(POOL_BYTE_ARRAY, NIL, PoolByteArray, set, INT, "idx", INT, "byte", varray()); ADDFUNC1(POOL_BYTE_ARRAY, NIL, PoolByteArray, push_back, INT, "byte", varray()); ADDFUNC1(POOL_BYTE_ARRAY, NIL, PoolByteArray, fill, INT, "byte", varray()); @@ -2014,6 +2019,7 @@ void register_variant_methods() { ADDFUNC0R(POOL_INT_ARRAY, INT, PoolIntArray, size, varray()); ADDFUNC0R(POOL_INT_ARRAY, BOOL, PoolIntArray, empty, varray()); + ADDFUNC1R(POOL_INT_ARRAY, INT, PoolIntArray, get, INT, "index", varray()); ADDFUNC2(POOL_INT_ARRAY, NIL, PoolIntArray, set, INT, "idx", INT, "integer", varray()); ADDFUNC1(POOL_INT_ARRAY, NIL, PoolIntArray, push_back, INT, "integer", varray()); ADDFUNC1(POOL_INT_ARRAY, NIL, PoolIntArray, fill, INT, "integer", varray()); @@ -2032,6 +2038,7 @@ void register_variant_methods() { ADDFUNC0R(POOL_REAL_ARRAY, INT, PoolRealArray, size, varray()); ADDFUNC0R(POOL_REAL_ARRAY, BOOL, PoolRealArray, empty, varray()); + ADDFUNC1R(POOL_REAL_ARRAY, REAL, PoolRealArray, get, INT, "index", varray()); ADDFUNC2(POOL_REAL_ARRAY, NIL, PoolRealArray, set, INT, "idx", REAL, "value", varray()); ADDFUNC1(POOL_REAL_ARRAY, NIL, PoolRealArray, push_back, REAL, "value", varray()); ADDFUNC1(POOL_REAL_ARRAY, NIL, PoolRealArray, fill, REAL, "value", varray()); @@ -2050,6 +2057,7 @@ void register_variant_methods() { ADDFUNC0R(POOL_STRING_ARRAY, INT, PoolStringArray, size, varray()); ADDFUNC0R(POOL_STRING_ARRAY, BOOL, PoolStringArray, empty, varray()); + ADDFUNC1R(POOL_STRING_ARRAY, STRING, PoolStringArray, get, INT, "index", varray()); ADDFUNC2(POOL_STRING_ARRAY, NIL, PoolStringArray, set, INT, "idx", STRING, "string", varray()); ADDFUNC1(POOL_STRING_ARRAY, NIL, PoolStringArray, push_back, STRING, "string", varray()); ADDFUNC1(POOL_STRING_ARRAY, NIL, PoolStringArray, fill, STRING, "string", varray()); @@ -2069,6 +2077,7 @@ void register_variant_methods() { ADDFUNC0R(POOL_VECTOR2_ARRAY, INT, PoolVector2Array, size, varray()); ADDFUNC0R(POOL_VECTOR2_ARRAY, BOOL, PoolVector2Array, empty, varray()); + ADDFUNC1R(POOL_VECTOR2_ARRAY, VECTOR2, PoolVector2Array, get, INT, "index", varray()); ADDFUNC2(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, set, INT, "idx", VECTOR2, "vector2", varray()); ADDFUNC1(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, push_back, VECTOR2, "vector2", varray()); ADDFUNC1(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, fill, VECTOR2, "vector2", varray()); @@ -2087,6 +2096,7 @@ void register_variant_methods() { ADDFUNC0R(POOL_VECTOR3_ARRAY, INT, PoolVector3Array, size, varray()); ADDFUNC0R(POOL_VECTOR3_ARRAY, BOOL, PoolVector3Array, empty, varray()); + ADDFUNC1R(POOL_VECTOR3_ARRAY, VECTOR3, PoolVector3Array, get, INT, "index", varray()); ADDFUNC2(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, set, INT, "idx", VECTOR3, "vector3", varray()); ADDFUNC1(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, push_back, VECTOR3, "vector3", varray()); ADDFUNC1(POOL_VECTOR3_ARRAY, NIL, PoolVector3Array, fill, VECTOR3, "vector3", varray()); @@ -2105,6 +2115,7 @@ void register_variant_methods() { ADDFUNC0R(POOL_COLOR_ARRAY, INT, PoolColorArray, size, varray()); ADDFUNC0R(POOL_COLOR_ARRAY, BOOL, PoolColorArray, empty, varray()); + ADDFUNC1R(POOL_COLOR_ARRAY, COLOR, PoolColorArray, get, INT, "index", varray()); ADDFUNC2(POOL_COLOR_ARRAY, NIL, PoolColorArray, set, INT, "idx", COLOR, "color", varray()); ADDFUNC1(POOL_COLOR_ARRAY, NIL, PoolColorArray, push_back, COLOR, "color", varray()); ADDFUNC1(POOL_COLOR_ARRAY, NIL, PoolColorArray, fill, COLOR, "color", varray()); diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index e537bff81919..b559c6f2fa83 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -211,6 +211,13 @@ [b]Note:[/b] Calling this function is not the same as writing [code]array[0][/code]. If the array is empty, accessing by index will pause project execution when running from the editor. </description> </method> + <method name="get"> + <return type="Variant" /> + <argument index="0" name="index" type="int" /> + <description> + Returns the element at the given [code]index[/code] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has"> <return type="bool" /> <argument index="0" name="value" type="Variant" /> @@ -329,6 +336,13 @@ Searches the array in reverse order. Optionally, a start search index can be passed. If negative, the start index is considered relative to the end of the array. If the adjusted start index is out of bounds, this method searches from the end of the array. </description> </method> + <method name="set"> + <argument index="0" name="index" type="int" /> + <argument index="1" name="value" type="Variant" /> + <description> + Sets the value of the element at the given [code]index[/code] to the given [code]value[/code]. This will not change the size of the array, it only changes the value at an index already in the array. This is the same as using the [code][][/code] operator ([code]array[index] = value[/code]). + </description> + </method> <method name="shuffle"> <description> Shuffles the array such that the items will have a random order. This method uses the global random number generator common to methods such as [method @GDScript.randi]. Call [method @GDScript.randomize] to ensure that a new seed will be used each time if you want non-reproducible shuffling. diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index 3b82d98a75cc..2af7ad591f3b 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -187,6 +187,13 @@ Adds elements from [code]dictionary[/code] to this [Dictionary]. By default, duplicate keys will not be copied over, unless [code]overwrite[/code] is [code]true[/code]. </description> </method> + <method name="set"> + <argument index="0" name="key" type="Variant" /> + <argument index="1" name="value" type="Variant" /> + <description> + Sets the value of the element at the given [code]key[/code] to the given [code]value[/code]. This is the same as using the [code][][/code] operator ([code]array[index] = value[/code]). + </description> + </method> <method name="size"> <return type="int" /> <description> diff --git a/doc/classes/PoolByteArray.xml b/doc/classes/PoolByteArray.xml index eaabb87d06a5..453fee062ff4 100644 --- a/doc/classes/PoolByteArray.xml +++ b/doc/classes/PoolByteArray.xml @@ -100,6 +100,13 @@ Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed. Returns [code]-1[/code] if [code]from[/code] is out of bounds. </description> </method> + <method name="get"> + <return type="int" /> + <argument index="0" name="index" type="int" /> + <description> + Returns the byte at the given [code]index[/code] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="get_string_from_ascii"> <return type="String" /> <description> diff --git a/doc/classes/PoolColorArray.xml b/doc/classes/PoolColorArray.xml index f9a1223d0737..01c7a1c5a534 100644 --- a/doc/classes/PoolColorArray.xml +++ b/doc/classes/PoolColorArray.xml @@ -74,6 +74,13 @@ Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed. Returns [code]-1[/code] if [code]from[/code] is out of bounds. </description> </method> + <method name="get"> + <return type="Color" /> + <argument index="0" name="index" type="int" /> + <description> + Returns the Color at the given [code]index[/code] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has"> <return type="bool" /> <argument index="0" name="value" type="Color" /> diff --git a/doc/classes/PoolIntArray.xml b/doc/classes/PoolIntArray.xml index efb44f7034b3..2275f497edd2 100644 --- a/doc/classes/PoolIntArray.xml +++ b/doc/classes/PoolIntArray.xml @@ -75,6 +75,13 @@ Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed. Returns [code]-1[/code] if [code]from[/code] is out of bounds. </description> </method> + <method name="get"> + <return type="int" /> + <argument index="0" name="index" type="int" /> + <description> + Returns the integer at the given [code]index[/code] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has"> <return type="bool" /> <argument index="0" name="value" type="int" /> diff --git a/doc/classes/PoolRealArray.xml b/doc/classes/PoolRealArray.xml index 2e2cd4c44f32..2bec2aa62f21 100644 --- a/doc/classes/PoolRealArray.xml +++ b/doc/classes/PoolRealArray.xml @@ -75,6 +75,13 @@ Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed. Returns [code]-1[/code] if [code]from[/code] is out of bounds. </description> </method> + <method name="get"> + <return type="float" /> + <argument index="0" name="index" type="int" /> + <description> + Returns the float at the given [code]index[/code] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has"> <return type="bool" /> <argument index="0" name="value" type="float" /> diff --git a/doc/classes/PoolStringArray.xml b/doc/classes/PoolStringArray.xml index 0c8a4e9a9377..958cd2515f97 100644 --- a/doc/classes/PoolStringArray.xml +++ b/doc/classes/PoolStringArray.xml @@ -75,6 +75,13 @@ Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed. Returns [code]-1[/code] if [code]from[/code] is out of bounds. </description> </method> + <method name="get"> + <return type="String" /> + <argument index="0" name="index" type="int" /> + <description> + Returns the String at the given [code]index[/code] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has"> <return type="bool" /> <argument index="0" name="value" type="String" /> diff --git a/doc/classes/PoolVector2Array.xml b/doc/classes/PoolVector2Array.xml index 4da929cb64ab..bc597d470980 100644 --- a/doc/classes/PoolVector2Array.xml +++ b/doc/classes/PoolVector2Array.xml @@ -75,6 +75,13 @@ Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed. Returns [code]-1[/code] if [code]from[/code] is out of bounds. </description> </method> + <method name="get"> + <return type="Vector2" /> + <argument index="0" name="index" type="int" /> + <description> + Returns the Vector2 at the given [code]index[/code] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has"> <return type="bool" /> <argument index="0" name="value" type="Vector2" /> diff --git a/doc/classes/PoolVector3Array.xml b/doc/classes/PoolVector3Array.xml index d6d645af8566..b81f6fec141d 100644 --- a/doc/classes/PoolVector3Array.xml +++ b/doc/classes/PoolVector3Array.xml @@ -74,6 +74,13 @@ Searches the array for a value and returns its index or [code]-1[/code] if not found. Optionally, the initial search index can be passed. Returns [code]-1[/code] if [code]from[/code] is out of bounds. </description> </method> + <method name="get"> + <return type="Vector3" /> + <argument index="0" name="index" type="int" /> + <description> + Returns the Vector3 at the given [code]index[/code] in the array. This is the same as using the [code][][/code] operator ([code]array[index][/code]). + </description> + </method> <method name="has"> <return type="bool" /> <argument index="0" name="value" type="Vector3" /> diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index a3f221606157..edf7f9451a4e 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -231,12 +231,14 @@ AudioStreamPlaybackMicrophone::AudioStreamPlaybackMicrophone() { //////////////////////////////// void AudioStreamRandomPitch::set_audio_stream(const Ref<AudioStream> &p_audio_stream) { + AudioServer::get_singleton()->lock(); audio_stream = p_audio_stream; if (audio_stream.is_valid()) { for (Set<AudioStreamPlaybackRandomPitch *>::Element *E = playbacks.front(); E; E = E->next()) { E->get()->playback = audio_stream->instance_playback(); } } + AudioServer::get_singleton()->unlock(); } Ref<AudioStream> AudioStreamRandomPitch::get_audio_stream() const {