summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYRIGHT.txt2
-rw-r--r--core/core_constants.cpp41
-rw-r--r--core/input/input.cpp106
-rw-r--r--core/input/input.h5
-rw-r--r--core/input/input_event.h57
-rw-r--r--core/variant/variant_call.cpp27
-rw-r--r--core/variant/variant_internal.h22
-rw-r--r--core/variant/variant_setget.cpp106
-rw-r--r--doc/classes/@GlobalScope.xml141
-rw-r--r--doc/classes/Node.xml6
-rw-r--r--drivers/unix/net_socket_posix.cpp4
-rw-r--r--editor/editor_export.cpp10
-rw-r--r--editor/input_map_editor.cpp54
-rw-r--r--modules/visual_script/doc_classes/VisualScriptLists.xml2
-rw-r--r--platform/android/export/export.cpp58
-rw-r--r--platform/iphone/export/export.cpp13
-rw-r--r--platform/javascript/detect.py1
-rw-r--r--platform/javascript/export/export.cpp6
-rw-r--r--platform/linuxbsd/detect.py1
-rw-r--r--platform/osx/detect.py7
-rw-r--r--platform/server/detect.py1
-rw-r--r--platform/uwp/export/export.cpp6
-rw-r--r--platform/windows/detect.py7
-rw-r--r--scene/3d/soft_body_3d.cpp2
-rw-r--r--scene/main/timer.cpp4
-rw-r--r--tests/test_json.h166
-rw-r--r--tests/test_main.cpp7
-rw-r--r--tests/test_object.h92
-rw-r--r--tests/test_rect2.h467
-rw-r--r--thirdparty/README.md8
-rw-r--r--thirdparty/doctest/LICENSE.txt2
-rw-r--r--thirdparty/doctest/doctest.h337
-rw-r--r--thirdparty/doctest/patches/fix-arm64-mac.patch18
-rw-r--r--thirdparty/nanosvg/nanosvg.h81
34 files changed, 1157 insertions, 710 deletions
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index 31f51c2854..011514ef04 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -128,7 +128,7 @@ License: Expat
Files: ./thirdparty/doctest/
Comment: doctest
-Copyright: 2016-2019, Viktor Kirilov
+Copyright: 2016-2020, Viktor Kirilov
License: Expat
Files: ./thirdparty/enet/
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index 4229436e84..64bfff1c58 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -409,7 +409,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(BUTTON_MASK_XBUTTON2);
// Joypad buttons
- BIND_CORE_ENUM_CONSTANT(JOY_INVALID_BUTTON);
+ BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_INVALID);
BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_A);
BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_B);
BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_X);
@@ -425,51 +425,18 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_DOWN);
BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_LEFT);
BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_DPAD_RIGHT);
- BIND_CORE_ENUM_CONSTANT(JOY_SDL_BUTTONS);
- BIND_CORE_ENUM_CONSTANT(JOY_SONY_X);
- BIND_CORE_ENUM_CONSTANT(JOY_SONY_CROSS);
- BIND_CORE_ENUM_CONSTANT(JOY_SONY_CIRCLE);
- BIND_CORE_ENUM_CONSTANT(JOY_SONY_SQUARE);
- BIND_CORE_ENUM_CONSTANT(JOY_SONY_TRIANGLE);
- BIND_CORE_ENUM_CONSTANT(JOY_SONY_SELECT);
- BIND_CORE_ENUM_CONSTANT(JOY_SONY_START);
- BIND_CORE_ENUM_CONSTANT(JOY_SONY_PS);
- BIND_CORE_ENUM_CONSTANT(JOY_SONY_L1);
- BIND_CORE_ENUM_CONSTANT(JOY_SONY_R1);
- BIND_CORE_ENUM_CONSTANT(JOY_SONY_L3);
- BIND_CORE_ENUM_CONSTANT(JOY_SONY_R3);
- BIND_CORE_ENUM_CONSTANT(JOY_XBOX_A);
- BIND_CORE_ENUM_CONSTANT(JOY_XBOX_B);
- BIND_CORE_ENUM_CONSTANT(JOY_XBOX_X);
- BIND_CORE_ENUM_CONSTANT(JOY_XBOX_Y);
- BIND_CORE_ENUM_CONSTANT(JOY_XBOX_BACK);
- BIND_CORE_ENUM_CONSTANT(JOY_XBOX_START);
- BIND_CORE_ENUM_CONSTANT(JOY_XBOX_HOME);
- BIND_CORE_ENUM_CONSTANT(JOY_XBOX_LS);
- BIND_CORE_ENUM_CONSTANT(JOY_XBOX_RS);
- BIND_CORE_ENUM_CONSTANT(JOY_XBOX_LB);
- BIND_CORE_ENUM_CONSTANT(JOY_XBOX_RB);
+ BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_SDL_MAX);
BIND_CORE_ENUM_CONSTANT(JOY_BUTTON_MAX);
// Joypad axes
- BIND_CORE_ENUM_CONSTANT(JOY_INVALID_AXIS);
+ BIND_CORE_ENUM_CONSTANT(JOY_AXIS_INVALID);
BIND_CORE_ENUM_CONSTANT(JOY_AXIS_LEFT_X);
BIND_CORE_ENUM_CONSTANT(JOY_AXIS_LEFT_Y);
BIND_CORE_ENUM_CONSTANT(JOY_AXIS_RIGHT_X);
BIND_CORE_ENUM_CONSTANT(JOY_AXIS_RIGHT_Y);
BIND_CORE_ENUM_CONSTANT(JOY_AXIS_TRIGGER_LEFT);
BIND_CORE_ENUM_CONSTANT(JOY_AXIS_TRIGGER_RIGHT);
- BIND_CORE_ENUM_CONSTANT(JOY_SDL_AXES);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_0_X);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_0_Y);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_1_X);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_1_Y);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_2_X);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_2_Y);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_3_X);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_3_Y);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_4_X);
- BIND_CORE_ENUM_CONSTANT(JOY_AXIS_4_Y);
+ BIND_CORE_ENUM_CONSTANT(JOY_AXIS_SDL_MAX);
BIND_CORE_ENUM_CONSTANT(JOY_AXIS_MAX);
// midi
diff --git a/core/input/input.cpp b/core/input/input.cpp
index aa64ac09a7..00a7e63a73 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -39,7 +39,7 @@
#include "editor/editor_settings.h"
#endif
-static const char *_joy_buttons[JOY_SDL_BUTTONS + 1] = {
+static const char *_joy_buttons[JOY_BUTTON_SDL_MAX] = {
"a",
"b",
"x",
@@ -55,69 +55,15 @@ static const char *_joy_buttons[JOY_SDL_BUTTONS + 1] = {
"dpdown",
"dpleft",
"dpright",
- nullptr
};
-static const char *_joy_button_names[JOY_BUTTON_MAX] = {
- "Face Bottom",
- "Face Right",
- "Face Left",
- "Face Top",
- "Select",
- "Guide",
- "Start",
- "Left Stick",
- "Right Stick",
- "Left Shoulder",
- "Right Shoulder",
- "D-Pad Up",
- "D-Pad Down",
- "D-Pad Left",
- "D-Pad Right",
- "Button 15",
- "Button 16",
- "Button 17",
- "Button 18",
- "Button 19",
- "Button 20",
- "Button 21",
- "Button 22",
- "Button 23",
- "Button 24",
- "Button 25",
- "Button 26",
- "Button 27",
- "Button 28",
- "Button 29",
- "Button 30",
- "Button 31",
- "Button 32",
- "Button 33",
- "Button 34",
- "Button 35"
-};
-
-static const char *_joy_axes[JOY_SDL_AXES + 1] = {
+static const char *_joy_axes[JOY_AXIS_SDL_MAX] = {
"leftx",
"lefty",
"rightx",
"righty",
"lefttrigger",
"righttrigger",
- nullptr
-};
-
-static const char *_joy_axis_names[JOY_AXIS_MAX] = {
- "Left Stick X",
- "Left Stick Y",
- "Right Stick X",
- "Right Stick Y",
- "Left Trigger",
- "Right Trigger",
- "Joystick 3 Stick X",
- "Joystick 3 Stick Y",
- "Joystick 4 Stick X",
- "Joystick 4 Stick Y"
};
Input *Input::singleton = nullptr;
@@ -162,10 +108,6 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_connected_joypads"), &Input::get_connected_joypads);
ClassDB::bind_method(D_METHOD("get_joy_vibration_strength", "device"), &Input::get_joy_vibration_strength);
ClassDB::bind_method(D_METHOD("get_joy_vibration_duration", "device"), &Input::get_joy_vibration_duration);
- ClassDB::bind_method(D_METHOD("get_joy_button_string", "button_index"), &Input::get_joy_button_string);
- ClassDB::bind_method(D_METHOD("get_joy_button_index_from_string", "button"), &Input::get_joy_button_index_from_string);
- ClassDB::bind_method(D_METHOD("get_joy_axis_string", "axis_index"), &Input::get_joy_axis_string);
- ClassDB::bind_method(D_METHOD("get_joy_axis_index_from_string", "axis"), &Input::get_joy_axis_index_from_string);
ClassDB::bind_method(D_METHOD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &Input::start_joy_vibration, DEFVAL(0));
ClassDB::bind_method(D_METHOD("stop_joy_vibration", "device"), &Input::stop_joy_vibration);
ClassDB::bind_method(D_METHOD("vibrate_handheld", "duration_ms"), &Input::vibrate_handheld, DEFVAL(500));
@@ -1226,21 +1168,21 @@ void Input::_get_mapped_hat_events(const JoyDeviceMapping &mapping, int p_hat, J
}
JoyButtonList Input::_get_output_button(String output) {
- for (int i = 0; _joy_buttons[i]; i++) {
+ for (int i = 0; i < JOY_BUTTON_SDL_MAX; i++) {
if (output == _joy_buttons[i]) {
return JoyButtonList(i);
}
}
- return JoyButtonList::JOY_INVALID_BUTTON;
+ return JoyButtonList::JOY_BUTTON_INVALID;
}
JoyAxisList Input::_get_output_axis(String output) {
- for (int i = 0; _joy_axes[i]; i++) {
+ for (int i = 0; i < JOY_AXIS_SDL_MAX; i++) {
if (output == _joy_axes[i]) {
return JoyAxisList(i);
}
}
- return JoyAxisList::JOY_INVALID_AXIS;
+ return JoyAxisList::JOY_AXIS_INVALID;
}
void Input::parse_mapping(String p_mapping) {
@@ -1300,16 +1242,16 @@ void Input::parse_mapping(String p_mapping) {
JoyButtonList output_button = _get_output_button(output);
JoyAxisList output_axis = _get_output_axis(output);
- ERR_CONTINUE_MSG(output_button == JOY_INVALID_BUTTON && output_axis == JOY_INVALID_AXIS,
+ ERR_CONTINUE_MSG(output_button == JOY_BUTTON_INVALID && output_axis == JOY_AXIS_INVALID,
String(entry[idx] + "\nUnrecognised output string: " + output));
- ERR_CONTINUE_MSG(output_button != JOY_INVALID_BUTTON && output_axis != JOY_INVALID_AXIS,
+ ERR_CONTINUE_MSG(output_button != JOY_BUTTON_INVALID && output_axis != JOY_AXIS_INVALID,
String("BUG: Output string matched both button and axis: " + output));
JoyBinding binding;
- if (output_button != JOY_INVALID_BUTTON) {
+ if (output_button != JOY_BUTTON_INVALID) {
binding.outputType = TYPE_BUTTON;
binding.output.button = output_button;
- } else if (output_axis != JOY_INVALID_AXIS) {
+ } else if (output_axis != JOY_AXIS_INVALID) {
binding.outputType = TYPE_AXIS;
binding.output.axis.axis = output_axis;
binding.output.axis.range = output_range;
@@ -1401,20 +1343,6 @@ Array Input::get_connected_joypads() {
return ret;
}
-String Input::get_joy_button_string(int p_button) {
- ERR_FAIL_INDEX_V(p_button, JOY_BUTTON_MAX, "Invalid button");
- return _joy_button_names[p_button];
-}
-
-int Input::get_joy_button_index_from_string(String p_button) {
- for (int i = 0; i < JOY_BUTTON_MAX; i++) {
- if (p_button == _joy_button_names[i]) {
- return i;
- }
- }
- ERR_FAIL_V(JOY_INVALID_BUTTON);
-}
-
int Input::get_unused_joy_id() {
for (int i = 0; i < JOYPADS_MAX; i++) {
if (!joy_names.has(i) || !joy_names[i].connected) {
@@ -1424,20 +1352,6 @@ int Input::get_unused_joy_id() {
return -1;
}
-String Input::get_joy_axis_string(int p_axis) {
- ERR_FAIL_INDEX_V(p_axis, JOY_AXIS_MAX, "Invalid axis");
- return _joy_axis_names[p_axis];
-}
-
-int Input::get_joy_axis_index_from_string(String p_axis) {
- for (int i = 0; i < JOY_AXIS_MAX; i++) {
- if (p_axis == _joy_axis_names[i]) {
- return i;
- }
- }
- ERR_FAIL_V(JOY_INVALID_AXIS);
-}
-
Input::Input() {
singleton = this;
diff --git a/core/input/input.h b/core/input/input.h
index 46e9d24bf2..1b2df49ac0 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -330,11 +330,6 @@ public:
void add_joy_mapping(String p_mapping, bool p_update_existing = false);
void remove_joy_mapping(String p_guid);
- String get_joy_button_string(int p_button);
- String get_joy_axis_string(int p_axis);
- int get_joy_axis_index_from_string(String p_axis);
- int get_joy_button_index_from_string(String p_button);
-
int get_unused_joy_id();
bool is_joy_known(int p_device);
diff --git a/core/input/input_event.h b/core/input/input_event.h
index 52b785c9a1..0eae3a2bbe 100644
--- a/core/input/input_event.h
+++ b/core/input/input_event.h
@@ -60,9 +60,7 @@ enum ButtonList {
};
enum JoyButtonList {
- JOY_INVALID_BUTTON = -1,
-
- // SDL Buttons
+ JOY_BUTTON_INVALID = -1,
JOY_BUTTON_A = 0,
JOY_BUTTON_B = 1,
JOY_BUTTON_X = 2,
@@ -78,63 +76,20 @@ enum JoyButtonList {
JOY_BUTTON_DPAD_DOWN = 12,
JOY_BUTTON_DPAD_LEFT = 13,
JOY_BUTTON_DPAD_RIGHT = 14,
- JOY_SDL_BUTTONS = 15,
-
- // Sony Buttons
- JOY_SONY_X = JOY_BUTTON_A,
- JOY_SONY_CROSS = JOY_BUTTON_A,
- JOY_SONY_CIRCLE = JOY_BUTTON_B,
- JOY_SONY_SQUARE = JOY_BUTTON_X,
- JOY_SONY_TRIANGLE = JOY_BUTTON_Y,
- JOY_SONY_SELECT = JOY_BUTTON_BACK,
- JOY_SONY_START = JOY_BUTTON_START,
- JOY_SONY_PS = JOY_BUTTON_GUIDE,
- JOY_SONY_L1 = JOY_BUTTON_LEFT_SHOULDER,
- JOY_SONY_R1 = JOY_BUTTON_RIGHT_SHOULDER,
- JOY_SONY_L3 = JOY_BUTTON_LEFT_STICK,
- JOY_SONY_R3 = JOY_BUTTON_RIGHT_STICK,
-
- // Xbox Buttons
- JOY_XBOX_A = JOY_BUTTON_A,
- JOY_XBOX_B = JOY_BUTTON_B,
- JOY_XBOX_X = JOY_BUTTON_X,
- JOY_XBOX_Y = JOY_BUTTON_Y,
- JOY_XBOX_BACK = JOY_BUTTON_BACK,
- JOY_XBOX_START = JOY_BUTTON_START,
- JOY_XBOX_HOME = JOY_BUTTON_GUIDE,
- JOY_XBOX_LS = JOY_BUTTON_LEFT_STICK,
- JOY_XBOX_RS = JOY_BUTTON_RIGHT_STICK,
- JOY_XBOX_LB = JOY_BUTTON_LEFT_SHOULDER,
- JOY_XBOX_RB = JOY_BUTTON_RIGHT_SHOULDER,
-
- JOY_BUTTON_MAX = 36 // Apparently Android supports up to 36 buttons.
+ JOY_BUTTON_SDL_MAX = 15,
+ JOY_BUTTON_MAX = 36, // Android supports up to 36 buttons.
};
enum JoyAxisList {
- JOY_INVALID_AXIS = -1,
-
- // SDL Axes
+ JOY_AXIS_INVALID = -1,
JOY_AXIS_LEFT_X = 0,
JOY_AXIS_LEFT_Y = 1,
JOY_AXIS_RIGHT_X = 2,
JOY_AXIS_RIGHT_Y = 3,
JOY_AXIS_TRIGGER_LEFT = 4,
JOY_AXIS_TRIGGER_RIGHT = 5,
- JOY_SDL_AXES = 6,
-
- // Joystick axes.
- JOY_AXIS_0_X = 0,
- JOY_AXIS_0_Y = 1,
- JOY_AXIS_1_X = 2,
- JOY_AXIS_1_Y = 3,
- JOY_AXIS_2_X = 4,
- JOY_AXIS_2_Y = 5,
- JOY_AXIS_3_X = 6,
- JOY_AXIS_3_Y = 7,
- JOY_AXIS_4_X = 8,
- JOY_AXIS_4_Y = 9,
-
- JOY_AXIS_MAX = 10 // OpenVR supports up to 5 Joysticks making a total of 10 axes.
+ JOY_AXIS_SDL_MAX = 6,
+ JOY_AXIS_MAX = 10, // OpenVR supports up to 5 Joysticks making a total of 10 axes.
};
enum MidiMessageList {
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index f6fe642493..13514b7b9f 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -42,27 +42,6 @@
typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args);
typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args);
-template <class T>
-struct TypeAdjust {
- _FORCE_INLINE_ static void adjust(Variant *r_ret) {
- VariantTypeChanger<typename GetSimpleTypeT<T>::type_t>::change(r_ret);
- }
-};
-
-template <> //do nothing for variant
-struct TypeAdjust<Variant> {
- _FORCE_INLINE_ static void adjust(Variant *r_ret) {
- }
-};
-
-template <> //do nothing for variant
-struct TypeAdjust<Object *> {
- _FORCE_INLINE_ static void adjust(Variant *r_ret) {
- VariantInternal::clear(r_ret);
- *r_ret = (Object *)nullptr;
- }
-};
-
template <class R, class T, class... P>
static _FORCE_INLINE_ void vc_method_call(R (T::*method)(P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
call_with_variant_args_ret_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, r_error, p_defvals);
@@ -124,12 +103,12 @@ static _FORCE_INLINE_ void vc_ptrcall(void (T::*method)(P...) const, void *p_bas
template <class R, class T, class... P>
static _FORCE_INLINE_ void vc_change_return_type(R (T::*method)(P...), Variant *v) {
- TypeAdjust<R>::adjust(v);
+ VariantTypeAdjust<R>::adjust(v);
}
template <class R, class T, class... P>
static _FORCE_INLINE_ void vc_change_return_type(R (T::*method)(P...) const, Variant *v) {
- TypeAdjust<R>::adjust(v);
+ VariantTypeAdjust<R>::adjust(v);
}
template <class T, class... P>
@@ -144,7 +123,7 @@ static _FORCE_INLINE_ void vc_change_return_type(void (T::*method)(P...) const,
template <class R, class... P>
static _FORCE_INLINE_ void vc_change_return_type(R (*method)(P...), Variant *v) {
- TypeAdjust<R>::adjust(v);
+ VariantTypeAdjust<R>::adjust(v);
}
template <class R, class T, class... P>
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index 3ac7f32dec..3c3be44ef7 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -1128,4 +1128,26 @@ struct VariantTypeChanger {
}
};
+template <class T>
+struct VariantTypeAdjust {
+ _FORCE_INLINE_ static void adjust(Variant *r_ret) {
+ VariantTypeChanger<typename GetSimpleTypeT<T>::type_t>::change(r_ret);
+ }
+};
+
+template <>
+struct VariantTypeAdjust<Variant> {
+ _FORCE_INLINE_ static void adjust(Variant *r_ret) {
+ // Do nothing for variant.
+ }
+};
+
+template <>
+struct VariantTypeAdjust<Object *> {
+ _FORCE_INLINE_ static void adjust(Variant *r_ret) {
+ VariantInternal::clear(r_ret);
+ *r_ret = (Object *)nullptr;
+ }
+};
+
#endif // VARIANT_INTERNAL_H
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index 05fe2b80d9..f6a2c11830 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -41,9 +41,7 @@
#define SETGET_STRUCT(m_base_type, m_member_type, m_member) \
struct VariantSetGet_##m_base_type##_##m_member { \
static void get(const Variant *base, Variant *member) { \
- *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \
- } \
- static void validated_get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
*VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \
} \
static void ptr_get(const void *base, void *member) { \
@@ -71,9 +69,7 @@
#define SETGET_NUMBER_STRUCT(m_base_type, m_member_type, m_member) \
struct VariantSetGet_##m_base_type##_##m_member { \
static void get(const Variant *base, Variant *member) { \
- *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \
- } \
- static void validated_get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
*VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_member; \
} \
static void ptr_get(const void *base, void *member) { \
@@ -104,9 +100,7 @@
#define SETGET_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \
struct VariantSetGet_##m_base_type##_##m_member { \
static void get(const Variant *base, Variant *member) { \
- *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \
- } \
- static void validated_get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
*VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \
} \
static void ptr_get(const void *base, void *member) { \
@@ -134,9 +128,7 @@
#define SETGET_NUMBER_STRUCT_CUSTOM(m_base_type, m_member_type, m_member, m_custom) \
struct VariantSetGet_##m_base_type##_##m_member { \
static void get(const Variant *base, Variant *member) { \
- *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \
- } \
- static void validated_get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
*VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_custom; \
} \
static void ptr_get(const void *base, void *member) { \
@@ -167,9 +159,7 @@
#define SETGET_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \
struct VariantSetGet_##m_base_type##_##m_member { \
static void get(const Variant *base, Variant *member) { \
- *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \
- } \
- static void validated_get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
*VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \
} \
static void ptr_get(const void *base, void *member) { \
@@ -197,9 +187,7 @@
#define SETGET_NUMBER_STRUCT_FUNC(m_base_type, m_member_type, m_member, m_setter, m_getter) \
struct VariantSetGet_##m_base_type##_##m_member { \
static void get(const Variant *base, Variant *member) { \
- *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \
- } \
- static void validated_get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
*VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(); \
} \
static void ptr_get(const void *base, void *member) { \
@@ -230,9 +218,7 @@
#define SETGET_STRUCT_FUNC_INDEX(m_base_type, m_member_type, m_member, m_setter, m_getter, m_index) \
struct VariantSetGet_##m_base_type##_##m_member { \
static void get(const Variant *base, Variant *member) { \
- *member = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \
- } \
- static void validated_get(const Variant *base, Variant *member) { \
+ VariantTypeAdjust<m_member_type>::adjust(member); \
*VariantGetInternalPtr<m_member_type>::get_ptr(member) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_getter(m_index); \
} \
static void ptr_get(const void *base, void *member) { \
@@ -340,7 +326,7 @@ static void register_member(Variant::Type p_type, const StringName &p_member) {
sgi.ptr_setter = T::ptr_set;
sgi.getter = T::get;
- sgi.validated_getter = T::validated_get;
+ sgi.validated_getter = T::get;
sgi.ptr_getter = T::ptr_get;
sgi.member_type = T::get_type();
@@ -605,18 +591,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
oob = true; \
return; \
} \
- *value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \
- oob = false; \
- } \
- static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \
- int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
- if (index < 0) { \
- index += size; \
- } \
- if (index < 0 || index >= size) { \
- oob = true; \
- return; \
- } \
+ VariantTypeAdjust<m_elem_type>::adjust(value); \
*VariantGetInternalPtr<m_elem_type>::get_ptr(value) = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \
oob = false; \
} \
@@ -682,18 +657,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
oob = true; \
return; \
} \
- *value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \
- oob = false; \
- } \
- static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \
- int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
- if (index < 0) { \
- index += size; \
- } \
- if (index < 0 || index >= size) { \
- oob = true; \
- return; \
- } \
+ VariantTypeAdjust<m_elem_type>::adjust(value); \
*VariantGetInternalPtr<m_elem_type>::get_ptr(value) = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \
oob = false; \
} \
@@ -760,14 +724,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
oob = true; \
return; \
} \
- *value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \
- oob = false; \
- } \
- static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \
- if (index < 0 || index >= m_max) { \
- oob = true; \
- return; \
- } \
+ VariantTypeAdjust<m_elem_type>::adjust(value); \
*VariantGetInternalPtr<m_elem_type>::get_ptr(value) = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \
oob = false; \
} \
@@ -822,14 +779,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
oob = true; \
return; \
} \
- *value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))m_accessor[index]; \
- oob = false; \
- } \
- static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \
- if (index < 0 || index >= m_max) { \
- oob = true; \
- return; \
- } \
+ VariantTypeAdjust<m_elem_type>::adjust(value); \
*VariantGetInternalPtr<m_elem_type>::get_ptr(value) = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))m_accessor[index]; \
oob = false; \
} \
@@ -878,14 +828,7 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
oob = true; \
return; \
} \
- *value = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_get(index); \
- oob = false; \
- } \
- static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \
- if (index < 0 || index >= m_max) { \
- oob = true; \
- return; \
- } \
+ VariantTypeAdjust<m_elem_type>::adjust(value); \
*VariantGetInternalPtr<m_elem_type>::get_ptr(value) = VariantGetInternalPtr<m_base_type>::get_ptr(base)->m_get(index); \
oob = false; \
} \
@@ -941,18 +884,6 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
*value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \
oob = false; \
} \
- static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \
- int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
- if (index < 0) { \
- index += size; \
- } \
- if (index < 0 || index >= size) { \
- oob = true; \
- return; \
- } \
- *value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \
- oob = false; \
- } \
static void ptr_get(const void *base, int64_t index, void *member) { \
/* avoid ptrconvert for performance*/ \
const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \
@@ -1010,15 +941,6 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
*value = *ptr; \
oob = false; \
} \
- static void validated_get(const Variant *base, int64_t index, Variant *value, bool &oob) { \
- const Variant *ptr = VariantGetInternalPtr<m_base_type>::get_ptr(base)->getptr(index); \
- if (!ptr) { \
- oob = true; \
- return; \
- } \
- *value = *ptr; \
- oob = false; \
- } \
static void ptr_get(const void *base, int64_t index, void *member) { \
/* avoid ptrconvert for performance*/ \
const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \
@@ -1094,7 +1016,7 @@ static void register_indexed_member(Variant::Type p_type) {
sgi.ptr_setter = T::ptr_set;
sgi.getter = T::get;
- sgi.validated_getter = T::validated_get;
+ sgi.validated_getter = T::get;
sgi.ptr_getter = T::ptr_get;
sgi.index_type = T::get_index_type();
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index f6b1bb4d7c..f6b8e0da19 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -2093,130 +2093,61 @@
<constant name="BUTTON_MASK_XBUTTON2" value="256" enum="ButtonList">
Extra mouse button 2 mask.
</constant>
- <constant name="JOY_INVALID_BUTTON" value="-1" enum="JoyButtonList">
+ <constant name="JOY_BUTTON_INVALID" value="-1" enum="JoyButtonList">
An invalid game controller button.
</constant>
<constant name="JOY_BUTTON_A" value="0" enum="JoyButtonList">
- Game controller SDL button A.
+ Game controller SDL button A. Corresponds to the bottom action button: Sony Cross, Xbox A, Nintendo B.
</constant>
<constant name="JOY_BUTTON_B" value="1" enum="JoyButtonList">
- Game controller SDL button B.
+ Game controller SDL button B. Corresponds to the right action button: Sony Circle, Xbox B, Nintendo A.
</constant>
<constant name="JOY_BUTTON_X" value="2" enum="JoyButtonList">
- Game controller SDL button X.
+ Game controller SDL button X. Corresponds to the left action button: Sony Square, Xbox X, Nintendo Y.
</constant>
<constant name="JOY_BUTTON_Y" value="3" enum="JoyButtonList">
- Game controller SDL button Y.
+ Game controller SDL button Y. Corresponds to the top action button: Sony Triangle, Xbox Y, Nintendo X.
</constant>
<constant name="JOY_BUTTON_BACK" value="4" enum="JoyButtonList">
- Game controller SDL back button.
+ Game controller SDL back button. Corresponds to the Sony Select, Xbox Back, Nintendo - button.
</constant>
<constant name="JOY_BUTTON_GUIDE" value="5" enum="JoyButtonList">
- Game controller SDL guide button.
+ Game controller SDL guide button. Corresponds to the Sony PS, Xbox Home button.
</constant>
<constant name="JOY_BUTTON_START" value="6" enum="JoyButtonList">
- Game controller SDL start button.
+ Game controller SDL start button. Corresponds to the Nintendo + button.
</constant>
<constant name="JOY_BUTTON_LEFT_STICK" value="7" enum="JoyButtonList">
- Game controller SDL left stick button.
+ Game controller SDL left stick button. Corresponds to the Sony L3, Xbox L/LS button.
</constant>
<constant name="JOY_BUTTON_RIGHT_STICK" value="8" enum="JoyButtonList">
- Game controller SDL right stick button.
+ Game controller SDL right stick button. Corresponds to the Sony R3, Xbox R/RS button.
</constant>
<constant name="JOY_BUTTON_LEFT_SHOULDER" value="9" enum="JoyButtonList">
- Game controller SDL left shoulder button.
+ Game controller SDL left shoulder button. Corresponds to the Sony L1, Xbox LB button.
</constant>
<constant name="JOY_BUTTON_RIGHT_SHOULDER" value="10" enum="JoyButtonList">
- Game controller SDL right shoulder button.
+ Game controller SDL right shoulder button. Corresponds to the Sony R1, Xbox RB button.
</constant>
<constant name="JOY_BUTTON_DPAD_UP" value="11" enum="JoyButtonList">
- Game controller SDL D-pad up button.
+ Game controller D-pad up button.
</constant>
<constant name="JOY_BUTTON_DPAD_DOWN" value="12" enum="JoyButtonList">
- Game controller SDL D-pad down button.
+ Game controller D-pad down button.
</constant>
<constant name="JOY_BUTTON_DPAD_LEFT" value="13" enum="JoyButtonList">
- Game controller SDL D-pad left button.
+ Game controller D-pad left button.
</constant>
<constant name="JOY_BUTTON_DPAD_RIGHT" value="14" enum="JoyButtonList">
- Game controller SDL D-pad right button.
+ Game controller D-pad right button.
</constant>
- <constant name="JOY_SDL_BUTTONS" value="15" enum="JoyButtonList">
+ <constant name="JOY_BUTTON_SDL_MAX" value="15" enum="JoyButtonList">
The number of SDL game controller buttons.
</constant>
- <constant name="JOY_SONY_X" value="0" enum="JoyButtonList">
- Sony DualShock controller X button maps to SDL button A.
- </constant>
- <constant name="JOY_SONY_CROSS" value="0" enum="JoyButtonList">
- Sony DualShock controller cross button maps to SDL button A.
- </constant>
- <constant name="JOY_SONY_CIRCLE" value="1" enum="JoyButtonList">
- Sony DualShock controller circle button maps to SDL button B.
- </constant>
- <constant name="JOY_SONY_SQUARE" value="2" enum="JoyButtonList">
- Sony DualShock controller square button maps to SDL button X.
- </constant>
- <constant name="JOY_SONY_TRIANGLE" value="3" enum="JoyButtonList">
- Sony DualShock controller triangle button maps to SDL button Y.
- </constant>
- <constant name="JOY_SONY_SELECT" value="4" enum="JoyButtonList">
- Sony DualShock controller select button maps to SDL back button.
- </constant>
- <constant name="JOY_SONY_START" value="6" enum="JoyButtonList">
- Sony DualShock controller start button maps to SDL start button.
- </constant>
- <constant name="JOY_SONY_PS" value="5" enum="JoyButtonList">
- Sony DualShock controller PS button maps to SDL guide button.
- </constant>
- <constant name="JOY_SONY_L1" value="9" enum="JoyButtonList">
- Sony DualShock controller L1 button maps to SDL left shoulder button.
- </constant>
- <constant name="JOY_SONY_R1" value="10" enum="JoyButtonList">
- Sony DualShock controller R1 button maps to SDL right shoulder button.
- </constant>
- <constant name="JOY_SONY_L3" value="7" enum="JoyButtonList">
- Sony DualShock controller L3 button maps to SDL left stick button.
- </constant>
- <constant name="JOY_SONY_R3" value="8" enum="JoyButtonList">
- Sony DualShock controller R3 button maps to SDL right stick button.
- </constant>
- <constant name="JOY_XBOX_A" value="0" enum="JoyButtonList">
- Xbox game controller A button maps to SDL button A.
- </constant>
- <constant name="JOY_XBOX_B" value="1" enum="JoyButtonList">
- Xbox game controller B button maps to SDL button B.
- </constant>
- <constant name="JOY_XBOX_X" value="2" enum="JoyButtonList">
- Xbox game controller X button maps to SDL button X.
- </constant>
- <constant name="JOY_XBOX_Y" value="3" enum="JoyButtonList">
- Xbox game controller Y button maps to SDL button Y.
- </constant>
- <constant name="JOY_XBOX_BACK" value="4" enum="JoyButtonList">
- Xbox game controller back button maps to SDL back button.
- </constant>
- <constant name="JOY_XBOX_START" value="6" enum="JoyButtonList">
- Xbox game controller start button maps to SDL start button.
- </constant>
- <constant name="JOY_XBOX_HOME" value="5" enum="JoyButtonList">
- Xbox game controller home button maps to SDL guide button.
- </constant>
- <constant name="JOY_XBOX_LS" value="7" enum="JoyButtonList">
- Xbox game controller left stick button maps to SDL left stick button.
- </constant>
- <constant name="JOY_XBOX_RS" value="8" enum="JoyButtonList">
- Xbox game controller right stick button maps to SDL right stick button.
- </constant>
- <constant name="JOY_XBOX_LB" value="9" enum="JoyButtonList">
- Xbox game controller left bumper button maps to SDL left shoulder button.
- </constant>
- <constant name="JOY_XBOX_RB" value="10" enum="JoyButtonList">
- Xbox game controller right bumper button maps to SDL right shoulder button.
- </constant>
<constant name="JOY_BUTTON_MAX" value="36" enum="JoyButtonList">
- The maximum number of game controller buttons.
+ The maximum number of game controller buttons: Android supports up to 36 buttons.
</constant>
- <constant name="JOY_INVALID_AXIS" value="-1" enum="JoyAxisList">
+ <constant name="JOY_AXIS_INVALID" value="-1" enum="JoyAxisList">
An invalid game controller axis.
</constant>
<constant name="JOY_AXIS_LEFT_X" value="0" enum="JoyAxisList">
@@ -2237,41 +2168,11 @@
<constant name="JOY_AXIS_TRIGGER_RIGHT" value="5" enum="JoyAxisList">
Game controller right trigger axis.
</constant>
- <constant name="JOY_SDL_AXES" value="6" enum="JoyAxisList">
+ <constant name="JOY_AXIS_SDL_MAX" value="6" enum="JoyAxisList">
The number of SDL game controller axes.
</constant>
- <constant name="JOY_AXIS_0_X" value="0" enum="JoyAxisList">
- Game controller joystick 0 x-axis.
- </constant>
- <constant name="JOY_AXIS_0_Y" value="1" enum="JoyAxisList">
- Game controller joystick 0 y-axis.
- </constant>
- <constant name="JOY_AXIS_1_X" value="2" enum="JoyAxisList">
- Game controller joystick 1 x-axis.
- </constant>
- <constant name="JOY_AXIS_1_Y" value="3" enum="JoyAxisList">
- Game controller joystick 1 y-axis.
- </constant>
- <constant name="JOY_AXIS_2_X" value="4" enum="JoyAxisList">
- Game controller joystick 2 x-axis.
- </constant>
- <constant name="JOY_AXIS_2_Y" value="5" enum="JoyAxisList">
- Game controller joystick 2 y-axis.
- </constant>
- <constant name="JOY_AXIS_3_X" value="6" enum="JoyAxisList">
- Game controller joystick 3 x-axis.
- </constant>
- <constant name="JOY_AXIS_3_Y" value="7" enum="JoyAxisList">
- Game controller joystick 3 y-axis.
- </constant>
- <constant name="JOY_AXIS_4_X" value="8" enum="JoyAxisList">
- Game controller joystick 4 x-axis.
- </constant>
- <constant name="JOY_AXIS_4_Y" value="9" enum="JoyAxisList">
- Game controller joystick 4 y-axis.
- </constant>
<constant name="JOY_AXIS_MAX" value="10" enum="JoyAxisList">
- The maximum number of game controller axes.
+ The maximum number of game controller axes: OpenVR supports up to 5 Joysticks making a total of 10 axes.
</constant>
<constant name="MIDI_MESSAGE_NOTE_OFF" value="8" enum="MidiMessageList">
MIDI note OFF message.
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 3f212fa0f6..e3fc87ffb5 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -782,7 +782,8 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Enables or disables internal physics for this node. Internal physics processing happens in isolation from the normal [method _physics_process] calls and is used by some nodes internally to guarantee proper functioning even if the node is paused or physics processing is disabled for scripting ([method set_physics_process]). Only useful for advanced uses to manipulate built-in nodes' behaviour.
+ Enables or disables internal physics for this node. Internal physics processing happens in isolation from the normal [method _physics_process] calls and is used by some nodes internally to guarantee proper functioning even if the node is paused or physics processing is disabled for scripting ([method set_physics_process]). Only useful for advanced uses to manipulate built-in nodes' behavior.
+ [b]Warning:[/b] Built-in Nodes rely on the internal processing for their own logic, so changing this value from your code may lead to unexpected behavior. Script access to this internal logic is provided for specific advanced uses, but is unsafe and not supported.
</description>
</method>
<method name="set_process">
@@ -809,7 +810,8 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Enables or disabled internal processing for this node. Internal processing happens in isolation from the normal [method _process] calls and is used by some nodes internally to guarantee proper functioning even if the node is paused or processing is disabled for scripting ([method set_process]). Only useful for advanced uses to manipulate built-in nodes' behaviour.
+ Enables or disabled internal processing for this node. Internal processing happens in isolation from the normal [method _process] calls and is used by some nodes internally to guarantee proper functioning even if the node is paused or processing is disabled for scripting ([method set_process]). Only useful for advanced uses to manipulate built-in nodes' behavior.
+ [b]Warning:[/b] Built-in Nodes rely on the internal processing for their own logic, so changing this value from your code may lead to unexpected behavior. Script access to this internal logic is provided for specific advanced uses, but is unsafe and not supported.
</description>
</method>
<method name="set_process_unhandled_input">
diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp
index 186804dbb1..0ee97256fc 100644
--- a/drivers/unix/net_socket_posix.cpp
+++ b/drivers/unix/net_socket_posix.cpp
@@ -348,11 +348,11 @@ Error NetSocketPosix::open(Type p_sock_type, IP::Type &ip_type) {
// recv/recvfrom and an ICMP reply was received from a previous send/sendto.
unsigned long disable = 0;
if (ioctlsocket(_sock, SIO_UDP_CONNRESET, &disable) == SOCKET_ERROR) {
- print_verbose("Unable to turn off UDP WSAECONNRESET behaviour on Windows");
+ print_verbose("Unable to turn off UDP WSAECONNRESET behavior on Windows");
}
if (ioctlsocket(_sock, SIO_UDP_NETRESET, &disable) == SOCKET_ERROR) {
// This feature seems not to be supported on wine.
- print_verbose("Unable to turn off UDP WSAENETRESET behaviour on Windows");
+ print_verbose("Unable to turn off UDP WSAENETRESET behavior on Windows");
}
}
#endif
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 3aeffede82..69edefd75c 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -1632,15 +1632,17 @@ void EditorExportPlatformPC::get_preset_features(const Ref<EditorExportPreset> &
}
void EditorExportPlatformPC::get_export_options(List<ExportOption> *r_options) {
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE), ""));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/64_bits"), true));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/embed_pck"), false));
+
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/bptc"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/no_bptc_fallbacks"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/64_bits"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/embed_pck"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE), ""));
}
String EditorExportPlatformPC::get_name() const {
diff --git a/editor/input_map_editor.cpp b/editor/input_map_editor.cpp
index c67e16d371..5b6d850096 100644
--- a/editor/input_map_editor.cpp
+++ b/editor/input_map_editor.cpp
@@ -35,37 +35,37 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
-static const char *_button_descriptions[JOY_SDL_BUTTONS] = {
- TTRC("Face Bottom, DualShock Cross, Xbox A, Nintendo B"),
- TTRC("Face Right, DualShock Circle, Xbox B, Nintendo A"),
- TTRC("Face Left, DualShock Square, Xbox X, Nintendo Y"),
- TTRC("Face Top, DualShock Triangle, Xbox Y, Nintendo X"),
- TTRC("DualShock Select, Xbox Back, Nintendo -"),
- TTRC("Home, DualShock PS, Guide"),
+static const char *_button_descriptions[JOY_BUTTON_SDL_MAX] = {
+ TTRC("Bottom Action, Sony Cross, Xbox A, Nintendo B"),
+ TTRC("Right Action, Sony Circle, Xbox B, Nintendo A"),
+ TTRC("Left Action, Sony Square, Xbox X, Nintendo Y"),
+ TTRC("Top Action, Sony Triangle, Xbox Y, Nintendo X"),
+ TTRC("Back, Sony Select, Xbox Back, Nintendo -"),
+ TTRC("Guide, Sony PS, Xbox Home"),
TTRC("Start, Nintendo +"),
- TTRC("Left Stick, DualShock L3, Xbox L/LS"),
- TTRC("Right Stick, DualShock R3, Xbox R/RS"),
- TTRC("Left Shoulder, DualShock L1, Xbox LB"),
- TTRC("Right Shoulder, DualShock R1, Xbox RB"),
- TTRC("D-Pad Up"),
- TTRC("D-Pad Down"),
- TTRC("D-Pad Left"),
- TTRC("D-Pad Right")
+ TTRC("Left Stick, Sony L3, Xbox L/LS"),
+ TTRC("Right Stick, Sony R3, Xbox R/RS"),
+ TTRC("Left Shoulder, Sony L1, Xbox LB"),
+ TTRC("Right Shoulder, Sony R1, Xbox RB"),
+ TTRC("D-pad Up"),
+ TTRC("D-pad Down"),
+ TTRC("D-pad Left"),
+ TTRC("D-pad Right"),
};
static const char *_axis_descriptions[JOY_AXIS_MAX * 2] = {
- TTRC("Left Stick Left"),
- TTRC("Left Stick Right"),
- TTRC("Left Stick Up"),
- TTRC("Left Stick Down"),
- TTRC("Right Stick Left"),
- TTRC("Right Stick Right"),
- TTRC("Right Stick Up"),
- TTRC("Right Stick Down"),
+ TTRC("Left Stick Left, Joystick 0 Left"),
+ TTRC("Left Stick Right, Joystick 0 Right"),
+ TTRC("Left Stick Up, Joystick 0 Up"),
+ TTRC("Left Stick Down, Joystick 0 Down"),
+ TTRC("Right Stick Left, Joystick 1 Left"),
+ TTRC("Right Stick Right, Joystick 1 Right"),
+ TTRC("Right Stick Up, Joystick 1 Up"),
+ TTRC("Right Stick Down, Joystick 1 Down"),
TTRC("Joystick 2 Left"),
- TTRC("Joystick 2 Right, Left Trigger, L2, LT"),
+ TTRC("Left Trigger, L2, LT, Joystick 2 Right"),
TTRC("Joystick 2 Up"),
- TTRC("Joystick 2 Down, Right Trigger, R2, RT"),
+ TTRC("Right Trigger, R2, RT, Joystick 2 Down"),
TTRC("Joystick 3 Left"),
TTRC("Joystick 3 Right"),
TTRC("Joystick 3 Up"),
@@ -503,7 +503,7 @@ void InputMapEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_event) {
device_index->clear();
for (int i = 0; i < JOY_BUTTON_MAX; i++) {
String desc = TTR("Button") + " " + itos(i);
- if (i < JOY_SDL_BUTTONS) {
+ if (i < JOY_BUTTON_SDL_MAX) {
desc += " (" + TTR(_button_descriptions[i]) + ")";
}
device_index->add_item(desc);
@@ -717,7 +717,7 @@ void InputMapEditor::_update_actions() {
const int idx = jb->get_button_index();
String str = _get_device_string(jb->get_device()) + ", " +
TTR("Button") + " " + itos(idx);
- if (idx >= 0 && idx < JOY_SDL_BUTTONS) {
+ if (idx >= 0 && idx < JOY_BUTTON_SDL_MAX) {
str += String() + " (" + TTR(_button_descriptions[jb->get_button_index()]) + ")";
}
diff --git a/modules/visual_script/doc_classes/VisualScriptLists.xml b/modules/visual_script/doc_classes/VisualScriptLists.xml
index 5b64d8438b..8a7254b46a 100644
--- a/modules/visual_script/doc_classes/VisualScriptLists.xml
+++ b/modules/visual_script/doc_classes/VisualScriptLists.xml
@@ -4,7 +4,7 @@
A Visual Script virtual class for in-graph editable nodes.
</brief_description>
<description>
- A Visual Script virtual class that defines the shape and the default behaviour of the nodes that have to be in-graph editable nodes.
+ A Visual Script virtual class that defines the shape and the default behavior of the nodes that have to be in-graph editable nodes.
</description>
<tutorials>
</tutorials>
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 35a7c54a8f..9288fff82f 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -1610,12 +1610,6 @@ public:
}
virtual void get_export_options(List<ExportOption> *r_options) override {
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,Oculus Mobile VR"), 0));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/degrees_of_freedom", PROPERTY_HINT_ENUM, "None,3DOF and 6DOF,6DOF"), 0));
- r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "xr_features/focus_awareness"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_template/use_custom_build"), false));
@@ -1628,38 +1622,52 @@ public:
}
plugins_changed = false;
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), ""));
+ Vector<String> abis = get_abis();
+ for (int i = 0; i < abis.size(); ++i) {
+ String abi = abis[i];
+ bool is_default = (abi == "armeabi-v7a" || abi == "arm64-v8a");
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architectures/" + abi), is_default));
+ }
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_user"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_password"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password"), ""));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), false));
+
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "ext.domain.name"), "org.godotengine.$genname"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name [default if blank]"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/signed"), true));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icon_option, PROPERTY_HINT_FILE, "*.png"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_foreground_option, PROPERTY_HINT_FILE, "*.png"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_background_option, PROPERTY_HINT_FILE, "*.png"), ""));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/opengl_debug"), false));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,Oculus Mobile VR"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/degrees_of_freedom", PROPERTY_HINT_ENUM, "None,3DOF and 6DOF,6DOF"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "xr_features/focus_awareness"), false));
+
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/immersive_mode"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_small"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_normal"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_large"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/opengl_debug"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icon_option, PROPERTY_HINT_FILE, "*.png"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_foreground_option, PROPERTY_HINT_FILE, "*.png"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_background_option, PROPERTY_HINT_FILE, "*.png"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_user"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_password"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password"), ""));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), ""));
+
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "apk_expansion/enable"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "apk_expansion/SALT"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "apk_expansion/public_key", PROPERTY_HINT_MULTILINE_TEXT), ""));
- Vector<String> abis = get_abis();
- for (int i = 0; i < abis.size(); ++i) {
- String abi = abis[i];
- bool is_default = (abi == "armeabi-v7a" || abi == "arm64-v8a");
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architectures/" + abi), is_default));
- }
-
r_options->push_back(ExportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "permissions/custom_permissions"), PackedStringArray()));
const char **perms = android_perms;
@@ -2147,7 +2155,7 @@ public:
command_line_strings.push_back("--use_immersive");
}
- bool debug_opengl = p_preset->get("screen/opengl_debug");
+ bool debug_opengl = p_preset->get("graphics/opengl_debug");
if (debug_opengl) {
command_line_strings.push_back("--debug_opengl");
}
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index 62fcfffbb7..fff82c9467 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -338,12 +338,16 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
+ Vector<ExportArchitecture> architectures = _get_supported_architectures();
+ for (int i = 0; i < architectures.size(); ++i) {
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architectures/" + architectures[i].name), architectures[i].is_default));
+ }
+
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_store_team_id"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/provisioning_profile_uuid_debug"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/code_sign_identity_debug", PROPERTY_HINT_PLACEHOLDER_TEXT, "iPhone Developer"), "iPhone Developer"));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_method_debug", PROPERTY_HINT_ENUM, "App Store,Development,Ad-Hoc,Enterprise"), 1));
-
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/provisioning_profile_uuid_release"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/code_sign_identity_release", PROPERTY_HINT_PLACEHOLDER_TEXT, "iPhone Distribution"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_method_release", PROPERTY_HINT_ENUM, "App Store,Development,Ad-Hoc,Enterprise"), 0));
@@ -357,11 +361,9 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
Vector<PluginConfig> found_plugins = get_plugins();
-
for (int i = 0; i < found_plugins.size(); i++) {
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "plugins/" + found_plugins[i].name), false));
}
-
plugins_changed = false;
plugins = found_plugins;
@@ -404,11 +406,6 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
for (uint64_t i = 0; i < sizeof(loading_screen_infos) / sizeof(loading_screen_infos[0]); ++i) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, loading_screen_infos[i].preset_key, PROPERTY_HINT_FILE, "*.png"), ""));
}
-
- Vector<ExportArchitecture> architectures = _get_supported_architectures();
- for (int i = 0; i < architectures.size(); ++i) {
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architectures/" + architectures[i].name), architectures[i].is_default));
- }
}
void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &pfile, const IOSConfigData &p_config, bool p_debug) {
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index e6e35f6aa9..71189cf697 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -107,7 +107,6 @@ def configure(env):
env["CC"] = "emcc"
env["CXX"] = "em++"
- env["LINK"] = "emcc"
env["AR"] = "emar"
env["RANLIB"] = "emranlib"
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index d520931067..c3b7e0304e 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -294,13 +294,15 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP
}
void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_options) {
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
+
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_desktop"), true)); // S3TC
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_mobile"), false)); // ETC or ETC2, depending on renderer
+
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_FILE, "*.html"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/head_include", PROPERTY_HINT_MULTILINE_TEXT), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "html/full_window_size"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
}
String EditorExportPlatformJavaScript::get_name() const {
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index ea101e24dd..a1bc5867c5 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -129,7 +129,6 @@ def configure(env):
if "clang++" not in os.path.basename(env["CXX"]):
env["CC"] = "clang"
env["CXX"] = "clang++"
- env["LINK"] = "clang++"
env.Append(CPPDEFINES=["TYPED_METHOD_BIND"])
env.extra_suffix = ".llvm" + env.extra_suffix
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index 671efa216c..ea41479bb0 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -99,7 +99,6 @@ def configure(env):
mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local")
mpclangver = env["macports_clang"]
env["CC"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang"
- env["LINK"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang++"
env["CXX"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/clang++"
env["AR"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ar"
env["RANLIB"] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ranlib"
@@ -134,12 +133,6 @@ def configure(env):
env["AS"] = basecmd + "as"
env.Append(CPPDEFINES=["__MACPORTS__"]) # hack to fix libvpx MM256_BROADCASTSI128_SI256 define
- if env["CXX"] == "clang++":
- # This should now work with clang++, re-enable if there are issues
- # env.Append(CPPDEFINES=["TYPED_METHOD_BIND"])
- env["CC"] = "clang"
- env["LINK"] = "clang++"
-
if env["use_ubsan"] or env["use_asan"] or env["use_tsan"]:
env.extra_suffix += "s"
diff --git a/platform/server/detect.py b/platform/server/detect.py
index f9e151f956..a3f60b0710 100644
--- a/platform/server/detect.py
+++ b/platform/server/detect.py
@@ -94,7 +94,6 @@ def configure(env):
if "clang++" not in os.path.basename(env["CXX"]):
env["CC"] = "clang"
env["CXX"] = "clang++"
- env["LINK"] = "clang++"
env.Append(CPPDEFINES=["TYPED_METHOD_BIND"])
env.extra_suffix = ".llvm" + env.extra_suffix
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index e0c03df48e..30568241a9 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -1004,6 +1004,9 @@ public:
}
virtual void get_export_options(List<ExportOption> *r_options) override {
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
+
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "architecture/target", PROPERTY_HINT_ENUM, "arm,x86,x64"), 1));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), ""));
@@ -1045,9 +1048,6 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "tiles/show_name_on_wide310x150"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "tiles/show_name_on_square310x310"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
-
// Capabilities
const char **basic = uwp_capabilities;
while (*basic) {
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 934314b2f2..e0b2a52014 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -383,18 +383,17 @@ def configure_mingw(env):
if env["use_llvm"]:
env["CC"] = mingw_prefix + "clang"
- env["AS"] = mingw_prefix + "as"
env["CXX"] = mingw_prefix + "clang++"
+ env["AS"] = mingw_prefix + "as"
env["AR"] = mingw_prefix + "ar"
env["RANLIB"] = mingw_prefix + "ranlib"
- env["LINK"] = mingw_prefix + "clang++"
else:
env["CC"] = mingw_prefix + "gcc"
- env["AS"] = mingw_prefix + "as"
env["CXX"] = mingw_prefix + "g++"
+ env["AS"] = mingw_prefix + "as"
env["AR"] = mingw_prefix + "gcc-ar"
env["RANLIB"] = mingw_prefix + "gcc-ranlib"
- env["LINK"] = mingw_prefix + "g++"
+
env["x86_libtheora_opt_gcc"] = True
if env["use_lto"]:
diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp
index 132c35771b..e633b1eb4a 100644
--- a/scene/3d/soft_body_3d.cpp
+++ b/scene/3d/soft_body_3d.cpp
@@ -725,7 +725,7 @@ void SoftBody3D::_update_cache_pin_points_datas() {
w[i].spatial_attachment = Object::cast_to<Node3D>(get_node(w[i].spatial_attachment_path));
}
if (!w[i].spatial_attachment) {
- ERR_PRINT("Node3D node not defined in the pinned point, Softbody undefined behaviour!");
+ ERR_PRINT("Node3D node not defined in the pinned point, this is undefined behavior for SoftBody3D!");
}
}
}
diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp
index c9fce2f6c2..1c6037d26e 100644
--- a/scene/main/timer.cpp
+++ b/scene/main/timer.cpp
@@ -46,7 +46,7 @@ void Timer::_notification(int p_what) {
}
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
- if (timer_process_mode == TIMER_PROCESS_PHYSICS || !is_processing_internal()) {
+ if (!processing || timer_process_mode == TIMER_PROCESS_PHYSICS || !is_processing_internal()) {
return;
}
time_left -= get_process_delta_time();
@@ -63,7 +63,7 @@ void Timer::_notification(int p_what) {
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
- if (timer_process_mode == TIMER_PROCESS_IDLE || !is_physics_processing_internal()) {
+ if (!processing || timer_process_mode == TIMER_PROCESS_IDLE || !is_physics_processing_internal()) {
return;
}
time_left -= get_physics_process_delta_time();
diff --git a/tests/test_json.h b/tests/test_json.h
new file mode 100644
index 0000000000..fe29e89e06
--- /dev/null
+++ b/tests/test_json.h
@@ -0,0 +1,166 @@
+/*************************************************************************/
+/* test_json.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_JSON_H
+#define TEST_JSON_H
+
+#include "core/io/json.h"
+
+#include "thirdparty/doctest/doctest.h"
+
+namespace TestJSON {
+
+// NOTE: The current JSON parser accepts many non-conformant strings such as
+// single-quoted strings, duplicate commas and trailing commas.
+// This is intentionally not tested as users shouldn't rely on this behavior.
+
+TEST_CASE("[JSON] Parsing single data types") {
+ // Parsing a single data type as JSON is valid per the JSON specification.
+
+ JSON json;
+ Variant result;
+ String err_str;
+ int err_line;
+
+ json.parse("null", result, err_str, err_line);
+ CHECK_MESSAGE(
+ err_line == 0,
+ "Parsing `null` as JSON should parse successfully.");
+ CHECK_MESSAGE(
+ result == Variant(),
+ "Parsing a double quoted string as JSON should return the expected value.");
+
+ json.parse("true", result, err_str, err_line);
+ CHECK_MESSAGE(
+ err_line == 0,
+ "Parsing boolean `true` as JSON should parse successfully.");
+ CHECK_MESSAGE(
+ result,
+ "Parsing boolean `true` as JSON should return the expected value.");
+
+ json.parse("false", result, err_str, err_line);
+ CHECK_MESSAGE(
+ err_line == 0,
+ "Parsing boolean `false` as JSON should parse successfully.");
+ CHECK_MESSAGE(
+ !result,
+ "Parsing boolean `false` as JSON should return the expected value.");
+
+ // JSON only has a floating-point number type, no integer type.
+ // This is why we use `is_equal_approx()` for the comparison.
+ json.parse("123456", result, err_str, err_line);
+ CHECK_MESSAGE(
+ err_line == 0,
+ "Parsing an integer number as JSON should parse successfully.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(result, 123'456),
+ "Parsing an integer number as JSON should return the expected value.");
+
+ json.parse("0.123456", result, err_str, err_line);
+ CHECK_MESSAGE(
+ err_line == 0,
+ "Parsing a floating-point number as JSON should parse successfully.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(result, 0.123456),
+ "Parsing a floating-point number as JSON should return the expected value.");
+
+ json.parse("\"hello\"", result, err_str, err_line);
+ CHECK_MESSAGE(
+ err_line == 0,
+ "Parsing a double quoted string as JSON should parse successfully.");
+ CHECK_MESSAGE(
+ result == "hello",
+ "Parsing a double quoted string as JSON should return the expected value.");
+}
+
+TEST_CASE("[JSON] Parsing arrays") {
+ JSON json;
+ Variant result;
+ String err_str;
+ int err_line;
+
+ // JSON parsing fails if it's split over several lines (even if leading indentation is removed).
+ json.parse(
+ R"(["Hello", "world.", "This is",["a","json","array.",[]], "Empty arrays ahoy:", [[["Gotcha!"]]]])",
+ result, err_str, err_line);
+
+ const Array array = result;
+ CHECK_MESSAGE(
+ err_line == 0,
+ "Parsing a JSON array should parse successfully.");
+ CHECK_MESSAGE(
+ array[0] == "Hello",
+ "The parsed JSON should contain the expected values.");
+ const Array sub_array = array[3];
+ CHECK_MESSAGE(
+ sub_array.size() == 4,
+ "The parsed JSON should contain the expected values.");
+ CHECK_MESSAGE(
+ sub_array[1] == "json",
+ "The parsed JSON should contain the expected values.");
+ CHECK_MESSAGE(
+ sub_array[3].hash() == Array().hash(),
+ "The parsed JSON should contain the expected values.");
+ const Array deep_array = Array(Array(array[5])[0])[0];
+ CHECK_MESSAGE(
+ deep_array[0] == "Gotcha!",
+ "The parsed JSON should contain the expected values.");
+}
+
+TEST_CASE("[JSON] Parsing objects (dictionaries)") {
+ JSON json;
+ Variant result;
+ String err_str;
+ int err_line;
+
+ json.parse(
+ R"({"name": "Godot Engine", "is_free": true, "bugs": null, "apples": {"red": 500, "green": 0, "blue": -20}, "empty_object": {}})",
+ result, err_str, err_line);
+
+ const Dictionary dictionary = result;
+ CHECK_MESSAGE(
+ dictionary["name"] == "Godot Engine",
+ "The parsed JSON should contain the expected values.");
+ CHECK_MESSAGE(
+ dictionary["is_free"],
+ "The parsed JSON should contain the expected values.");
+ CHECK_MESSAGE(
+ dictionary["bugs"] == Variant(),
+ "The parsed JSON should contain the expected values.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(Dictionary(dictionary["apples"])["blue"], -20),
+ "The parsed JSON should contain the expected values.");
+ CHECK_MESSAGE(
+ dictionary["empty_object"].hash() == Dictionary().hash(),
+ "The parsed JSON should contain the expected values.");
+}
+} // namespace TestJSON
+
+#endif // TEST_JSON_H
diff --git a/tests/test_main.cpp b/tests/test_main.cpp
index cd7f1d3eac..4388654d08 100644
--- a/tests/test_main.cpp
+++ b/tests/test_main.cpp
@@ -42,15 +42,18 @@
#include "test_expression.h"
#include "test_gradient.h"
#include "test_gui.h"
+#include "test_json.h"
#include "test_list.h"
#include "test_math.h"
#include "test_method_bind.h"
#include "test_node_path.h"
#include "test_oa_hash_map.h"
+#include "test_object.h"
#include "test_ordered_hash_map.h"
#include "test_pck_packer.h"
#include "test_physics_2d.h"
#include "test_physics_3d.h"
+#include "test_rect2.h"
#include "test_render.h"
#include "test_shader_lang.h"
#include "test_string.h"
@@ -112,10 +115,6 @@ int test_main(int argc, char *argv[]) {
test_context.applyCommandLine(test_args.size(), doctest_args);
- test_context.setOption("order-by", "name");
- test_context.setOption("abort-after", 5);
- test_context.setOption("no-breaks", true);
-
for (int x = 0; x < test_args.size(); x++) {
delete[] doctest_args[x];
}
diff --git a/tests/test_object.h b/tests/test_object.h
new file mode 100644
index 0000000000..6fef2576e7
--- /dev/null
+++ b/tests/test_object.h
@@ -0,0 +1,92 @@
+/*************************************************************************/
+/* test_object.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_OBJECT_H
+#define TEST_OBJECT_H
+
+#include "core/object/object.h"
+
+#include "thirdparty/doctest/doctest.h"
+
+namespace TestObject {
+
+TEST_CASE("[Object] Core getters") {
+ Object object;
+
+ CHECK_MESSAGE(
+ object.is_class("Object"),
+ "is_class() should return the expected value.");
+ CHECK_MESSAGE(
+ object.get_class() == "Object",
+ "The returned class should match the expected value.");
+ CHECK_MESSAGE(
+ object.get_class_name() == "Object",
+ "The returned class name should match the expected value.");
+ CHECK_MESSAGE(
+ object.get_class_static() == "Object",
+ "The returned static class should match the expected value.");
+ CHECK_MESSAGE(
+ object.get_save_class() == "Object",
+ "The returned save class should match the expected value.");
+}
+
+TEST_CASE("[Object] Metadata") {
+ const String meta_path = "hello/world complex métadata\n\n\t\tpath";
+ Object object;
+
+ object.set_meta(meta_path, Color(0, 1, 0));
+ CHECK_MESSAGE(
+ Color(object.get_meta(meta_path)).is_equal_approx(Color(0, 1, 0)),
+ "The returned object metadata after setting should match the expected value.");
+
+ List<String> meta_list;
+ object.get_meta_list(&meta_list);
+ CHECK_MESSAGE(
+ meta_list.size() == 1,
+ "The metadata list should only contain 1 item after adding one metadata item.");
+
+ object.remove_meta(meta_path);
+ // Also try removing nonexistent metadata (it should do nothing, without printing an error message).
+ object.remove_meta("I don't exist");
+ ERR_PRINT_OFF;
+ CHECK_MESSAGE(
+ object.get_meta(meta_path) == Variant(),
+ "The returned object metadata after removing should match the expected value.");
+ ERR_PRINT_ON;
+
+ List<String> meta_list2;
+ object.get_meta_list(&meta_list2);
+ CHECK_MESSAGE(
+ meta_list2.size() == 0,
+ "The metadata list should contain 0 items after removing all metadata items.");
+}
+} // namespace TestObject
+
+#endif // TEST_OBJECT_H
diff --git a/tests/test_rect2.h b/tests/test_rect2.h
new file mode 100644
index 0000000000..aefceb1128
--- /dev/null
+++ b/tests/test_rect2.h
@@ -0,0 +1,467 @@
+/*************************************************************************/
+/* test_rect2.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_RECT2_H
+#define TEST_RECT2_H
+
+#include "core/math/rect2.h"
+
+#include "thirdparty/doctest/doctest.h"
+
+namespace TestRect2 {
+// We also test Rect2i here, for consistency with the source code where Rect2
+// and Rect2i are defined in the same file.
+
+// Rect2
+
+TEST_CASE("[Rect2] Constructor methods") {
+ const Rect2 rect = Rect2(0, 100, 1280, 720);
+ const Rect2 rect_vector = Rect2(Vector2(0, 100), Vector2(1280, 720));
+ const Rect2 rect_copy_rect = Rect2(rect);
+ const Rect2 rect_copy_recti = Rect2(Rect2i(0, 100, 1280, 720));
+
+ CHECK_MESSAGE(
+ rect == rect_vector,
+ "Rect2s created with the same dimensions but by different methods should be equal.");
+ CHECK_MESSAGE(
+ rect == rect_copy_rect,
+ "Rect2s created with the same dimensions but by different methods should be equal.");
+ CHECK_MESSAGE(
+ rect == rect_copy_recti,
+ "Rect2s created with the same dimensions but by different methods should be equal.");
+}
+
+TEST_CASE("[Rect2] String conversion") {
+ // Note: This also depends on the Vector2 string representation.
+ CHECK_MESSAGE(
+ String(Rect2(0, 100, 1280, 720)) == "0, 100, 1280, 720",
+ "The string representation should match the expected value.");
+}
+
+TEST_CASE("[Rect2] Basic getters") {
+ const Rect2 rect = Rect2(0, 100, 1280, 720);
+ CHECK_MESSAGE(
+ rect.get_position().is_equal_approx(Vector2(0, 100)),
+ "get_position() should return the expected value.");
+ CHECK_MESSAGE(
+ rect.get_size().is_equal_approx(Vector2(1280, 720)),
+ "get_size() should return the expected value.");
+ CHECK_MESSAGE(
+ rect.get_end().is_equal_approx(Vector2(1280, 820)),
+ "get_end() should return the expected value.");
+}
+
+TEST_CASE("[Rect2] Basic setters") {
+ Rect2 rect = Rect2(0, 100, 1280, 720);
+ rect.set_end(Vector2(4000, 4000));
+ CHECK_MESSAGE(
+ rect.is_equal_approx(Rect2(0, 100, 4000, 3900)),
+ "set_end() should result in the expected Rect2.");
+
+ rect = Rect2(0, 100, 1280, 720);
+ rect.set_position(Vector2(4000, 4000));
+ CHECK_MESSAGE(
+ rect.is_equal_approx(Rect2(4000, 4000, 1280, 720)),
+ "set_position() should result in the expected Rect2.");
+
+ rect = Rect2(0, 100, 1280, 720);
+ rect.set_size(Vector2(4000, 4000));
+ CHECK_MESSAGE(
+ rect.is_equal_approx(Rect2(0, 100, 4000, 4000)),
+ "set_size() should result in the expected Rect2.");
+}
+
+TEST_CASE("[Rect2] Area getters") {
+ CHECK_MESSAGE(
+ Math::is_equal_approx(Rect2(0, 100, 1280, 720).get_area(), 921'600),
+ "get_area() should return the expected value.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(Rect2(0, 100, -1280, -720).get_area(), 921'600),
+ "get_area() should return the expected value.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(Rect2(0, 100, 1280, -720).get_area(), -921'600),
+ "get_area() should return the expected value.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(Rect2(0, 100, -1280, 720).get_area(), -921'600),
+ "get_area() should return the expected value.");
+ CHECK_MESSAGE(
+ Math::is_zero_approx(Rect2(0, 100, 0, 720).get_area()),
+ "get_area() should return the expected value.");
+
+ CHECK_MESSAGE(
+ !Rect2(0, 100, 1280, 720).has_no_area(),
+ "has_no_area() should return the expected value on Rect2 with an area.");
+ CHECK_MESSAGE(
+ Rect2(0, 100, 0, 500).has_no_area(),
+ "has_no_area() should return the expected value on Rect2 with no area.");
+ CHECK_MESSAGE(
+ Rect2(0, 100, 500, 0).has_no_area(),
+ "has_no_area() should return the expected value on Rect2 with no area.");
+ CHECK_MESSAGE(
+ Rect2(0, 100, 0, 0).has_no_area(),
+ "has_no_area() should return the expected value on Rect2 with no area.");
+}
+
+TEST_CASE("[Rect2] Absolute coordinates") {
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).abs().is_equal_approx(Rect2(0, 100, 1280, 720)),
+ "abs() should return the expected Rect2.");
+ CHECK_MESSAGE(
+ Rect2(0, -100, 1280, 720).abs().is_equal_approx(Rect2(0, -100, 1280, 720)),
+ "abs() should return the expected Rect2.");
+ CHECK_MESSAGE(
+ Rect2(0, -100, -1280, -720).abs().is_equal_approx(Rect2(-1280, -820, 1280, 720)),
+ "abs() should return the expected Rect2.");
+ CHECK_MESSAGE(
+ Rect2(0, 100, -1280, 720).abs().is_equal_approx(Rect2(-1280, 100, 1280, 720)),
+ "abs() should return the expected Rect2.");
+}
+
+TEST_CASE("[Rect2] Clipping") {
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).clip(Rect2(0, 300, 100, 100)).is_equal_approx(Rect2(0, 300, 100, 100)),
+ "clip() with fully enclosed Rect2 should return the expected result.");
+ // The resulting Rect2 is 100 pixels high because the first Rect2 is vertically offset by 100 pixels.
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).clip(Rect2(1200, 700, 100, 100)).is_equal_approx(Rect2(1200, 700, 80, 100)),
+ "clip() with partially enclosed Rect2 should return the expected result.");
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).clip(Rect2(-4000, -4000, 100, 100)).is_equal_approx(Rect2()),
+ "clip() with non-enclosed Rect2 should return the expected result.");
+}
+
+TEST_CASE("[Rect2] Enclosing") {
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).encloses(Rect2(0, 300, 100, 100)),
+ "clip() with fully contained Rect2 should return the expected result.");
+ CHECK_MESSAGE(
+ !Rect2(0, 100, 1280, 720).encloses(Rect2(1200, 700, 100, 100)),
+ "clip() with partially contained Rect2 should return the expected result.");
+ CHECK_MESSAGE(
+ !Rect2(0, 100, 1280, 720).encloses(Rect2(-4000, -4000, 100, 100)),
+ "clip() with non-contained Rect2 should return the expected result.");
+}
+
+TEST_CASE("[Rect2] Expanding") {
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).expand(Vector2(500, 600)).is_equal_approx(Rect2(0, 100, 1280, 720)),
+ "expand() with contained Vector2 should return the expected result.");
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).expand(Vector2(0, 0)).is_equal_approx(Rect2(0, 0, 1280, 820)),
+ "expand() with non-contained Vector2 should return the expected result.");
+}
+
+TEST_CASE("[Rect2] Growing") {
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).grow(100).is_equal_approx(Rect2(-100, 0, 1480, 920)),
+ "grow() with positive value should return the expected Rect2.");
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).grow(-100).is_equal_approx(Rect2(100, 200, 1080, 520)),
+ "grow() with negative value should return the expected Rect2.");
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).grow(-4000).is_equal_approx(Rect2(4000, 4100, -6720, -7280)),
+ "grow() with large negative value should return the expected Rect2.");
+
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).grow_individual(100, 200, 300, 400).is_equal_approx(Rect2(-100, -100, 1680, 1320)),
+ "grow_individual() with positive values should return the expected Rect2.");
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).grow_individual(-100, 200, 300, -400).is_equal_approx(Rect2(100, -100, 1480, 520)),
+ "grow_individual() with positive and negative values should return the expected Rect2.");
+
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).grow_margin(MARGIN_TOP, 500).is_equal_approx(Rect2(0, -400, 1280, 1220)),
+ "grow_margin() with positive value should return the expected Rect2.");
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).grow_margin(MARGIN_TOP, -500).is_equal_approx(Rect2(0, 600, 1280, 220)),
+ "grow_margin() with negative value should return the expected Rect2.");
+}
+
+TEST_CASE("[Rect2] Has point") {
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).has_point(Vector2(500, 600)),
+ "has_point() with contained Vector2 should return the expected result.");
+ CHECK_MESSAGE(
+ !Rect2(0, 100, 1280, 720).has_point(Vector2(0, 0)),
+ "has_point() with non-contained Vector2 should return the expected result.");
+
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).has_point(Vector2(0, 110)),
+ "has_point() with positive Vector2 on left edge should return the expected result.");
+ CHECK_MESSAGE(
+ !Rect2(0, 100, 1280, 720).has_point(Vector2(1280, 110)),
+ "has_point() with positive Vector2 on right edge should return the expected result.");
+
+ CHECK_MESSAGE(
+ Rect2(-4000, 100, 1280, 720).has_point(Vector2(-4000, 110)),
+ "has_point() with negative Vector2 on left edge should return the expected result.");
+ CHECK_MESSAGE(
+ !Rect2(-4000, 100, 1280, 720).has_point(Vector2(-2720, 110)),
+ "has_point() with negative Vector2 on right edge should return the expected result.");
+}
+
+TEST_CASE("[Rect2] Intersection") {
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).intersects(Rect2(0, 300, 100, 100)),
+ "intersects() with fully enclosed Rect2 should return the expected result.");
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).intersects(Rect2(1200, 700, 100, 100)),
+ "intersects() with partially enclosed Rect2 should return the expected result.");
+ CHECK_MESSAGE(
+ !Rect2(0, 100, 1280, 720).intersects(Rect2(-4000, -4000, 100, 100)),
+ "intersects() with non-enclosed Rect2 should return the expected result.");
+}
+
+TEST_CASE("[Rect2] Merging") {
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).merge(Rect2(0, 300, 100, 100)).is_equal_approx(Rect2(0, 100, 1280, 720)),
+ "merge() with fully enclosed Rect2 should return the expected result.");
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).merge(Rect2(1200, 700, 100, 100)).is_equal_approx(Rect2(0, 100, 1300, 720)),
+ "merge() with partially enclosed Rect2 should return the expected result.");
+ CHECK_MESSAGE(
+ Rect2(0, 100, 1280, 720).merge(Rect2(-4000, -4000, 100, 100)).is_equal_approx(Rect2(-4000, -4000, 5280, 4820)),
+ "merge() with non-enclosed Rect2 should return the expected result.");
+}
+
+// Rect2i
+
+TEST_CASE("[Rect2i] Constructor methods") {
+ Rect2i recti = Rect2i(0, 100, 1280, 720);
+ Rect2i recti_vector = Rect2i(Vector2i(0, 100), Vector2i(1280, 720));
+ Rect2i recti_copy_recti = Rect2i(recti);
+ Rect2i recti_copy_rect = Rect2i(Rect2(0, 100, 1280, 720));
+
+ CHECK_MESSAGE(
+ recti == recti_vector,
+ "Rect2is created with the same dimensions but by different methods should be equal.");
+ CHECK_MESSAGE(
+ recti == recti_copy_recti,
+ "Rect2is created with the same dimensions but by different methods should be equal.");
+ CHECK_MESSAGE(
+ recti == recti_copy_rect,
+ "Rect2is created with the same dimensions but by different methods should be equal.");
+}
+
+TEST_CASE("[Rect2i] String conversion") {
+ // Note: This also depends on the Vector2 string representation.
+ CHECK_MESSAGE(
+ String(Rect2i(0, 100, 1280, 720)) == "0, 100, 1280, 720",
+ "The string representation should match the expected value.");
+}
+
+TEST_CASE("[Rect2i] Basic getters") {
+ const Rect2i rect = Rect2i(0, 100, 1280, 720);
+ CHECK_MESSAGE(
+ rect.get_position() == Vector2i(0, 100),
+ "get_position() should return the expected value.");
+ CHECK_MESSAGE(
+ rect.get_size() == Vector2i(1280, 720),
+ "get_size() should return the expected value.");
+ CHECK_MESSAGE(
+ rect.get_end() == Vector2i(1280, 820),
+ "get_end() should return the expected value.");
+}
+
+TEST_CASE("[Rect2i] Basic setters") {
+ Rect2i rect = Rect2i(0, 100, 1280, 720);
+ rect.set_end(Vector2i(4000, 4000));
+ CHECK_MESSAGE(
+ rect == Rect2i(0, 100, 4000, 3900),
+ "set_end() should result in the expected Rect2i.");
+
+ rect = Rect2i(0, 100, 1280, 720);
+ rect.set_position(Vector2i(4000, 4000));
+ CHECK_MESSAGE(
+ rect == Rect2i(4000, 4000, 1280, 720),
+ "set_position() should result in the expected Rect2i.");
+
+ rect = Rect2i(0, 100, 1280, 720);
+ rect.set_size(Vector2i(4000, 4000));
+ CHECK_MESSAGE(
+ rect == Rect2i(0, 100, 4000, 4000),
+ "set_size() should result in the expected Rect2i.");
+}
+
+TEST_CASE("[Rect2i] Area getters") {
+ CHECK_MESSAGE(
+ Math::is_equal_approx(Rect2i(0, 100, 1280, 720).get_area(), 921'600),
+ "get_area() should return the expected value.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(Rect2i(0, 100, -1280, -720).get_area(), 921'600),
+ "get_area() should return the expected value.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(Rect2i(0, 100, 1280, -720).get_area(), -921'600),
+ "get_area() should return the expected value.");
+ CHECK_MESSAGE(
+ Math::is_equal_approx(Rect2i(0, 100, -1280, 720).get_area(), -921'600),
+ "get_area() should return the expected value.");
+ CHECK_MESSAGE(
+ Math::is_zero_approx(Rect2i(0, 100, 0, 720).get_area()),
+ "get_area() should return the expected value.");
+
+ CHECK_MESSAGE(
+ !Rect2i(0, 100, 1280, 720).has_no_area(),
+ "has_no_area() should return the expected value on Rect2i with an area.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 0, 500).has_no_area(),
+ "has_no_area() should return the expected value on Rect2i with no area.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 500, 0).has_no_area(),
+ "has_no_area() should return the expected value on Rect2i with no area.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 0, 0).has_no_area(),
+ "has_no_area() should return the expected value on Rect2i with no area.");
+}
+
+TEST_CASE("[Rect2i] Absolute coordinates") {
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).abs() == Rect2i(0, 100, 1280, 720),
+ "abs() should return the expected Rect2i.");
+ CHECK_MESSAGE(
+ Rect2i(0, -100, 1280, 720).abs() == Rect2i(0, -100, 1280, 720),
+ "abs() should return the expected Rect2i.");
+ CHECK_MESSAGE(
+ Rect2i(0, -100, -1280, -720).abs() == Rect2i(-1280, -820, 1280, 720),
+ "abs() should return the expected Rect2i.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, -1280, 720).abs() == Rect2i(-1280, 100, 1280, 720),
+ "abs() should return the expected Rect2i.");
+}
+
+TEST_CASE("[Rect2i] Clipping") {
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).clip(Rect2i(0, 300, 100, 100)) == Rect2i(0, 300, 100, 100),
+ "clip() with fully enclosed Rect2i should return the expected result.");
+ // The resulting Rect2i is 100 pixels high because the first Rect2i is vertically offset by 100 pixels.
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).clip(Rect2i(1200, 700, 100, 100)) == Rect2i(1200, 700, 80, 100),
+ "clip() with partially enclosed Rect2i should return the expected result.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).clip(Rect2i(-4000, -4000, 100, 100)) == Rect2i(),
+ "clip() with non-enclosed Rect2i should return the expected result.");
+}
+
+TEST_CASE("[Rect2i] Enclosing") {
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).encloses(Rect2i(0, 300, 100, 100)),
+ "clip() with fully contained Rect2i should return the expected result.");
+ CHECK_MESSAGE(
+ !Rect2i(0, 100, 1280, 720).encloses(Rect2i(1200, 700, 100, 100)),
+ "clip() with partially contained Rect2i should return the expected result.");
+ CHECK_MESSAGE(
+ !Rect2i(0, 100, 1280, 720).encloses(Rect2i(-4000, -4000, 100, 100)),
+ "clip() with non-contained Rect2i should return the expected result.");
+}
+
+TEST_CASE("[Rect2i] Expanding") {
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).expand(Vector2i(500, 600)) == Rect2i(0, 100, 1280, 720),
+ "expand() with contained Vector2i should return the expected result.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).expand(Vector2i(0, 0)) == Rect2i(0, 0, 1280, 820),
+ "expand() with non-contained Vector2i should return the expected result.");
+}
+
+TEST_CASE("[Rect2i] Growing") {
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).grow(100) == Rect2i(-100, 0, 1480, 920),
+ "grow() with positive value should return the expected Rect2i.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).grow(-100) == Rect2i(100, 200, 1080, 520),
+ "grow() with negative value should return the expected Rect2i.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).grow(-4000) == Rect2i(4000, 4100, -6720, -7280),
+ "grow() with large negative value should return the expected Rect2i.");
+
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).grow_individual(100, 200, 300, 400) == Rect2i(-100, -100, 1680, 1320),
+ "grow_individual() with positive values should return the expected Rect2i.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).grow_individual(-100, 200, 300, -400) == Rect2i(100, -100, 1480, 520),
+ "grow_individual() with positive and negative values should return the expected Rect2i.");
+
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).grow_margin(MARGIN_TOP, 500) == Rect2i(0, -400, 1280, 1220),
+ "grow_margin() with positive value should return the expected Rect2i.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).grow_margin(MARGIN_TOP, -500) == Rect2i(0, 600, 1280, 220),
+ "grow_margin() with negative value should return the expected Rect2i.");
+}
+
+TEST_CASE("[Rect2i] Has point") {
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).has_point(Vector2i(500, 600)),
+ "has_point() with contained Vector2i should return the expected result.");
+ CHECK_MESSAGE(
+ !Rect2i(0, 100, 1280, 720).has_point(Vector2i(0, 0)),
+ "has_point() with non-contained Vector2i should return the expected result.");
+
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).has_point(Vector2(0, 110)),
+ "has_point() with positive Vector2 on left edge should return the expected result.");
+ CHECK_MESSAGE(
+ !Rect2i(0, 100, 1280, 720).has_point(Vector2(1280, 110)),
+ "has_point() with positive Vector2 on right edge should return the expected result.");
+
+ CHECK_MESSAGE(
+ Rect2i(-4000, 100, 1280, 720).has_point(Vector2(-4000, 110)),
+ "has_point() with negative Vector2 on left edge should return the expected result.");
+ CHECK_MESSAGE(
+ !Rect2i(-4000, 100, 1280, 720).has_point(Vector2(-2720, 110)),
+ "has_point() with negative Vector2 on right edge should return the expected result.");
+}
+
+TEST_CASE("[Rect2i] Intersection") {
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).intersects(Rect2i(0, 300, 100, 100)),
+ "intersects() with fully enclosed Rect2i should return the expected result.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).intersects(Rect2i(1200, 700, 100, 100)),
+ "intersects() with partially enclosed Rect2i should return the expected result.");
+ CHECK_MESSAGE(
+ !Rect2i(0, 100, 1280, 720).intersects(Rect2i(-4000, -4000, 100, 100)),
+ "intersects() with non-enclosed Rect2i should return the expected result.");
+}
+
+TEST_CASE("[Rect2i] Merging") {
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).merge(Rect2i(0, 300, 100, 100)) == Rect2i(0, 100, 1280, 720),
+ "merge() with fully enclosed Rect2i should return the expected result.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).merge(Rect2i(1200, 700, 100, 100)) == Rect2i(0, 100, 1300, 720),
+ "merge() with partially enclosed Rect2i should return the expected result.");
+ CHECK_MESSAGE(
+ Rect2i(0, 100, 1280, 720).merge(Rect2i(-4000, -4000, 100, 100)) == Rect2i(-4000, -4000, 5280, 4820),
+ "merge() with non-enclosed Rect2i should return the expected result.");
+}
+} // namespace TestRect2
+
+#endif // TEST_RECT2_H
diff --git a/thirdparty/README.md b/thirdparty/README.md
index f590acaa0b..f4f3aad0fc 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -76,15 +76,11 @@ Files extracted from upstream source:
## doctest
- Upstream: https://github.com/onqtam/doctest
-- Version: 1c8da00 (2.4.0)
+- Version: 8424be5 (2.4.1)
- License: MIT
Extracted from .zip provided. Extracted license and header only.
-Important: Some files have Godot-made changes.
-They are marked with `// -- GODOT start --` and `// -- GODOT end --`
-comments.
-
## enet
- Upstream: http://enet.bespin.org
@@ -435,7 +431,7 @@ Collection of single-file libraries used in Godot components.
## nanosvg
- Upstream: https://github.com/memononen/nanosvg
-- Version: git (25241c5a8f8451d41ab1b02ab2d865b01600d949, 2019)
+- Version: git (3e403ec72a9145cbbcc6c63d94a4caf079aafec2, 2020)
- License: zlib
Files extracted from the upstream source:
diff --git a/thirdparty/doctest/LICENSE.txt b/thirdparty/doctest/LICENSE.txt
index a204721468..50a358cd1b 100644
--- a/thirdparty/doctest/LICENSE.txt
+++ b/thirdparty/doctest/LICENSE.txt
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2016-2019 Viktor Kirilov
+Copyright (c) 2016-2020 Viktor Kirilov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/doctest/doctest.h b/thirdparty/doctest/doctest.h
index e4fed12767..acbe6cd321 100644
--- a/thirdparty/doctest/doctest.h
+++ b/thirdparty/doctest/doctest.h
@@ -4,7 +4,7 @@
//
// doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD
//
-// Copyright (c) 2016-2019 Viktor Kirilov
+// Copyright (c) 2016-2020 Viktor Kirilov
//
// Distributed under the MIT Software License
// See accompanying file LICENSE.txt or copy at
@@ -48,8 +48,8 @@
#define DOCTEST_VERSION_MAJOR 2
#define DOCTEST_VERSION_MINOR 4
-#define DOCTEST_VERSION_PATCH 0
-#define DOCTEST_VERSION_STR "2.4.0"
+#define DOCTEST_VERSION_PATCH 1
+#define DOCTEST_VERSION_STR "2.4.1"
#define DOCTEST_VERSION \
(DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH)
@@ -301,11 +301,15 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
#define DOCTEST_NOINLINE __declspec(noinline)
#define DOCTEST_UNUSED
#define DOCTEST_ALIGNMENT(x)
-#else // MSVC
+#elif DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 5, 0)
+#define DOCTEST_NOINLINE
+#define DOCTEST_UNUSED
+#define DOCTEST_ALIGNMENT(x)
+#else
#define DOCTEST_NOINLINE __attribute__((noinline))
#define DOCTEST_UNUSED __attribute__((unused))
#define DOCTEST_ALIGNMENT(x) __attribute__((aligned(x)))
-#endif // MSVC
+#endif
#ifndef DOCTEST_NORETURN
#define DOCTEST_NORETURN [[noreturn]]
@@ -355,14 +359,20 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
#ifndef DOCTEST_BREAK_INTO_DEBUGGER
// should probably take a look at https://github.com/scottt/debugbreak
-#ifdef DOCTEST_PLATFORM_MAC
-// -- GODOT start --
+#ifdef DOCTEST_PLATFORM_LINUX
+#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))
+// Break at the location of the failing check if possible
+#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
+#else
+#include <signal.h>
+#define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP)
+#endif
+#elif defined(DOCTEST_PLATFORM_MAC)
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__)
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
#else
#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0");
#endif
-// -- GODOT end --
#elif DOCTEST_MSVC
#define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak()
#elif defined(__MINGW32__)
@@ -371,7 +381,7 @@ extern "C" __declspec(dllimport) void __stdcall DebugBreak();
DOCTEST_GCC_SUPPRESS_WARNING_POP
#define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak()
#else // linux
-#define DOCTEST_BREAK_INTO_DEBUGGER() ((void)0)
+#define DOCTEST_BREAK_INTO_DEBUGGER() (static_cast<void>(0))
#endif // linux
#endif // DOCTEST_BREAK_INTO_DEBUGGER
@@ -381,6 +391,9 @@ DOCTEST_GCC_SUPPRESS_WARNING_POP
#endif // DOCTEST_CONFIG_USE_IOSFWD
#ifdef DOCTEST_CONFIG_USE_STD_HEADERS
+#ifndef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
+#define DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
+#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
#include <iosfwd>
#include <cstddef>
#include <ostream>
@@ -746,7 +759,6 @@ struct ContextOptions //!OCLINT too many fields
};
namespace detail {
-#if defined(DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING) || defined(DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS)
template <bool CONDITION, typename TYPE = void>
struct enable_if
{};
@@ -754,7 +766,6 @@ namespace detail {
template <typename TYPE>
struct enable_if<true, TYPE>
{ typedef TYPE type; };
-#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING) || DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
// clang-format off
template<class T> struct remove_reference { typedef T type; };
@@ -763,6 +774,14 @@ namespace detail {
template<class T> struct remove_const { typedef T type; };
template<class T> struct remove_const<const T> { typedef T type; };
+#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS
+ template<class T> struct is_enum : public std::is_enum<T> {};
+ template<class T> struct underlying_type : public std::underlying_type<T> {};
+#else
+ // Use compiler intrinsics
+ template<class T> struct is_enum { constexpr static bool value = __is_enum(T); };
+ template<class T> struct underlying_type { typedef __underlying_type(T) type; };
+#endif
// clang-format on
template <typename T>
@@ -777,12 +796,12 @@ namespace detail {
template<class, class = void>
struct check {
- static constexpr auto value = false;
+ static constexpr bool value = false;
};
template<class T>
struct check<T, decltype(os() << val<T>(), void())> {
- static constexpr auto value = true;
+ static constexpr bool value = true;
};
} // namespace has_insertion_operator_impl
@@ -851,7 +870,7 @@ struct StringMaker<R C::*>
}
};
-template <typename T>
+template <typename T, typename detail::enable_if<!detail::is_enum<T>::value, bool>::type = true>
String toString(const DOCTEST_REF_WRAP(T) value) {
return StringMaker<T>::convert(value);
}
@@ -878,6 +897,12 @@ DOCTEST_INTERFACE String toString(int long long in);
DOCTEST_INTERFACE String toString(int long long unsigned in);
DOCTEST_INTERFACE String toString(std::nullptr_t in);
+template <typename T, typename detail::enable_if<detail::is_enum<T>::value, bool>::type = true>
+String toString(const DOCTEST_REF_WRAP(T) value) {
+ typedef typename detail::underlying_type<T>::type UT;
+ return toString(static_cast<UT>(value));
+}
+
#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0)
// see this issue on why this is needed: https://github.com/onqtam/doctest/issues/183
DOCTEST_INTERFACE String toString(const std::string& in);
@@ -1289,12 +1314,12 @@ namespace detail {
template <class L, class R> struct RelationalComparator<n, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return op(lhs, rhs); } };
// clang-format on
- DOCTEST_BINARY_RELATIONAL_OP(0, eq)
- DOCTEST_BINARY_RELATIONAL_OP(1, ne)
- DOCTEST_BINARY_RELATIONAL_OP(2, gt)
- DOCTEST_BINARY_RELATIONAL_OP(3, lt)
- DOCTEST_BINARY_RELATIONAL_OP(4, ge)
- DOCTEST_BINARY_RELATIONAL_OP(5, le)
+ DOCTEST_BINARY_RELATIONAL_OP(0, doctest::detail::eq)
+ DOCTEST_BINARY_RELATIONAL_OP(1, doctest::detail::ne)
+ DOCTEST_BINARY_RELATIONAL_OP(2, doctest::detail::gt)
+ DOCTEST_BINARY_RELATIONAL_OP(3, doctest::detail::lt)
+ DOCTEST_BINARY_RELATIONAL_OP(4, doctest::detail::ge)
+ DOCTEST_BINARY_RELATIONAL_OP(5, doctest::detail::le)
struct DOCTEST_INTERFACE ResultBuilder : public AssertData
{
@@ -1421,9 +1446,9 @@ namespace detail {
} catch(T ex) { // NOLINT
res = m_translateFunction(ex); //!OCLINT parameter reassignment
return true;
- } catch(...) {} //!OCLINT - empty catch statement
-#endif // DOCTEST_CONFIG_NO_EXCEPTIONS
- ((void)res); // to silence -Wunused-parameter
+ } catch(...) {} //!OCLINT - empty catch statement
+#endif // DOCTEST_CONFIG_NO_EXCEPTIONS
+ static_cast<void>(res); // to silence -Wunused-parameter
return false;
}
@@ -2189,37 +2214,37 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
-#define DOCTEST_WARN_THROWS(...) ((void)0)
-#define DOCTEST_CHECK_THROWS(...) ((void)0)
-#define DOCTEST_REQUIRE_THROWS(...) ((void)0)
-#define DOCTEST_WARN_THROWS_AS(expr, ...) ((void)0)
-#define DOCTEST_CHECK_THROWS_AS(expr, ...) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ((void)0)
-#define DOCTEST_WARN_THROWS_WITH(expr, ...) ((void)0)
-#define DOCTEST_CHECK_THROWS_WITH(expr, ...) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) ((void)0)
-#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) ((void)0)
-#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) ((void)0)
-#define DOCTEST_WARN_NOTHROW(...) ((void)0)
-#define DOCTEST_CHECK_NOTHROW(...) ((void)0)
-#define DOCTEST_REQUIRE_NOTHROW(...) ((void)0)
-
-#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) ((void)0)
-#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) ((void)0)
-#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0)
-#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0)
-#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0)
-#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0)
-#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0)
-#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0)
-#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) ((void)0)
-#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) ((void)0)
-#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) ((void)0)
+#define DOCTEST_WARN_THROWS(...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS(...) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_AS(expr, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_AS(expr, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_WITH(expr, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_WITH(expr, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_NOTHROW(...) (static_cast<void>(0))
+#define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0))
+
+#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
+#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
+#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
#else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
@@ -2310,86 +2335,86 @@ int registerReporter(const char* name, int priority, bool isReporter) {
#define DOCTEST_REGISTER_REPORTER(name, priority, reporter)
#define DOCTEST_REGISTER_LISTENER(name, priority, reporter)
-#define DOCTEST_INFO(x) ((void)0)
-#define DOCTEST_CAPTURE(x) ((void)0)
-#define DOCTEST_ADD_MESSAGE_AT(file, line, x) ((void)0)
-#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) ((void)0)
-#define DOCTEST_ADD_FAIL_AT(file, line, x) ((void)0)
-#define DOCTEST_MESSAGE(x) ((void)0)
-#define DOCTEST_FAIL_CHECK(x) ((void)0)
-#define DOCTEST_FAIL(x) ((void)0)
-
-#define DOCTEST_WARN(...) ((void)0)
-#define DOCTEST_CHECK(...) ((void)0)
-#define DOCTEST_REQUIRE(...) ((void)0)
-#define DOCTEST_WARN_FALSE(...) ((void)0)
-#define DOCTEST_CHECK_FALSE(...) ((void)0)
-#define DOCTEST_REQUIRE_FALSE(...) ((void)0)
-
-#define DOCTEST_WARN_MESSAGE(cond, msg) ((void)0)
-#define DOCTEST_CHECK_MESSAGE(cond, msg) ((void)0)
-#define DOCTEST_REQUIRE_MESSAGE(cond, msg) ((void)0)
-#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) ((void)0)
-#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) ((void)0)
-#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) ((void)0)
-
-#define DOCTEST_WARN_THROWS(...) ((void)0)
-#define DOCTEST_CHECK_THROWS(...) ((void)0)
-#define DOCTEST_REQUIRE_THROWS(...) ((void)0)
-#define DOCTEST_WARN_THROWS_AS(expr, ...) ((void)0)
-#define DOCTEST_CHECK_THROWS_AS(expr, ...) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ((void)0)
-#define DOCTEST_WARN_THROWS_WITH(expr, ...) ((void)0)
-#define DOCTEST_CHECK_THROWS_WITH(expr, ...) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) ((void)0)
-#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) ((void)0)
-#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) ((void)0)
-#define DOCTEST_WARN_NOTHROW(...) ((void)0)
-#define DOCTEST_CHECK_NOTHROW(...) ((void)0)
-#define DOCTEST_REQUIRE_NOTHROW(...) ((void)0)
-
-#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) ((void)0)
-#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) ((void)0)
-#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0)
-#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0)
-#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0)
-#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) ((void)0)
-#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0)
-#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0)
-#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) ((void)0)
-#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) ((void)0)
-#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) ((void)0)
-#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) ((void)0)
-
-#define DOCTEST_WARN_EQ(...) ((void)0)
-#define DOCTEST_CHECK_EQ(...) ((void)0)
-#define DOCTEST_REQUIRE_EQ(...) ((void)0)
-#define DOCTEST_WARN_NE(...) ((void)0)
-#define DOCTEST_CHECK_NE(...) ((void)0)
-#define DOCTEST_REQUIRE_NE(...) ((void)0)
-#define DOCTEST_WARN_GT(...) ((void)0)
-#define DOCTEST_CHECK_GT(...) ((void)0)
-#define DOCTEST_REQUIRE_GT(...) ((void)0)
-#define DOCTEST_WARN_LT(...) ((void)0)
-#define DOCTEST_CHECK_LT(...) ((void)0)
-#define DOCTEST_REQUIRE_LT(...) ((void)0)
-#define DOCTEST_WARN_GE(...) ((void)0)
-#define DOCTEST_CHECK_GE(...) ((void)0)
-#define DOCTEST_REQUIRE_GE(...) ((void)0)
-#define DOCTEST_WARN_LE(...) ((void)0)
-#define DOCTEST_CHECK_LE(...) ((void)0)
-#define DOCTEST_REQUIRE_LE(...) ((void)0)
-
-#define DOCTEST_WARN_UNARY(...) ((void)0)
-#define DOCTEST_CHECK_UNARY(...) ((void)0)
-#define DOCTEST_REQUIRE_UNARY(...) ((void)0)
-#define DOCTEST_WARN_UNARY_FALSE(...) ((void)0)
-#define DOCTEST_CHECK_UNARY_FALSE(...) ((void)0)
-#define DOCTEST_REQUIRE_UNARY_FALSE(...) ((void)0)
+#define DOCTEST_INFO(x) (static_cast<void>(0))
+#define DOCTEST_CAPTURE(x) (static_cast<void>(0))
+#define DOCTEST_ADD_MESSAGE_AT(file, line, x) (static_cast<void>(0))
+#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) (static_cast<void>(0))
+#define DOCTEST_ADD_FAIL_AT(file, line, x) (static_cast<void>(0))
+#define DOCTEST_MESSAGE(x) (static_cast<void>(0))
+#define DOCTEST_FAIL_CHECK(x) (static_cast<void>(0))
+#define DOCTEST_FAIL(x) (static_cast<void>(0))
+
+#define DOCTEST_WARN(...) (static_cast<void>(0))
+#define DOCTEST_CHECK(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE(...) (static_cast<void>(0))
+#define DOCTEST_WARN_FALSE(...) (static_cast<void>(0))
+#define DOCTEST_CHECK_FALSE(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_FALSE(...) (static_cast<void>(0))
+
+#define DOCTEST_WARN_MESSAGE(cond, msg) (static_cast<void>(0))
+#define DOCTEST_CHECK_MESSAGE(cond, msg) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_MESSAGE(cond, msg) (static_cast<void>(0))
+#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
+#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) (static_cast<void>(0))
+
+#define DOCTEST_WARN_THROWS(...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS(...) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_AS(expr, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_AS(expr, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_WITH(expr, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_WITH(expr, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) (static_cast<void>(0))
+#define DOCTEST_WARN_NOTHROW(...) (static_cast<void>(0))
+#define DOCTEST_CHECK_NOTHROW(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_NOTHROW(...) (static_cast<void>(0))
+
+#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, msg) (static_cast<void>(0))
+#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
+#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, msg) (static_cast<void>(0))
+#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
+#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) (static_cast<void>(0))
+
+#define DOCTEST_WARN_EQ(...) (static_cast<void>(0))
+#define DOCTEST_CHECK_EQ(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_EQ(...) (static_cast<void>(0))
+#define DOCTEST_WARN_NE(...) (static_cast<void>(0))
+#define DOCTEST_CHECK_NE(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_NE(...) (static_cast<void>(0))
+#define DOCTEST_WARN_GT(...) (static_cast<void>(0))
+#define DOCTEST_CHECK_GT(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_GT(...) (static_cast<void>(0))
+#define DOCTEST_WARN_LT(...) (static_cast<void>(0))
+#define DOCTEST_CHECK_LT(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_LT(...) (static_cast<void>(0))
+#define DOCTEST_WARN_GE(...) (static_cast<void>(0))
+#define DOCTEST_CHECK_GE(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_GE(...) (static_cast<void>(0))
+#define DOCTEST_WARN_LE(...) (static_cast<void>(0))
+#define DOCTEST_CHECK_LE(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_LE(...) (static_cast<void>(0))
+
+#define DOCTEST_WARN_UNARY(...) (static_cast<void>(0))
+#define DOCTEST_CHECK_UNARY(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_UNARY(...) (static_cast<void>(0))
+#define DOCTEST_WARN_UNARY_FALSE(...) (static_cast<void>(0))
+#define DOCTEST_CHECK_UNARY_FALSE(...) (static_cast<void>(0))
+#define DOCTEST_REQUIRE_UNARY_FALSE(...) (static_cast<void>(0))
#endif // DOCTEST_CONFIG_DISABLE
@@ -3742,8 +3767,8 @@ namespace {
DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations")
void color_to_stream(std::ostream& s, Color::Enum code) {
- ((void)s); // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS
- ((void)code); // for DOCTEST_CONFIG_COLORS_NONE
+ static_cast<void>(s); // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS
+ static_cast<void>(code); // for DOCTEST_CONFIG_COLORS_NONE
#ifdef DOCTEST_CONFIG_COLORS_ANSI
if(g_no_colors ||
(isatty(STDOUT_FILENO) == false && getContextOptions()->force_colors == false))
@@ -3849,7 +3874,28 @@ namespace detail {
#ifdef DOCTEST_IS_DEBUGGER_ACTIVE
bool isDebuggerActive() { return DOCTEST_IS_DEBUGGER_ACTIVE(); }
#else // DOCTEST_IS_DEBUGGER_ACTIVE
-#ifdef DOCTEST_PLATFORM_MAC
+#ifdef DOCTEST_PLATFORM_LINUX
+ class ErrnoGuard {
+ public:
+ ErrnoGuard() : m_oldErrno(errno) {}
+ ~ErrnoGuard() { errno = m_oldErrno; }
+ private:
+ int m_oldErrno;
+ };
+ // See the comments in Catch2 for the reasoning behind this implementation:
+ // https://github.com/catchorg/Catch2/blob/v2.13.1/include/internal/catch_debugger.cpp#L79-L102
+ bool isDebuggerActive() {
+ ErrnoGuard guard;
+ std::ifstream in("/proc/self/status");
+ for(std::string line; std::getline(in, line);) {
+ static const int PREFIX_LEN = 11;
+ if(line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0) {
+ return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';
+ }
+ }
+ return false;
+ }
+#elif defined(DOCTEST_PLATFORM_MAC)
// The following function is taken directly from the following technical note:
// https://developer.apple.com/library/archive/qa/qa1361/_index.html
// Returns true if the current process is being debugged (either
@@ -5460,25 +5506,28 @@ DOCTEST_CLANG_SUPPRESS_WARNING_POP
separator_to_stream();
s << std::dec;
+ auto totwidth = int(std::ceil(log10((std::max(p.numTestCasesPassingFilters, static_cast<unsigned>(p.numAsserts))) + 1)));
+ auto passwidth = int(std::ceil(log10((std::max(p.numTestCasesPassingFilters - p.numTestCasesFailed, static_cast<unsigned>(p.numAsserts - p.numAssertsFailed))) + 1)));
+ auto failwidth = int(std::ceil(log10((std::max(p.numTestCasesFailed, static_cast<unsigned>(p.numAssertsFailed))) + 1)));
const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0;
- s << Color::Cyan << "[doctest] " << Color::None << "test cases: " << std::setw(6)
+ s << Color::Cyan << "[doctest] " << Color::None << "test cases: " << std::setw(totwidth)
<< p.numTestCasesPassingFilters << " | "
<< ((p.numTestCasesPassingFilters == 0 || anythingFailed) ? Color::None :
Color::Green)
- << std::setw(6) << p.numTestCasesPassingFilters - p.numTestCasesFailed << " passed"
+ << std::setw(passwidth) << p.numTestCasesPassingFilters - p.numTestCasesFailed << " passed"
<< Color::None << " | " << (p.numTestCasesFailed > 0 ? Color::Red : Color::None)
- << std::setw(6) << p.numTestCasesFailed << " failed" << Color::None << " | ";
+ << std::setw(failwidth) << p.numTestCasesFailed << " failed" << Color::None << " |";
if(opt.no_skipped_summary == false) {
const int numSkipped = p.numTestCases - p.numTestCasesPassingFilters;
- s << (numSkipped == 0 ? Color::None : Color::Yellow) << std::setw(6) << numSkipped
+ s << " " << (numSkipped == 0 ? Color::None : Color::Yellow) << numSkipped
<< " skipped" << Color::None;
}
s << "\n";
- s << Color::Cyan << "[doctest] " << Color::None << "assertions: " << std::setw(6)
+ s << Color::Cyan << "[doctest] " << Color::None << "assertions: " << std::setw(totwidth)
<< p.numAsserts << " | "
<< ((p.numAsserts == 0 || anythingFailed) ? Color::None : Color::Green)
- << std::setw(6) << (p.numAsserts - p.numAssertsFailed) << " passed" << Color::None
- << " | " << (p.numAssertsFailed > 0 ? Color::Red : Color::None) << std::setw(6)
+ << std::setw(passwidth) << (p.numAsserts - p.numAssertsFailed) << " passed" << Color::None
+ << " | " << (p.numAssertsFailed > 0 ? Color::Red : Color::None) << std::setw(failwidth)
<< p.numAssertsFailed << " failed" << Color::None << " |\n";
s << Color::Cyan << "[doctest] " << Color::None
<< "Status: " << (p.numTestCasesFailed > 0 ? Color::Red : Color::Green)
diff --git a/thirdparty/doctest/patches/fix-arm64-mac.patch b/thirdparty/doctest/patches/fix-arm64-mac.patch
deleted file mode 100644
index f78014534f..0000000000
--- a/thirdparty/doctest/patches/fix-arm64-mac.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-diff --git a/thirdparty/doctest/doctest.h b/thirdparty/doctest/doctest.h
-index 9444698286..e4fed12767 100644
---- a/thirdparty/doctest/doctest.h
-+++ b/thirdparty/doctest/doctest.h
-@@ -356,7 +356,13 @@ DOCTEST_MSVC_SUPPRESS_WARNING(26812) // Prefer 'enum class' over 'enum'
- #ifndef DOCTEST_BREAK_INTO_DEBUGGER
- // should probably take a look at https://github.com/scottt/debugbreak
- #ifdef DOCTEST_PLATFORM_MAC
-+// -- GODOT start --
-+#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__)
- #define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :)
-+#else
-+#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0");
-+#endif
-+// -- GODOT end --
- #elif DOCTEST_MSVC
- #define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak()
- #elif defined(__MINGW32__)
diff --git a/thirdparty/nanosvg/nanosvg.h b/thirdparty/nanosvg/nanosvg.h
index e5f6900614..4c03ee5893 100644
--- a/thirdparty/nanosvg/nanosvg.h
+++ b/thirdparty/nanosvg/nanosvg.h
@@ -225,11 +225,6 @@ static int nsvg__isdigit(char c)
return c >= '0' && c <= '9';
}
-static int nsvg__isnum(char c)
-{
- return strchr("0123456789+-.eE", c) != 0;
-}
-
static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; }
static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; }
@@ -736,9 +731,11 @@ static void nsvg__lineTo(NSVGparser* p, float x, float y)
static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y)
{
- nsvg__addPoint(p, cpx1, cpy1);
- nsvg__addPoint(p, cpx2, cpy2);
- nsvg__addPoint(p, x, y);
+ if (p->npts > 0) {
+ nsvg__addPoint(p, cpx1, cpy1);
+ nsvg__addPoint(p, cpx2, cpy2);
+ nsvg__addPoint(p, x, y);
+ }
}
static NSVGattrib* nsvg__getAttr(NSVGparser* p)
@@ -808,7 +805,9 @@ static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig,
static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id)
{
NSVGgradientData* grad = p->gradients;
- while (grad) {
+ if (id == NULL || *id == '\0')
+ return NULL;
+ while (grad != NULL) {
if (strcmp(grad->id, id) == 0)
return grad;
grad = grad->next;
@@ -825,19 +824,26 @@ static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const f
NSVGgradient* grad;
float ox, oy, sw, sh, sl;
int nstops = 0;
+ int refIter;
data = nsvg__findGradientData(p, id);
if (data == NULL) return NULL;
// TODO: use ref to fill in all unset values too.
ref = data;
+ refIter = 0;
while (ref != NULL) {
+ NSVGgradientData* nextRef = NULL;
if (stops == NULL && ref->stops != NULL) {
stops = ref->stops;
nstops = ref->nstops;
break;
}
- ref = nsvg__findGradientData(p, ref->ref);
+ nextRef = nsvg__findGradientData(p, ref->ref);
+ if (nextRef == ref) break; // prevent infite loops on malformed data
+ ref = nextRef;
+ refIter++;
+ if (refIter > 32) break; // prevent infite loops on malformed data
}
if (stops == NULL) return NULL;
@@ -1040,6 +1046,10 @@ static void nsvg__addPath(NSVGparser* p, char closed)
if (closed)
nsvg__lineTo(p, p->pts[0], p->pts[1]);
+ // Expect 1 + N*3 points (N = number of cubic bezier segments).
+ if ((p->npts % 3) != 1)
+ return;
+
path = (NSVGpath*)malloc(sizeof(NSVGpath));
if (path == NULL) goto error;
memset(path, 0, sizeof(NSVGpath));
@@ -1458,6 +1468,15 @@ static int nsvg__parseUnits(const char* units)
return NSVG_UNITS_USER;
}
+static int nsvg__isCoordinate(const char* s)
+{
+ // optional sign
+ if (*s == '-' || *s == '+')
+ s++;
+ // must have at least one digit, or start by a dot
+ return (nsvg__isdigit(*s) || *s == '.');
+}
+
static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str)
{
NSVGcoordinate coord = {0, NSVG_UNITS_USER};
@@ -1597,25 +1616,32 @@ static int nsvg__parseRotate(float* xform, const char* str)
static void nsvg__parseTransform(float* xform, const char* str)
{
float t[6];
+ int len;
nsvg__xformIdentity(xform);
while (*str)
{
if (strncmp(str, "matrix", 6) == 0)
- str += nsvg__parseMatrix(t, str);
+ len = nsvg__parseMatrix(t, str);
else if (strncmp(str, "translate", 9) == 0)
- str += nsvg__parseTranslate(t, str);
+ len = nsvg__parseTranslate(t, str);
else if (strncmp(str, "scale", 5) == 0)
- str += nsvg__parseScale(t, str);
+ len = nsvg__parseScale(t, str);
else if (strncmp(str, "rotate", 6) == 0)
- str += nsvg__parseRotate(t, str);
+ len = nsvg__parseRotate(t, str);
else if (strncmp(str, "skewX", 5) == 0)
- str += nsvg__parseSkewX(t, str);
+ len = nsvg__parseSkewX(t, str);
else if (strncmp(str, "skewY", 5) == 0)
- str += nsvg__parseSkewY(t, str);
+ len = nsvg__parseSkewY(t, str);
else{
++str;
continue;
}
+ if (len != 0) {
+ str += len;
+ } else {
+ ++str;
+ continue;
+ }
nsvg__xformPremultiply(xform, t);
}
@@ -1876,8 +1902,11 @@ static int nsvg__getArgsPerElement(char cmd)
case 'a':
case 'A':
return 7;
+ case 'z':
+ case 'Z':
+ return 0;
}
- return 0;
+ return -1;
}
static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
@@ -2187,6 +2216,7 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
float args[10];
int nargs;
int rargs = 0;
+ char initPoint;
float cpx, cpy, cpx2, cpy2;
const char* tmp[4];
char closedFlag;
@@ -2209,13 +2239,14 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
nsvg__resetPath(p);
cpx = 0; cpy = 0;
cpx2 = 0; cpy2 = 0;
+ initPoint = 0;
closedFlag = 0;
nargs = 0;
while (*s) {
s = nsvg__getNextPathItem(s, item);
if (!*item) break;
- if (nsvg__isnum(item[0])) {
+ if (cmd != '\0' && nsvg__isCoordinate(item)) {
if (nargs < 10)
args[nargs++] = (float)nsvg__atof(item);
if (nargs >= rargs) {
@@ -2228,6 +2259,7 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
cmd = (cmd == 'm') ? 'l' : 'L';
rargs = nsvg__getArgsPerElement(cmd);
cpx2 = cpx; cpy2 = cpy;
+ initPoint = 1;
break;
case 'l':
case 'L':
@@ -2277,7 +2309,6 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
}
} else {
cmd = item[0];
- rargs = nsvg__getArgsPerElement(cmd);
if (cmd == 'M' || cmd == 'm') {
// Commit path.
if (p->npts > 0)
@@ -2286,7 +2317,11 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
nsvg__resetPath(p);
closedFlag = 0;
nargs = 0;
- } else if (cmd == 'Z' || cmd == 'z') {
+ } else if (initPoint == 0) {
+ // Do not allow other commands until initial point has been set (moveTo called once).
+ cmd = '\0';
+ }
+ if (cmd == 'Z' || cmd == 'z') {
closedFlag = 1;
// Commit path.
if (p->npts > 0) {
@@ -2302,6 +2337,12 @@ static void nsvg__parsePath(NSVGparser* p, const char** attr)
closedFlag = 0;
nargs = 0;
}
+ rargs = nsvg__getArgsPerElement(cmd);
+ if (rargs == -1) {
+ // Command not recognized
+ cmd = '\0';
+ rargs = 0;
+ }
}
}
// Commit path.