diff options
30 files changed, 281 insertions, 273 deletions
diff --git a/core/templates/vector.h b/core/templates/vector.h index e53c502f67..bd4c6ade86 100644 --- a/core/templates/vector.h +++ b/core/templates/vector.h @@ -42,6 +42,7 @@ #include "core/templates/search_array.h" #include "core/templates/sort_array.h" +#include <climits> #include <initializer_list> template <class T> @@ -144,25 +145,29 @@ public: return ret; } - Vector<T> slice(int p_begin, int p_end) const { + Vector<T> slice(int p_begin, int p_end = INT_MAX) const { Vector<T> result; - if (p_end < 0) { - p_end += size() + 1; - } + const int s = size(); - ERR_FAIL_INDEX_V(p_begin, size(), result); - ERR_FAIL_INDEX_V(p_end, size() + 1, result); + int begin = CLAMP(p_begin, -s, s); + if (begin < 0) { + begin += s; + } + int end = CLAMP(p_end, -s, s); + if (end < 0) { + end += s; + } - ERR_FAIL_COND_V(p_begin > p_end, result); + ERR_FAIL_COND_V(begin > end, result); - int result_size = p_end - p_begin; + int result_size = end - begin; result.resize(result_size); const T *const r = ptr(); T *const w = result.ptrw(); for (int i = 0; i < result_size; ++i) { - w[i] = r[p_begin + i]; + w[i] = r[begin + i]; } return result; diff --git a/core/variant/array.cpp b/core/variant/array.cpp index 8d20b1bc79..3d2f337442 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -370,20 +370,24 @@ Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { ERR_FAIL_COND_V_MSG(p_step == 0, result, "Slice step cannot be zero."); - if (p_end < 0) { - p_end += size() + 1; - } + const int s = size(); - ERR_FAIL_INDEX_V(p_begin, size(), result); - ERR_FAIL_INDEX_V(p_end, size() + 1, result); + int begin = CLAMP(p_begin, -s, s); + if (begin < 0) { + begin += s; + } + int end = CLAMP(p_end, -s, s); + if (end < 0) { + end += s; + } - ERR_FAIL_COND_V_MSG(p_step > 0 && p_begin > p_end, result, "Slice is positive, but bounds is decreasing"); - ERR_FAIL_COND_V_MSG(p_step < 0 && p_begin < p_end, result, "Slice is negative, but bounds is increasing"); + ERR_FAIL_COND_V_MSG(p_step > 0 && begin > end, result, "Slice is positive, but bounds is decreasing."); + ERR_FAIL_COND_V_MSG(p_step < 0 && begin < end, result, "Slice is negative, but bounds is increasing."); - int result_size = (p_end - p_begin) / p_step; + int result_size = (end - begin) / p_step; result.resize(result_size); - for (int src_idx = p_begin, dest_idx = 0; dest_idx < result_size; ++dest_idx) { + for (int src_idx = begin, dest_idx = 0; dest_idx < result_size; ++dest_idx) { result[dest_idx] = p_deep ? get(src_idx).duplicate(true) : get(src_idx); src_idx += p_step; } diff --git a/core/variant/array.h b/core/variant/array.h index f48444bb39..72bed5932c 100644 --- a/core/variant/array.h +++ b/core/variant/array.h @@ -33,6 +33,8 @@ #include "core/typedefs.h" +#include <climits> + class Variant; class ArrayPrivate; class Object; @@ -102,7 +104,7 @@ public: Array duplicate(bool p_deep = false) const; Array recursive_duplicate(bool p_deep, int recursion_count) const; - Array slice(int p_begin, int p_end, int p_step = 1, bool p_deep = false) const; + Array slice(int p_begin, int p_end = INT_MAX, int p_step = 1, bool p_deep = false) const; Array filter(const Callable &p_callable) const; Array map(const Callable &p_callable) const; Variant reduce(const Callable &p_callable, const Variant &p_accum) const; diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index ecf5009fb6..8dd48a4c28 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1838,7 +1838,7 @@ static void _register_variant_builtin_methods() { bind_method(Array, bsearch_custom, sarray("value", "func", "before"), varray(true)); bind_method(Array, reverse, sarray(), varray()); bind_method(Array, duplicate, sarray("deep"), varray(false)); - bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false)); + bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(INT_MAX, 1, false)); bind_method(Array, filter, sarray("method"), varray()); bind_method(Array, map, sarray("method"), varray()); bind_method(Array, reduce, sarray("method", "accum"), varray(Variant())); @@ -1858,7 +1858,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedByteArray, resize, sarray("new_size"), varray()); bind_method(PackedByteArray, has, sarray("value"), varray()); bind_method(PackedByteArray, reverse, sarray(), varray()); - bind_method(PackedByteArray, slice, sarray("begin", "end"), varray()); + bind_method(PackedByteArray, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedByteArray, sort, sarray(), varray()); bind_method(PackedByteArray, bsearch, sarray("value", "before"), varray(true)); bind_method(PackedByteArray, duplicate, sarray(), varray()); @@ -1919,7 +1919,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedInt32Array, resize, sarray("new_size"), varray()); bind_method(PackedInt32Array, has, sarray("value"), varray()); bind_method(PackedInt32Array, reverse, sarray(), varray()); - bind_method(PackedInt32Array, slice, sarray("begin", "end"), varray()); + bind_method(PackedInt32Array, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedInt32Array, to_byte_array, sarray(), varray()); bind_method(PackedInt32Array, sort, sarray(), varray()); bind_method(PackedInt32Array, bsearch, sarray("value", "before"), varray(true)); @@ -1939,7 +1939,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedInt64Array, resize, sarray("new_size"), varray()); bind_method(PackedInt64Array, has, sarray("value"), varray()); bind_method(PackedInt64Array, reverse, sarray(), varray()); - bind_method(PackedInt64Array, slice, sarray("begin", "end"), varray()); + bind_method(PackedInt64Array, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedInt64Array, to_byte_array, sarray(), varray()); bind_method(PackedInt64Array, sort, sarray(), varray()); bind_method(PackedInt64Array, bsearch, sarray("value", "before"), varray(true)); @@ -1959,7 +1959,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedFloat32Array, resize, sarray("new_size"), varray()); bind_method(PackedFloat32Array, has, sarray("value"), varray()); bind_method(PackedFloat32Array, reverse, sarray(), varray()); - bind_method(PackedFloat32Array, slice, sarray("begin", "end"), varray()); + bind_method(PackedFloat32Array, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedFloat32Array, to_byte_array, sarray(), varray()); bind_method(PackedFloat32Array, sort, sarray(), varray()); bind_method(PackedFloat32Array, bsearch, sarray("value", "before"), varray(true)); @@ -1979,7 +1979,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedFloat64Array, resize, sarray("new_size"), varray()); bind_method(PackedFloat64Array, has, sarray("value"), varray()); bind_method(PackedFloat64Array, reverse, sarray(), varray()); - bind_method(PackedFloat64Array, slice, sarray("begin", "end"), varray()); + bind_method(PackedFloat64Array, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedFloat64Array, to_byte_array, sarray(), varray()); bind_method(PackedFloat64Array, sort, sarray(), varray()); bind_method(PackedFloat64Array, bsearch, sarray("value", "before"), varray(true)); @@ -1999,7 +1999,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedStringArray, resize, sarray("new_size"), varray()); bind_method(PackedStringArray, has, sarray("value"), varray()); bind_method(PackedStringArray, reverse, sarray(), varray()); - bind_method(PackedStringArray, slice, sarray("begin", "end"), varray()); + bind_method(PackedStringArray, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedStringArray, to_byte_array, sarray(), varray()); bind_method(PackedStringArray, sort, sarray(), varray()); bind_method(PackedStringArray, bsearch, sarray("value", "before"), varray(true)); @@ -2019,7 +2019,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedVector2Array, resize, sarray("new_size"), varray()); bind_method(PackedVector2Array, has, sarray("value"), varray()); bind_method(PackedVector2Array, reverse, sarray(), varray()); - bind_method(PackedVector2Array, slice, sarray("begin", "end"), varray()); + bind_method(PackedVector2Array, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedVector2Array, to_byte_array, sarray(), varray()); bind_method(PackedVector2Array, sort, sarray(), varray()); bind_method(PackedVector2Array, bsearch, sarray("value", "before"), varray(true)); @@ -2039,7 +2039,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedVector3Array, resize, sarray("new_size"), varray()); bind_method(PackedVector3Array, has, sarray("value"), varray()); bind_method(PackedVector3Array, reverse, sarray(), varray()); - bind_method(PackedVector3Array, slice, sarray("begin", "end"), varray()); + bind_method(PackedVector3Array, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedVector3Array, to_byte_array, sarray(), varray()); bind_method(PackedVector3Array, sort, sarray(), varray()); bind_method(PackedVector3Array, bsearch, sarray("value", "before"), varray(true)); @@ -2059,7 +2059,7 @@ static void _register_variant_builtin_methods() { bind_method(PackedColorArray, resize, sarray("new_size"), varray()); bind_method(PackedColorArray, has, sarray("value"), varray()); bind_method(PackedColorArray, reverse, sarray(), varray()); - bind_method(PackedColorArray, slice, sarray("begin", "end"), varray()); + bind_method(PackedColorArray, slice, sarray("begin", "end"), varray(INT_MAX)); bind_method(PackedColorArray, to_byte_array, sarray(), varray()); bind_method(PackedColorArray, sort, sarray(), varray()); bind_method(PackedColorArray, bsearch, sarray("value", "before"), varray(true)); diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index 7cb6f71190..57f51c7ccf 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -445,13 +445,14 @@ <method name="slice" qualifiers="const"> <return type="Array" /> <argument index="0" name="begin" type="int" /> - <argument index="1" name="end" type="int" /> + <argument index="1" name="end" type="int" default="2147483647" /> <argument index="2" name="step" type="int" default="1" /> <argument index="3" name="deep" type="bool" default="false" /> <description> Returns the slice of the [Array], from [code]begin[/code] (inclusive) to [code]end[/code] (exclusive), as a new [Array]. - If [code]end[/code] is negative, it will be relative to the end of the array. - If specified, [code]step[/code] is the relative index between source elements. + The absolute value of [code]begin[/code] and [code]end[/code] will be clamped to the array size, so the default value for [code]end[/code] makes it slice to the size of the array by default (i.e. [code]arr.slice(1)[/code] is a shorthand for [code]arr.slice(1, arr.size())[/code]). + If either [code]begin[/code] or [code]end[/code] are negative, they will be relative to the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for [code]arr.slice(0, arr.size() - 2)[/code]). + If specified, [code]step[/code] is the relative index between source elements. It can be negative, then [code]begin[/code] must be higher than [code]end[/code]. For example, [code][0, 1, 2, 3, 4, 5].slice(5, 1, -2)[/code] returns [code][5, 3][/code]). If [code]deep[/code] is true, each element will be copied by value rather than by reference. </description> </method> diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml index 686854ffe8..3dc8307d44 100644 --- a/doc/classes/PackedByteArray.xml +++ b/doc/classes/PackedByteArray.xml @@ -369,10 +369,11 @@ <method name="slice" qualifiers="const"> <return type="PackedByteArray" /> <argument index="0" name="begin" type="int" /> - <argument index="1" name="end" type="int" /> + <argument index="1" name="end" type="int" default="2147483647" /> <description> Returns the slice of the [PackedByteArray], from [code]begin[/code] (inclusive) to [code]end[/code] (exclusive), as a new [PackedByteArray]. - If [code]end[/code]is negative, it will be relative to the end of the array. + The absolute value of [code]begin[/code] and [code]end[/code] will be clamped to the array size, so the default value for [code]end[/code] makes it slice to the size of the array by default (i.e. [code]arr.slice(1)[/code] is a shorthand for [code]arr.slice(1, arr.size())[/code]). + If either [code]begin[/code] or [code]end[/code] are negative, they will be relative to the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for [code]arr.slice(0, arr.size() - 2)[/code]). </description> </method> <method name="sort"> diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml index d875549319..8aac7d1bf4 100644 --- a/doc/classes/PackedColorArray.xml +++ b/doc/classes/PackedColorArray.xml @@ -132,8 +132,11 @@ <method name="slice" qualifiers="const"> <return type="PackedColorArray" /> <argument index="0" name="begin" type="int" /> - <argument index="1" name="end" type="int" /> + <argument index="1" name="end" type="int" default="2147483647" /> <description> + Returns the slice of the [PackedColorArray], from [code]begin[/code] (inclusive) to [code]end[/code] (exclusive), as a new [PackedColorArray]. + The absolute value of [code]begin[/code] and [code]end[/code] will be clamped to the array size, so the default value for [code]end[/code] makes it slice to the size of the array by default (i.e. [code]arr.slice(1)[/code] is a shorthand for [code]arr.slice(1, arr.size())[/code]). + If either [code]begin[/code] or [code]end[/code] are negative, they will be relative to the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for [code]arr.slice(0, arr.size() - 2)[/code]). </description> </method> <method name="sort"> diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml index 6c77c4bee2..0e66dd7967 100644 --- a/doc/classes/PackedFloat32Array.xml +++ b/doc/classes/PackedFloat32Array.xml @@ -133,8 +133,11 @@ <method name="slice" qualifiers="const"> <return type="PackedFloat32Array" /> <argument index="0" name="begin" type="int" /> - <argument index="1" name="end" type="int" /> + <argument index="1" name="end" type="int" default="2147483647" /> <description> + Returns the slice of the [PackedFloat32Array], from [code]begin[/code] (inclusive) to [code]end[/code] (exclusive), as a new [PackedFloat32Array]. + The absolute value of [code]begin[/code] and [code]end[/code] will be clamped to the array size, so the default value for [code]end[/code] makes it slice to the size of the array by default (i.e. [code]arr.slice(1)[/code] is a shorthand for [code]arr.slice(1, arr.size())[/code]). + If either [code]begin[/code] or [code]end[/code] are negative, they will be relative to the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for [code]arr.slice(0, arr.size() - 2)[/code]). </description> </method> <method name="sort"> diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml index a8282c099a..eaad4fec54 100644 --- a/doc/classes/PackedFloat64Array.xml +++ b/doc/classes/PackedFloat64Array.xml @@ -133,8 +133,11 @@ <method name="slice" qualifiers="const"> <return type="PackedFloat64Array" /> <argument index="0" name="begin" type="int" /> - <argument index="1" name="end" type="int" /> + <argument index="1" name="end" type="int" default="2147483647" /> <description> + Returns the slice of the [PackedFloat64Array], from [code]begin[/code] (inclusive) to [code]end[/code] (exclusive), as a new [PackedFloat64Array]. + The absolute value of [code]begin[/code] and [code]end[/code] will be clamped to the array size, so the default value for [code]end[/code] makes it slice to the size of the array by default (i.e. [code]arr.slice(1)[/code] is a shorthand for [code]arr.slice(1, arr.size())[/code]). + If either [code]begin[/code] or [code]end[/code] are negative, they will be relative to the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for [code]arr.slice(0, arr.size() - 2)[/code]). </description> </method> <method name="sort"> diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml index da26e93b96..ec698ed8e5 100644 --- a/doc/classes/PackedInt32Array.xml +++ b/doc/classes/PackedInt32Array.xml @@ -133,8 +133,11 @@ <method name="slice" qualifiers="const"> <return type="PackedInt32Array" /> <argument index="0" name="begin" type="int" /> - <argument index="1" name="end" type="int" /> + <argument index="1" name="end" type="int" default="2147483647" /> <description> + Returns the slice of the [PackedInt32Array], from [code]begin[/code] (inclusive) to [code]end[/code] (exclusive), as a new [PackedInt32Array]. + The absolute value of [code]begin[/code] and [code]end[/code] will be clamped to the array size, so the default value for [code]end[/code] makes it slice to the size of the array by default (i.e. [code]arr.slice(1)[/code] is a shorthand for [code]arr.slice(1, arr.size())[/code]). + If either [code]begin[/code] or [code]end[/code] are negative, they will be relative to the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for [code]arr.slice(0, arr.size() - 2)[/code]). </description> </method> <method name="sort"> diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml index 9ddf43a837..ec4b3c1209 100644 --- a/doc/classes/PackedInt64Array.xml +++ b/doc/classes/PackedInt64Array.xml @@ -133,8 +133,11 @@ <method name="slice" qualifiers="const"> <return type="PackedInt64Array" /> <argument index="0" name="begin" type="int" /> - <argument index="1" name="end" type="int" /> + <argument index="1" name="end" type="int" default="2147483647" /> <description> + Returns the slice of the [PackedInt64Array], from [code]begin[/code] (inclusive) to [code]end[/code] (exclusive), as a new [PackedInt64Array]. + The absolute value of [code]begin[/code] and [code]end[/code] will be clamped to the array size, so the default value for [code]end[/code] makes it slice to the size of the array by default (i.e. [code]arr.slice(1)[/code] is a shorthand for [code]arr.slice(1, arr.size())[/code]). + If either [code]begin[/code] or [code]end[/code] are negative, they will be relative to the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for [code]arr.slice(0, arr.size() - 2)[/code]). </description> </method> <method name="sort"> diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml index 439d59dde7..ebe9c591b8 100644 --- a/doc/classes/PackedStringArray.xml +++ b/doc/classes/PackedStringArray.xml @@ -133,8 +133,11 @@ <method name="slice" qualifiers="const"> <return type="PackedStringArray" /> <argument index="0" name="begin" type="int" /> - <argument index="1" name="end" type="int" /> + <argument index="1" name="end" type="int" default="2147483647" /> <description> + Returns the slice of the [PackedStringArray], from [code]begin[/code] (inclusive) to [code]end[/code] (exclusive), as a new [PackedStringArray]. + The absolute value of [code]begin[/code] and [code]end[/code] will be clamped to the array size, so the default value for [code]end[/code] makes it slice to the size of the array by default (i.e. [code]arr.slice(1)[/code] is a shorthand for [code]arr.slice(1, arr.size())[/code]). + If either [code]begin[/code] or [code]end[/code] are negative, they will be relative to the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for [code]arr.slice(0, arr.size() - 2)[/code]). </description> </method> <method name="sort"> diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml index 8c4f052016..d72ca4b4bb 100644 --- a/doc/classes/PackedVector2Array.xml +++ b/doc/classes/PackedVector2Array.xml @@ -133,8 +133,11 @@ <method name="slice" qualifiers="const"> <return type="PackedVector2Array" /> <argument index="0" name="begin" type="int" /> - <argument index="1" name="end" type="int" /> + <argument index="1" name="end" type="int" default="2147483647" /> <description> + Returns the slice of the [PackedVector2Array], from [code]begin[/code] (inclusive) to [code]end[/code] (exclusive), as a new [PackedVector2Array]. + The absolute value of [code]begin[/code] and [code]end[/code] will be clamped to the array size, so the default value for [code]end[/code] makes it slice to the size of the array by default (i.e. [code]arr.slice(1)[/code] is a shorthand for [code]arr.slice(1, arr.size())[/code]). + If either [code]begin[/code] or [code]end[/code] are negative, they will be relative to the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for [code]arr.slice(0, arr.size() - 2)[/code]). </description> </method> <method name="sort"> diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml index 8229af984d..cbae0c40e7 100644 --- a/doc/classes/PackedVector3Array.xml +++ b/doc/classes/PackedVector3Array.xml @@ -132,8 +132,11 @@ <method name="slice" qualifiers="const"> <return type="PackedVector3Array" /> <argument index="0" name="begin" type="int" /> - <argument index="1" name="end" type="int" /> + <argument index="1" name="end" type="int" default="2147483647" /> <description> + Returns the slice of the [PackedVector3Array], from [code]begin[/code] (inclusive) to [code]end[/code] (exclusive), as a new [PackedVector3Array]. + The absolute value of [code]begin[/code] and [code]end[/code] will be clamped to the array size, so the default value for [code]end[/code] makes it slice to the size of the array by default (i.e. [code]arr.slice(1)[/code] is a shorthand for [code]arr.slice(1, arr.size())[/code]). + If either [code]begin[/code] or [code]end[/code] are negative, they will be relative to the end of the array (i.e. [code]arr.slice(0, -2)[/code] is a shorthand for [code]arr.slice(0, arr.size() - 2)[/code]). </description> </method> <method name="sort"> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 9e2d789076..357186b917 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -487,7 +487,7 @@ </member> <member name="display/window/handheld/orientation" type="int" setter="" getter="" default="0"> The default screen orientation to use on mobile devices. See [enum DisplayServer.ScreenOrientation] for possible values. - [b]Note:[/b] When set to a portrait orientation, this project setting does not flip the project resolution's width and height automatically. Instead, you have to set [member display/window/size/width] and [member display/window/size/height] accordingly. + [b]Note:[/b] When set to a portrait orientation, this project setting does not flip the project resolution's width and height automatically. Instead, you have to set [member display/window/size/viewport_width] and [member display/window/size/viewport_height] accordingly. </member> <member name="display/window/ios/hide_home_indicator" type="bool" setter="" getter="" default="true"> If [code]true[/code], the home indicator is hidden automatically. This only affects iOS devices without a physical home button. @@ -505,21 +505,23 @@ Regardless of the platform, enabling fullscreen will change the window size to match the monitor's size. Therefore, make sure your project supports [url=$DOCS_URL/tutorials/rendering/multiple_resolutions.html]multiple resolutions[/url] when enabling fullscreen mode. [b]Note:[/b] This setting is ignored on iOS, Android, and HTML5. </member> - <member name="display/window/size/height" type="int" setter="" getter="" default="600"> - Sets the game's main viewport height. On desktop platforms, this is the default window size. Stretch mode settings also use this as a reference when enabled. - </member> <member name="display/window/size/resizable" type="bool" setter="" getter="" default="true"> Allows the window to be resizable by default. [b]Note:[/b] This setting is ignored on iOS and Android. </member> - <member name="display/window/size/test_height" type="int" setter="" getter="" default="0"> - If greater than zero, overrides the window height when running the game. Useful for testing stretch modes. + <member name="display/window/size/viewport_height" type="int" setter="" getter="" default="600"> + Sets the game's main viewport height. On desktop platforms, this is also the initial window height. + </member> + <member name="display/window/size/viewport_width" type="int" setter="" getter="" default="1024"> + Sets the game's main viewport width. On desktop platforms, this is also the initial window width. </member> - <member name="display/window/size/test_width" type="int" setter="" getter="" default="0"> - If greater than zero, overrides the window width when running the game. Useful for testing stretch modes. + <member name="display/window/size/window_height_override" type="int" setter="" getter="" default="0"> + On desktop platforms, sets the game's initial window height. + [b]Note:[/b] By default, or when set to 0, the initial window height is the [member display/window/size/viewport_height]. This setting is ignored on iOS, Android, and HTML5. </member> - <member name="display/window/size/width" type="int" setter="" getter="" default="1024"> - Sets the game's main viewport width. On desktop platforms, this is the default window size. Stretch mode settings also use this as a reference when enabled. + <member name="display/window/size/window_width_override" type="int" setter="" getter="" default="0"> + On desktop platforms, sets the game's initial window width. + [b]Note:[/b] By default, or when set to 0, the initial window width is the viewport [member display/window/size/viewport_width]. This setting is ignored on iOS, Android, and HTML5. </member> <member name="display/window/vsync/vsync_mode" type="int" setter="" getter="" default="1"> Sets the VSync mode for the main game window. diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 5d868777e7..11efe7202e 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -2593,13 +2593,21 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { file->set_current_path(path.replacen("." + ext, "." + extensions.front()->get())); } } - } else { - String existing; - if (extensions.size()) { - String root_name(scene->get_name()); - existing = root_name + "." + extensions.front()->get().to_lower(); + } else if (extensions.size()) { + String root_name = scene->get_name(); + // Very similar to node naming logic. + switch (ProjectSettings::get_singleton()->get("editor/scene/scene_naming").operator int()) { + case SCENE_NAME_CASING_AUTO: + // Use casing of the root node. + break; + case SCENE_NAME_CASING_PASCAL_CASE: { + root_name = root_name.capitalize().replace(" ", ""); + } break; + case SCENE_NAME_CASING_SNAKE_CASE: + root_name = root_name.capitalize().replace(" ", "").replace("-", "_").camelcase_to_underscore(); + break; } - file->set_current_path(existing); + file->set_current_path(root_name + "." + extensions.front()->get().to_lower()); } file->popup_file_dialog(); file->set_title(TTR("Save Scene As...")); @@ -5673,6 +5681,8 @@ void EditorNode::_feature_profile_changed() { } void EditorNode::_bind_methods() { + GLOBAL_DEF("editor/scene/scene_naming", SCENE_NAME_CASING_SNAKE_CASE); + ProjectSettings::get_singleton()->set_custom_property_info("editor/scene/scene_naming", PropertyInfo(Variant::INT, "editor/scene/scene_naming", PROPERTY_HINT_ENUM, "Auto,PascalCase,snake_case")); ClassDB::bind_method("_editor_select", &EditorNode::_editor_select); ClassDB::bind_method("_node_renamed", &EditorNode::_node_renamed); ClassDB::bind_method("edit_node", &EditorNode::edit_node); diff --git a/editor/editor_node.h b/editor/editor_node.h index e315f1f4b3..7f5d23dbde 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -216,6 +216,12 @@ private: TOOL_MENU_BASE = 1000 }; + enum ScriptNameCasing { + SCENE_NAME_CASING_AUTO, + SCENE_NAME_CASING_PASCAL_CASE, + SCENE_NAME_CASING_SNAKE_CASE + }; + SubViewport *scene_root; // root of the scene being edited PanelContainer *scene_root_parent; diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index 3c1799d80c..574abf85ea 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -98,15 +98,15 @@ Error EditorRun::run(const String &p_scene) { screen_rect.position = DisplayServer::get_singleton()->screen_get_position(screen); screen_rect.size = DisplayServer::get_singleton()->screen_get_size(screen); + Size2 window_size; + window_size.x = ProjectSettings::get_singleton()->get("display/window/size/viewport_width"); + window_size.y = ProjectSettings::get_singleton()->get("display/window/size/viewport_height"); + Size2 desired_size; - desired_size.x = ProjectSettings::get_singleton()->get("display/window/size/width"); - desired_size.y = ProjectSettings::get_singleton()->get("display/window/size/height"); - - Size2 test_size; - test_size.x = ProjectSettings::get_singleton()->get("display/window/size/test_width"); - test_size.y = ProjectSettings::get_singleton()->get("display/window/size/test_height"); - if (test_size.x > 0 && test_size.y > 0) { - desired_size = test_size; + desired_size.x = ProjectSettings::get_singleton()->get("display/window/size/window_width_override"); + desired_size.y = ProjectSettings::get_singleton()->get("display/window/size/window_height_override"); + if (desired_size.x > 0 && desired_size.y > 0) { + window_size = desired_size; } int window_placement = EditorSettings::get_singleton()->get("run/window_placement/rect"); @@ -136,7 +136,7 @@ Error EditorRun::run(const String &p_scene) { args.push_back(itos(screen_rect.position.x) + "," + itos(screen_rect.position.y)); } break; case 1: { // centered - Vector2 pos = (screen_rect.position) + ((screen_rect.size - desired_size) / 2).floor(); + Vector2 pos = (screen_rect.position) + ((screen_rect.size - window_size) / 2).floor(); args.push_back("--position"); args.push_back(itos(pos.x) + "," + itos(pos.y)); } break; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index cb84e7ea65..970d53a137 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -3517,7 +3517,7 @@ void CanvasItemEditor::_draw_axis() { Color area_axis_color = EditorSettings::get_singleton()->get("editors/2d/viewport_border_color"); - Size2 screen_size = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); + Size2 screen_size = Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height")); Vector2 screen_endpoints[4] = { transform.xform(Vector2(0, 0)), @@ -4010,7 +4010,7 @@ void CanvasItemEditor::_update_scrollbars() { Size2 vmin = v_scroll->get_minimum_size(); // Get the visible frame. - Size2 screen_rect = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); + Size2 screen_rect = Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height")); Rect2 local_rect = Rect2(Point2(), viewport->get_size() - Size2(vmin.width, hmin.height)); // Calculate scrollable area. diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 6ea8fba9b5..ef9c6a65e7 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -3064,7 +3064,7 @@ void Node3DEditorViewport::_draw() { Math::round(2 * EDSCALE)); } if (previewing) { - Size2 ss = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); + Size2 ss = Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height")); float aspect = ss.aspect(); Size2 s = get_size(); diff --git a/main/main.cpp b/main/main.cpp index 7350e15ef5..8b58641461 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1306,47 +1306,47 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph // always convert to lower case for consistency in the code rendering_driver = rendering_driver.to_lower(); - GLOBAL_DEF_BASIC("display/window/size/width", 1024); - ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/width", - PropertyInfo(Variant::INT, "display/window/size/width", + GLOBAL_DEF_BASIC("display/window/size/viewport_width", 1024); + ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/viewport_width", + PropertyInfo(Variant::INT, "display/window/size/viewport_width", PROPERTY_HINT_RANGE, "0,7680,or_greater")); // 8K resolution - GLOBAL_DEF_BASIC("display/window/size/height", 600); - ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/height", - PropertyInfo(Variant::INT, "display/window/size/height", + GLOBAL_DEF_BASIC("display/window/size/viewport_height", 600); + ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/viewport_height", + PropertyInfo(Variant::INT, "display/window/size/viewport_height", PROPERTY_HINT_RANGE, "0,4320,or_greater")); // 8K resolution GLOBAL_DEF_BASIC("display/window/size/resizable", true); GLOBAL_DEF_BASIC("display/window/size/borderless", false); GLOBAL_DEF_BASIC("display/window/size/fullscreen", false); GLOBAL_DEF("display/window/size/always_on_top", false); - GLOBAL_DEF("display/window/size/test_width", 0); - ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/test_width", + GLOBAL_DEF("display/window/size/window_width_override", 0); + ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/window_width_override", PropertyInfo(Variant::INT, - "display/window/size/test_width", + "display/window/size/window_width_override", PROPERTY_HINT_RANGE, "0,7680,or_greater")); // 8K resolution - GLOBAL_DEF("display/window/size/test_height", 0); - ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/test_height", + GLOBAL_DEF("display/window/size/window_height_override", 0); + ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/window_height_override", PropertyInfo(Variant::INT, - "display/window/size/test_height", + "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "0,4320,or_greater")); // 8K resolution if (use_custom_res) { if (!force_res) { - window_size.width = GLOBAL_GET("display/window/size/width"); - window_size.height = GLOBAL_GET("display/window/size/height"); - - if (globals->has_setting("display/window/size/test_width") && - globals->has_setting("display/window/size/test_height")) { - int tw = globals->get("display/window/size/test_width"); - if (tw > 0) { - window_size.width = tw; + window_size.width = GLOBAL_GET("display/window/size/viewport_width"); + window_size.height = GLOBAL_GET("display/window/size/viewport_height"); + + if (globals->has_setting("display/window/size/window_width_override") && + globals->has_setting("display/window/size/window_height_override")) { + int desired_width = globals->get("display/window/size/window_width_override"); + if (desired_width > 0) { + window_size.width = desired_width; } - int th = globals->get("display/window/size/test_height"); - if (th > 0) { - window_size.height = th; + int desired_height = globals->get("display/window/size/window_height_override"); + if (desired_height > 0) { + window_size.height = desired_height; } } } @@ -2348,8 +2348,8 @@ bool Main::start() { String stretch_mode = GLOBAL_DEF_BASIC("display/window/stretch/mode", "disabled"); String stretch_aspect = GLOBAL_DEF_BASIC("display/window/stretch/aspect", "keep"); - Size2i stretch_size = Size2i(GLOBAL_DEF_BASIC("display/window/size/width", 0), - GLOBAL_DEF_BASIC("display/window/size/height", 0)); + Size2i stretch_size = Size2i(GLOBAL_DEF_BASIC("display/window/size/viewport_width", 0), + GLOBAL_DEF_BASIC("display/window/size/viewport_height", 0)); real_t stretch_scale = GLOBAL_DEF_BASIC("display/window/stretch/scale", 1.0); Window::ContentScaleMode cs_sm = Window::CONTENT_SCALE_MODE_DISABLED; diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index aa44183329..78155fbef3 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -1514,7 +1514,7 @@ String EditorExportPlatformAndroid::load_splash_refs(Ref<Image> &splash_image, R } if (scale_splash) { - Size2 screen_size = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); + Size2 screen_size = Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height")); int width, height; if (screen_size.width > screen_size.height) { // scale horizontally diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index f4c0665f36..e8dfaf9c2e 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -530,7 +530,7 @@ Point2 Camera2D::get_camera_screen_center() const { Size2 Camera2D::_get_camera_screen_size() const { // special case if the camera2D is in the root viewport if (Engine::get_singleton()->is_editor_hint() && get_viewport()->get_parent_viewport() == get_tree()->get_root()) { - return Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); + return Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height")); } return get_viewport_rect().size; } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 69e6d74292..11d7946866 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1306,7 +1306,7 @@ Rect2 Control::get_parent_anchorable_rect() const { #ifdef TOOLS_ENABLED Node *edited_root = get_tree()->get_edited_scene_root(); if (edited_root && (this == edited_root || edited_root->is_ancestor_of(this))) { - parent_rect.size = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height")); + parent_rect.size = Size2(ProjectSettings::get_singleton()->get("display/window/size/viewport_width"), ProjectSettings::get_singleton()->get("display/window/size/viewport_height")); } else { parent_rect = get_viewport()->get_visible_rect(); } diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp index b0629de2f0..78e81eac0b 100644 --- a/servers/rendering/shader_compiler.cpp +++ b/servers/rendering/shader_compiler.cpp @@ -832,16 +832,49 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene } else { declaration += _prestr(vdnode->precision) + _typestr(vdnode->datatype); } + declaration += " "; for (int i = 0; i < vdnode->declarations.size(); i++) { + bool is_array = vdnode->declarations[i].size > 0; if (i > 0) { declaration += ","; - } else { - declaration += " "; } declaration += _mkid(vdnode->declarations[i].name); - if (vdnode->declarations[i].initializer) { - declaration += "="; - declaration += _dump_node_code(vdnode->declarations[i].initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + if (is_array) { + declaration += "["; + if (vdnode->declarations[i].size_expression != nullptr) { + declaration += _dump_node_code(vdnode->declarations[i].size_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + } else { + declaration += itos(vdnode->declarations[i].size); + } + declaration += "]"; + } + + if (!is_array || vdnode->declarations[i].single_expression) { + if (!vdnode->declarations[i].initializer.is_empty()) { + declaration += "="; + declaration += _dump_node_code(vdnode->declarations[i].initializer[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + } + } else { + int size = vdnode->declarations[i].initializer.size(); + if (size > 0) { + declaration += "="; + if (vdnode->datatype == SL::TYPE_STRUCT) { + declaration += _mkid(vdnode->struct_name); + } else { + declaration += _typestr(vdnode->datatype); + } + declaration += "["; + declaration += itos(size); + declaration += "]"; + declaration += "("; + for (int j = 0; j < size; j++) { + if (j > 0) { + declaration += ","; + } + declaration += _dump_node_code(vdnode->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + } + declaration += ")"; + } } } @@ -943,58 +976,6 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene } code += ")"; } break; - case SL::Node::TYPE_ARRAY_DECLARATION: { - SL::ArrayDeclarationNode *adnode = (SL::ArrayDeclarationNode *)p_node; - String declaration; - declaration += _constr(adnode->is_const); - if (adnode->datatype == SL::TYPE_STRUCT) { - declaration += _mkid(adnode->struct_name); - } else { - declaration += _prestr(adnode->precision) + _typestr(adnode->datatype); - } - for (int i = 0; i < adnode->declarations.size(); i++) { - if (i > 0) { - declaration += ","; - } else { - declaration += " "; - } - declaration += _mkid(adnode->declarations[i].name); - declaration += "["; - if (adnode->size_expression != nullptr) { - declaration += _dump_node_code(adnode->size_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - } else { - declaration += itos(adnode->declarations[i].size); - } - declaration += "]"; - if (adnode->declarations[i].single_expression) { - declaration += "="; - declaration += _dump_node_code(adnode->declarations[i].initializer[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - } else { - int sz = adnode->declarations[i].initializer.size(); - if (sz > 0) { - declaration += "="; - if (adnode->datatype == SL::TYPE_STRUCT) { - declaration += _mkid(adnode->struct_name); - } else { - declaration += _typestr(adnode->datatype); - } - declaration += "["; - declaration += itos(sz); - declaration += "]"; - declaration += "("; - for (int j = 0; j < sz; j++) { - declaration += _dump_node_code(adnode->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - if (j != sz - 1) { - declaration += ", "; - } - } - declaration += ")"; - } - } - } - - code += declaration; - } break; case SL::Node::TYPE_ARRAY: { SL::ArrayNode *anode = (SL::ArrayNode *)p_node; bool use_fragment_varying = false; diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 7641943fe9..bb6cfd7b03 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -6428,17 +6428,23 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun return ERR_PARSE_ERROR; } - Node *vardecl = nullptr; int array_size = 0; bool fixed_array_size = false; bool first = true; + VariableDeclarationNode *vdnode = alloc_node<VariableDeclarationNode>(); + vdnode->precision = precision; + if (is_struct) { + vdnode->struct_name = struct_name; + vdnode->datatype = TYPE_STRUCT; + } else { + vdnode->datatype = type; + }; + vdnode->is_const = is_const; + do { bool unknown_size = false; - Node *size_expr = nullptr; - - ArrayDeclarationNode *anode = nullptr; - ArrayDeclarationNode::Declaration adecl; + VariableDeclarationNode::Declaration decl; tk = _get_token(); @@ -6451,12 +6457,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } if (tk.type == TK_BRACKET_OPEN) { - Error error = _parse_array_size(p_block, p_function_info, false, &size_expr, &array_size, &unknown_size); + Error error = _parse_array_size(p_block, p_function_info, false, &decl.size_expression, &array_size, &unknown_size); if (error != OK) { return error; } - adecl.single_expression = false; - adecl.size = array_size; + decl.size = array_size; fixed_array_size = true; tk = _get_token(); @@ -6476,8 +6481,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun return ERR_PARSE_ERROR; } } - - adecl.name = name; + decl.name = name; #ifdef DEBUG_ENABLED if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG)) { @@ -6503,45 +6507,24 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun tk = _get_token(); - bool is_array_decl = var.array_size > 0 || unknown_size; - if (tk.type == TK_BRACKET_OPEN) { if (RenderingServer::get_singleton()->is_low_end() && is_const) { _set_error("Local const arrays are supported only on high-end platform!"); return ERR_PARSE_ERROR; } - Error error = _parse_array_size(p_block, p_function_info, false, &size_expr, &var.array_size, &unknown_size); + Error error = _parse_array_size(p_block, p_function_info, false, &decl.size_expression, &var.array_size, &unknown_size); if (error != OK) { return error; } - adecl.single_expression = false; - adecl.size = var.array_size; + decl.size = var.array_size; array_size = var.array_size; - is_array_decl = true; tk = _get_token(); } - if (is_array_decl) { - { - anode = alloc_node<ArrayDeclarationNode>(); - - if (is_struct) { - anode->struct_name = struct_name; - anode->datatype = TYPE_STRUCT; - } else { - anode->datatype = type; - } - - anode->precision = precision; - anode->is_const = is_const; - anode->size_expression = size_expr; - - vardecl = (Node *)anode; - } - + if (var.array_size > 0 || unknown_size) { bool full_def = false; if (tk.type == TK_OP_ASSIGN) { @@ -6562,7 +6545,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun return ERR_PARSE_ERROR; } else { if (unknown_size) { - adecl.size = n->get_array_size(); + decl.size = n->get_array_size(); var.array_size = n->get_array_size(); } @@ -6570,8 +6553,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun return ERR_PARSE_ERROR; } - adecl.single_expression = true; - adecl.initializer.push_back(n); + decl.single_expression = true; + decl.initializer.push_back(n); } tk = _get_token(); @@ -6685,7 +6668,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun return ERR_PARSE_ERROR; } - if (anode->is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) { + if (is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) { _set_error("Expected constant expression"); return ERR_PARSE_ERROR; } @@ -6696,13 +6679,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun tk = _get_token(); if (tk.type == TK_COMMA) { - adecl.initializer.push_back(n); + decl.initializer.push_back(n); continue; } else if (!curly && tk.type == TK_PARENTHESIS_CLOSE) { - adecl.initializer.push_back(n); + decl.initializer.push_back(n); break; } else if (curly && tk.type == TK_CURLY_BRACKET_CLOSE) { - adecl.initializer.push_back(n); + decl.initializer.push_back(n); break; } else { if (curly) { @@ -6714,9 +6697,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } } if (unknown_size) { - adecl.size = adecl.initializer.size(); - var.array_size = adecl.initializer.size(); - } else if (adecl.initializer.size() != var.array_size) { + decl.size = decl.initializer.size(); + var.array_size = decl.initializer.size(); + } else if (decl.initializer.size() != var.array_size) { _set_error("Array size mismatch"); return ERR_PARSE_ERROR; } @@ -6728,36 +6711,20 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun _set_error("Expected array initialization"); return ERR_PARSE_ERROR; } - if (anode->is_const) { + if (is_const) { _set_error("Expected initialization of constant"); return ERR_PARSE_ERROR; } } array_size = var.array_size; - anode->declarations.push_back(adecl); } else if (tk.type == TK_OP_ASSIGN) { - VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>(); - if (is_struct) { - node->struct_name = struct_name; - node->datatype = TYPE_STRUCT; - } else { - node->datatype = type; - } - node->precision = precision; - node->is_const = is_const; - vardecl = (Node *)node; - - VariableDeclarationNode::Declaration decl; - decl.name = name; - decl.initializer = nullptr; - //variable created with assignment! must parse an expression Node *n = _parse_and_reduce_expression(p_block, p_function_info); if (!n) { return ERR_PARSE_ERROR; } - if (node->is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) { + if (is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) { OperatorNode *op = ((OperatorNode *)n); for (int i = 1; i < op->arguments.size(); i++) { if (!_check_node_constness(op->arguments[i])) { @@ -6766,7 +6733,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } } } - decl.initializer = n; if (n->type == Node::TYPE_CONSTANT) { ConstantNode *const_node = static_cast<ConstantNode *>(n); @@ -6778,31 +6744,17 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun if (!_compare_datatypes(var.type, var.struct_name, var.array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) { return ERR_PARSE_ERROR; } + + decl.initializer.push_back(n); tk = _get_token(); - node->declarations.push_back(decl); } else { if (is_const) { _set_error("Expected initialization of constant"); return ERR_PARSE_ERROR; } - - VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>(); - if (is_struct) { - node->struct_name = struct_name; - node->datatype = TYPE_STRUCT; - } else { - node->datatype = type; - } - node->precision = precision; - vardecl = (Node *)node; - - VariableDeclarationNode::Declaration decl; - decl.name = name; - decl.initializer = nullptr; - node->declarations.push_back(decl); } - p_block->statements.push_back(vardecl); + vdnode->declarations.push_back(decl); p_block->variables[name] = var; if (!fixed_array_size) { @@ -6821,6 +6773,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun return ERR_PARSE_ERROR; } } while (tk.type == TK_COMMA); //another variable + + p_block->statements.push_back((Node *)vdnode); } else if (tk.type == TK_CURLY_BRACKET_OPEN) { //a sub block, just because.. BlockNode *block = alloc_node<BlockNode>(); @@ -8337,7 +8291,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct if (constant.array_size > 0 || unknown_size) { bool full_def = false; - ArrayDeclarationNode::Declaration decl; + VariableDeclarationNode::Declaration decl; decl.name = name; decl.size = constant.array_size; diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 74f97319fe..c619934182 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -362,7 +362,6 @@ public: TYPE_CONTROL_FLOW, TYPE_MEMBER, TYPE_ARRAY, - TYPE_ARRAY_DECLARATION, TYPE_ARRAY_CONSTRUCT, TYPE_STRUCT, }; @@ -428,7 +427,10 @@ public: struct Declaration { StringName name; - Node *initializer; + uint32_t size = 0U; + Node *size_expression = nullptr; + Vector<Node *> initializer; + bool single_expression = false; }; Vector<Declaration> declarations; @@ -471,27 +473,6 @@ public: Node(TYPE_ARRAY_CONSTRUCT) {} }; - struct ArrayDeclarationNode : public Node { - DataPrecision precision = PRECISION_DEFAULT; - DataType datatype = TYPE_VOID; - String struct_name; - bool is_const = false; - Node *size_expression = nullptr; - - struct Declaration { - StringName name; - uint32_t size; - Vector<Node *> initializer; - bool single_expression; - }; - Vector<Declaration> declarations; - - virtual DataType get_datatype() const override { return datatype; } - - ArrayDeclarationNode() : - Node(TYPE_ARRAY_DECLARATION) {} - }; - struct ConstantNode : public Node { DataType datatype = TYPE_VOID; String struct_name = ""; @@ -505,7 +486,7 @@ public: }; Vector<Value> values; - Vector<ArrayDeclarationNode::Declaration> array_declarations; + Vector<VariableDeclarationNode::Declaration> array_declarations; virtual DataType get_datatype() const override { return datatype; } virtual String get_datatype_name() const override { return struct_name; } diff --git a/tests/core/templates/test_vector.h b/tests/core/templates/test_vector.h index 24b3547256..f27d6a332e 100644 --- a/tests/core/templates/test_vector.h +++ b/tests/core/templates/test_vector.h @@ -257,27 +257,42 @@ TEST_CASE("[Vector] Slice") { vector.push_back(3); vector.push_back(4); + Vector<int> slice0 = vector.slice(0, 0); + CHECK(slice0.size() == 0); + Vector<int> slice1 = vector.slice(1, 3); CHECK(slice1.size() == 2); CHECK(slice1[0] == 1); CHECK(slice1[1] == 2); Vector<int> slice2 = vector.slice(1, -1); - CHECK(slice2.size() == 4); + CHECK(slice2.size() == 3); CHECK(slice2[0] == 1); CHECK(slice2[1] == 2); CHECK(slice2[2] == 3); - CHECK(slice2[3] == 4); - Vector<int> slice3 = vector.slice(3, -1); + Vector<int> slice3 = vector.slice(3); CHECK(slice3.size() == 2); CHECK(slice3[0] == 3); CHECK(slice3[1] == 4); Vector<int> slice4 = vector.slice(2, -2); - CHECK(slice4.size() == 2); + CHECK(slice4.size() == 1); CHECK(slice4[0] == 2); - CHECK(slice4[1] == 3); + + Vector<int> slice5 = vector.slice(-2); + CHECK(slice5.size() == 2); + CHECK(slice5[0] == 3); + CHECK(slice5[1] == 4); + + Vector<int> slice6 = vector.slice(2, 42); + CHECK(slice6.size() == 3); + CHECK(slice6[0] == 2); + CHECK(slice6[1] == 3); + CHECK(slice6[2] == 4); + + Vector<int> slice7 = vector.slice(5, 1); + CHECK(slice7.size() == 0); } TEST_CASE("[Vector] Find, has") { diff --git a/tests/core/variant/test_array.h b/tests/core/variant/test_array.h index 205e34daea..6093048307 100644 --- a/tests/core/variant/test_array.h +++ b/tests/core/variant/test_array.h @@ -254,27 +254,52 @@ TEST_CASE("[Array] slice()") { array.push_back(3); array.push_back(4); + Array slice0 = array.slice(0, 0); + CHECK(slice0.size() == 0); + Array slice1 = array.slice(1, 3); CHECK(slice1.size() == 2); CHECK(slice1[0] == Variant(1)); CHECK(slice1[1] == Variant(2)); Array slice2 = array.slice(1, -1); - CHECK(slice2.size() == 4); + CHECK(slice2.size() == 3); CHECK(slice2[0] == Variant(1)); CHECK(slice2[1] == Variant(2)); CHECK(slice2[2] == Variant(3)); - CHECK(slice2[3] == Variant(4)); - Array slice3 = array.slice(3, -1); + Array slice3 = array.slice(3); CHECK(slice3.size() == 2); CHECK(slice3[0] == Variant(3)); CHECK(slice3[1] == Variant(4)); Array slice4 = array.slice(2, -2); - CHECK(slice4.size() == 2); + CHECK(slice4.size() == 1); CHECK(slice4[0] == Variant(2)); - CHECK(slice4[1] == Variant(3)); + + Array slice5 = array.slice(-2); + CHECK(slice5.size() == 2); + CHECK(slice5[0] == Variant(3)); + CHECK(slice5[1] == Variant(4)); + + Array slice6 = array.slice(2, 42); + CHECK(slice6.size() == 3); + CHECK(slice6[0] == Variant(2)); + CHECK(slice6[1] == Variant(3)); + CHECK(slice6[2] == Variant(4)); + + Array slice7 = array.slice(4, 0, -2); + CHECK(slice7.size() == 2); + CHECK(slice7[0] == Variant(4)); + CHECK(slice7[1] == Variant(2)); + + ERR_PRINT_OFF; + Array slice8 = array.slice(4, 1); + CHECK(slice8.size() == 0); + + Array slice9 = array.slice(3, -4); + CHECK(slice9.size() == 0); + ERR_PRINT_ON; } TEST_CASE("[Array] Duplicate array") { diff --git a/tests/servers/test_shader_lang.cpp b/tests/servers/test_shader_lang.cpp index acc7e32441..06e28212d2 100644 --- a/tests/servers/test_shader_lang.cpp +++ b/tests/servers/test_shader_lang.cpp @@ -211,9 +211,6 @@ static String dump_node_code(SL::Node *p_node, int p_level) { SL::ArrayNode *vnode = (SL::ArrayNode *)p_node; code = vnode->name; } break; - case SL::Node::TYPE_ARRAY_DECLARATION: { - // FIXME: Implement - } break; case SL::Node::TYPE_ARRAY_CONSTRUCT: { // FIXME: Implement } break; |