Skip to content

Commit

Permalink
Merge pull request #58234 from akien-mga/3.4-cherrypicks
Browse files Browse the repository at this point in the history
  • Loading branch information
akien-mga committed Feb 17, 2022
2 parents 1891c8e + 46037af commit 0ea54d0
Show file tree
Hide file tree
Showing 128 changed files with 413 additions and 188 deletions.
8 changes: 5 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,10 @@ understand that:

To speed up our work, **please upload a minimal project** that isolates
and reproduces the issue. This is always the **best way for us to fix it**.
You can attach a ZIP file with the minimal project directly to the bug report,
by drag and dropping the file in the GitHub edition field.
We recommend attaching a ZIP file with the minimal project directly to the bug report,
by drag and dropping the file in the GitHub edition field. This ensures the file
can remain available for a long period of time. Only use third-party file hosts
if your ZIP file isn't accepted by GitHub because it's too large.

We recommend always attaching a minimal reproduction project, even if the issue
may seem simple to reproduce manually.
Expand All @@ -79,7 +81,7 @@ it'll be considered too difficult to diagnose.
Now that you've read the guidelines, click the link below to create a
bug report:

- **[Report a bug](https://github.com/godotengine/godot/issues/new?assignees=&labels=&template=bug_report.md&title=)**
- **[Report a bug](https://github.com/godotengine/godot/issues/new?assignees=&labels=&template=bug_report.yml)**

## Proposing features or improvements

Expand Down
14 changes: 13 additions & 1 deletion SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,9 @@ opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursi

# Advanced options
opts.Add(BoolVariable("dev", "If yes, alias for verbose=yes warnings=extra werror=yes", False))
opts.Add(BoolVariable("progress", "Show a progress indicator during compilation", True))
opts.Add(BoolVariable("fast_unsafe", "Enable unsafe options for faster rebuilds", False))
opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))
opts.Add(BoolVariable("progress", "Show a progress indicator during compilation", True))
opts.Add(EnumVariable("warnings", "Level of compilation warnings", "all", ("extra", "all", "moderate", "no")))
opts.Add(BoolVariable("werror", "Treat compiler warnings as errors", False))
opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all generated binary files", "")
Expand Down Expand Up @@ -308,6 +309,17 @@ if env_base["target"] == "debug":
# working on the engine itself.
env_base.Append(CPPDEFINES=["DEV_ENABLED"])

# SCons speed optimization controlled by the `fast_unsafe` option, which provide
# more than 10 s speed up for incremental rebuilds.
# Unsafe as they reduce the certainty of rebuilding all changed files, so it's
# enabled by default for `debug` builds, and can be overridden from command line.
# Ref: https://github.com/SCons/scons/wiki/GoFastButton
if methods.get_cmdline_bool("fast_unsafe", env_base["target"] == "debug"):
# Renamed to `content-timestamp` in SCons >= 4.2, keeping MD5 for compat.
env_base.Decider("MD5-timestamp")
env_base.SetOption("implicit_cache", 1)
env_base.SetOption("max_drift", 60)

if env_base["use_precise_math_checks"]:
env_base.Append(CPPDEFINES=["PRECISE_MATH_CHECKS"])

Expand Down
4 changes: 4 additions & 0 deletions core/error_macros.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool fatal) {
_err_print_index_error(p_function, p_file, p_line, p_index, p_size, p_index_str, p_size_str, p_message.utf8().get_data(), fatal);
}

void _err_flush_stdout() {
fflush(stdout);
}
4 changes: 4 additions & 0 deletions core/error_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co
void _err_print_error(const char *p_function, const char *p_file, int p_line, const String &p_error, const String &p_message, ErrorHandlerType p_type = ERR_HANDLER_ERROR);
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message = "", bool fatal = false);
void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const String &p_message, bool fatal = false);
void _err_flush_stdout();

#ifndef _STR
#define _STR(m_x) #m_x
Expand Down Expand Up @@ -426,6 +427,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
#define CRASH_NOW() \
if (true) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method failed."); \
void _err_flush_stdout(); \
GENERATE_TRAP \
} else \
((void)0)
Expand All @@ -437,6 +439,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
#define CRASH_NOW_MSG(m_msg) \
if (true) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method failed.", m_msg); \
void _err_flush_stdout(); \
GENERATE_TRAP \
} else \
((void)0)
Expand Down Expand Up @@ -520,6 +523,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
#define DEV_ASSERT(m_cond) \
if (unlikely(!(m_cond))) { \
_err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: DEV_ASSERT failed \"" _STR(m_cond) "\" is false."); \
void _err_flush_stdout(); \
GENERATE_TRAP \
} else \
((void)0)
Expand Down
11 changes: 6 additions & 5 deletions core/io/marshalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r
return OK;
}

Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_objects) {
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_objects, int p_depth) {
ERR_FAIL_COND_V_MSG(p_depth > Variant::MAX_RECURSION_DEPTH, ERR_OUT_OF_MEMORY, "Variant is too deep. Bailing.");
const uint8_t *buf = p_buffer;
int len = p_len;

Expand Down Expand Up @@ -430,7 +431,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int

Variant value;
int used;
err = decode_variant(value, buf, len, &used, p_allow_objects);
err = decode_variant(value, buf, len, &used, p_allow_objects, p_depth + 1);
if (err) {
return err;
}
Expand Down Expand Up @@ -473,7 +474,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
Variant key, value;

int used;
Error err = decode_variant(key, buf, len, &used, p_allow_objects);
Error err = decode_variant(key, buf, len, &used, p_allow_objects, p_depth + 1);
ERR_FAIL_COND_V_MSG(err != OK, err, "Error when trying to decode Variant.");

buf += used;
Expand All @@ -482,7 +483,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
(*r_len) += used;
}

err = decode_variant(value, buf, len, &used, p_allow_objects);
err = decode_variant(value, buf, len, &used, p_allow_objects, p_depth + 1);
ERR_FAIL_COND_V_MSG(err != OK, err, "Error when trying to decode Variant.");

buf += used;
Expand Down Expand Up @@ -515,7 +516,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
for (int i = 0; i < count; i++) {
int used = 0;
Variant v;
Error err = decode_variant(v, buf, len, &used, p_allow_objects);
Error err = decode_variant(v, buf, len, &used, p_allow_objects, p_depth + 1);
ERR_FAIL_COND_V_MSG(err != OK, err, "Error when trying to decode Variant.");
buf += used;
len -= used;
Expand Down
2 changes: 1 addition & 1 deletion core/io/marshalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ class EncodedObjectAsID : public Reference {
EncodedObjectAsID();
};

Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = nullptr, bool p_allow_objects = false);
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = nullptr, bool p_allow_objects = false, int p_depth = 0);
Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects = false, int p_depth = 0);

#endif
18 changes: 15 additions & 3 deletions core/math/bvh_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ class BVH_Tree {
change_root_node(sibling_id, p_tree_id);

// delete the old root node as no longer needed
_nodes.free(p_parent_id);
node_free_node_and_leaf(p_parent_id);
}

return;
Expand All @@ -257,7 +257,19 @@ class BVH_Tree {
}

// put the node on the free list to recycle
_nodes.free(p_parent_id);
node_free_node_and_leaf(p_parent_id);
}

// A node can either be a node, or a node AND a leaf combo.
// Both must be deleted to prevent a leak.
void node_free_node_and_leaf(uint32_t p_node_id) {
TNode &node = _nodes[p_node_id];
if (node.is_leaf()) {
int leaf_id = node.get_leaf_id();
_leaves.free(leaf_id);
}

_nodes.free(p_node_id);
}

void change_root_node(uint32_t p_new_root_id, uint32_t p_tree_id) {
Expand Down Expand Up @@ -349,7 +361,7 @@ class BVH_Tree {
refit_upward(parent_id);

// put the node on the free list to recycle
_nodes.free(owner_node_id);
node_free_node_and_leaf(owner_node_id);
}

// else if no parent, it is the root node. Do not delete
Expand Down
52 changes: 45 additions & 7 deletions core/math/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,14 @@ static bool _is_number(CharType c) {
return (c >= '0' && c <= '9');
}

static bool _is_hex_digit(char32_t c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}

static bool _is_binary_digit(char32_t c) {
return (c == '0' || c == '1');
}

Error Expression::_get_token(Token &r_token) {
while (true) {
#define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++])
Expand Down Expand Up @@ -1011,30 +1019,58 @@ Error Expression::_get_token(Token &r_token) {
String num;
#define READING_SIGN 0
#define READING_INT 1
#define READING_DEC 2
#define READING_EXP 3
#define READING_DONE 4
#define READING_HEX 2
#define READING_BIN 3
#define READING_DEC 4
#define READING_EXP 5
#define READING_DONE 6
int reading = READING_INT;

CharType c = cchar;
bool exp_sign = false;
bool exp_beg = false;
bool bin_beg = false;
bool hex_beg = false;
bool is_float = false;
bool is_first_char = true;

while (true) {
switch (reading) {
case READING_INT: {
if (_is_number(c)) {
//pass
if (is_first_char && c == '0') {
if (next_char == 'b') {
reading = READING_BIN;
} else if (next_char == 'x') {
reading = READING_HEX;
}
}
} else if (c == '.') {
reading = READING_DEC;
is_float = true;
} else if (c == 'e') {
reading = READING_EXP;
is_float = true;
} else {
reading = READING_DONE;
}

} break;
case READING_BIN: {
if (bin_beg && !_is_binary_digit(c)) {
reading = READING_DONE;
} else if (c == 'b') {
bin_beg = true;
}

} break;
case READING_HEX: {
if (hex_beg && !_is_hex_digit(c)) {
reading = READING_DONE;
} else if (c == 'x') {
hex_beg = true;
}

} break;
case READING_DEC: {
if (_is_number(c)) {
Expand All @@ -1051,9 +1087,6 @@ Error Expression::_get_token(Token &r_token) {
exp_beg = true;

} else if ((c == '-' || c == '+') && !exp_sign && !exp_beg) {
if (c == '-') {
is_float = true;
}
exp_sign = true;

} else {
Expand All @@ -1067,6 +1100,7 @@ Error Expression::_get_token(Token &r_token) {
}
num += String::chr(c);
c = GET_CHAR();
is_first_char = false;
}

str_ofs--;
Expand All @@ -1075,6 +1109,10 @@ Error Expression::_get_token(Token &r_token) {

if (is_float) {
r_token.value = num.to_double();
} else if (bin_beg) {
r_token.value = num.bin_to_int64();
} else if (hex_beg) {
r_token.value = num.hex_to_int64();
} else {
r_token.value = num.to_int64();
}
Expand Down
6 changes: 5 additions & 1 deletion core/project_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,11 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
bool ProjectSettings::has_setting(String p_var) const {
_THREAD_SAFE_METHOD_

return props.has(p_var);
StringName name = p_var;
if (!disable_feature_overrides && feature_overrides.has(name)) {
name = feature_overrides[name];
}
return props.has(name);
}

void ProjectSettings::set_registering_order(bool p_enable) {
Expand Down
8 changes: 4 additions & 4 deletions core/variant_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -652,17 +652,17 @@ struct _VariantCall {

static void _call_PoolByteArray_decompress_dynamic(Variant &r_ret, Variant &p_self, const Variant **p_args) {
PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem);
PoolByteArray *decompressed = memnew(PoolByteArray);
PoolByteArray decompressed;
int max_output_size = (int)(*p_args[0]);
Compression::Mode mode = (Compression::Mode)(int)(*p_args[1]);

decompressed->resize(1024);
int result = Compression::decompress_dynamic(decompressed, max_output_size, ba->read().ptr(), ba->size(), mode);
decompressed.resize(1024);
int result = Compression::decompress_dynamic(&decompressed, max_output_size, ba->read().ptr(), ba->size(), mode);

if (result == OK) {
r_ret = decompressed;
} else {
decompressed->resize(0);
decompressed.resize(0);
r_ret = decompressed;
ERR_FAIL_MSG("Decompression failed.");
}
Expand Down
4 changes: 2 additions & 2 deletions doc/classes/Array.xml
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@
<method name="hash">
<return type="int" />
<description>
Returns a hashed integer value representing the array and its contents.
[b]Note:[/b] Arrays with equal contents can still produce different hashes. Only the exact same arrays will produce the same hashed integer value.
Returns a hashed 32-bit integer value representing the array and its contents.
[b]Note:[/b] [Array]s with equal content will always produce identical hash values. However, the reverse is not true. Returning identical hash values does [i]not[/i] imply the arrays are equal, because different arrays can have identical hash values due to hash collisions.
</description>
</method>
<method name="insert">
Expand Down
6 changes: 3 additions & 3 deletions doc/classes/AudioServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<method name="capture_get_device">
<return type="String" />
<description>
Name of the current device for audio input (see [method capture_get_device_list]).
Name of the current device for audio input (see [method capture_get_device_list]). The value [code]"Default"[/code] means that the system-wide default audio input is currently used.
</description>
</method>
<method name="capture_get_device_list">
Expand All @@ -45,7 +45,7 @@
<return type="void" />
<argument index="0" name="name" type="String" />
<description>
Sets which audio input device is used for audio capture.
Sets which audio input device is used for audio capture. On systems with multiple audio inputs (such as analog and USB), this can be used to select the audio input device. Setting the value [code]"Default"[/code] will record audio from the system-wide default audio input. If an invalid device name is set, the value will be reverted back to [code]"Default"[/code].
</description>
</method>
<method name="generate_bus_layout" qualifiers="const">
Expand Down Expand Up @@ -309,7 +309,7 @@
Number of available audio buses.
</member>
<member name="device" type="String" setter="set_device" getter="get_device" default="&quot;Default&quot;">
Name of the current device for audio output (see [method get_device_list]).
Name of the current device for audio output (see [method get_device_list]). On systems with multiple audio outputs (such as analog, USB and HDMI audio), this can be used to select the audio output device. The value [code]"Default"[/code] will play audio on the system-wide default audio output. If an invalid device name is set, the value will be reverted back to [code]"Default"[/code].
</member>
<member name="global_rate_scale" type="float" setter="set_global_rate_scale" getter="get_global_rate_scale" default="1.0">
Scales the rate at which audio is played (i.e. setting it to [code]0.5[/code] will make the audio be played twice as fast).
Expand Down
2 changes: 1 addition & 1 deletion doc/classes/AudioStreamPlayer2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
</methods>
<members>
<member name="area_mask" type="int" setter="set_area_mask" getter="get_area_mask" default="1">
Areas in which this sound plays.
Determines which [Area2D] layers affect the sound for reverb and audio bus effects. Areas can be used to redirect [AudioStream]s so that they play in a certain audio bus. An example of how you might use this is making a "water" area so that sounds played in the water are redirected through an audio bus to make them sound like they are being played underwater.
</member>
<member name="attenuation" type="float" setter="set_attenuation" getter="get_attenuation" default="1.0">
Dampens audio over distance with this as an exponent.
Expand Down
2 changes: 1 addition & 1 deletion doc/classes/AudioStreamPlayer3D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
</methods>
<members>
<member name="area_mask" type="int" setter="set_area_mask" getter="get_area_mask" default="1">
Areas in which this sound plays.
Determines which [Area] layers affect the sound for reverb and audio bus effects. Areas can be used to redirect [AudioStream]s so that they play in a certain audio bus. An example of how you might use this is making a "water" area so that sounds played in the water are redirected through an audio bus to make them sound like they are being played underwater.
</member>
<member name="attenuation_filter_cutoff_hz" type="float" setter="set_attenuation_filter_cutoff_hz" getter="get_attenuation_filter_cutoff_hz" default="5000.0">
Dampens audio using a low-pass filter above this frequency, in Hz. To disable the dampening effect entirely, set this to [code]20500[/code] as this frequency is above the human hearing limit.
Expand Down
3 changes: 2 additions & 1 deletion doc/classes/Dictionary.xml
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,15 @@
<method name="hash">
<return type="int" />
<description>
Returns a hashed integer value representing the dictionary contents. This can be used to compare dictionaries by value:
Returns a hashed 32-bit integer value representing the dictionary contents. This can be used to compare dictionaries by value:
[codeblock]
var dict1 = {0: 10}
var dict2 = {0: 10}
# The line below prints `true`, whereas it would have printed `false` if both variables were compared directly.
print(dict1.hash() == dict2.hash())
[/codeblock]
[b]Note:[/b] Dictionaries with the same keys/values but in a different order will have a different hash.
[b]Note:[/b] Dictionaries with equal content will always produce identical hash values. However, the reverse is not true. Returning identical hash values does [i]not[/i] imply the dictionaries are equal, because different dictionaries can have identical hash values due to hash collisions.
</description>
</method>
<method name="keys">
Expand Down
Loading

0 comments on commit 0ea54d0

Please sign in to comment.