summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/arkit/arkit_interface.mm12
-rw-r--r--modules/assimp/SCsub13
-rwxr-xr-x[-rw-r--r--]modules/assimp/godot_update_assimp.sh3
-rw-r--r--modules/bullet/rigid_body_bullet.h2
-rw-r--r--modules/bullet/space_bullet.cpp4
-rw-r--r--modules/gdnative/gdnative/string.cpp14
-rw-r--r--modules/gdnative/gdnative/vector2.cpp8
-rw-r--r--modules/gdnative/gdnative/vector3.cpp8
-rw-r--r--modules/gdnative/gdnative_api.json48
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.cpp45
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.h2
-rw-r--r--modules/gdnative/include/gdnative/string.h2
-rw-r--r--modules/gdnative/include/gdnative/vector2.h2
-rw-r--r--modules/gdnative/include/gdnative/vector3.h2
-rw-r--r--modules/gdnative/include/nativescript/godot_nativescript.h6
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml3
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp36
-rw-r--r--modules/gdscript/gdscript_tokenizer.h6
-rw-r--r--modules/mono/csharp_script.cpp1
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs38
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs17
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs11
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs65
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/MonoDevelopInstance.cs22
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs5
-rw-r--r--modules/mono/glue/Managed/Files/Basis.cs3
-rw-r--r--modules/mono/glue/Managed/Files/NodePath.cs2
-rw-r--r--modules/mono/glue/Managed/Files/Quat.cs12
-rw-r--r--modules/mono/glue/Managed/Files/StringExtensions.cs60
-rw-r--r--modules/mono/glue/Managed/Files/Transform.cs2
-rw-r--r--modules/mono/glue/Managed/Files/Transform2D.cs7
-rw-r--r--modules/mono/glue/Managed/Files/Vector2.cs2
-rw-r--r--modules/mono/glue/Managed/Files/Vector3.cs2
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp38
-rw-r--r--modules/mono/mono_gd/gd_mono.h13
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.cpp15
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp17
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h2
-rw-r--r--modules/websocket/wsl_client.cpp12
42 files changed, 414 insertions, 154 deletions
diff --git a/modules/arkit/arkit_interface.mm b/modules/arkit/arkit_interface.mm
index de58f93276..68844c54c2 100644
--- a/modules/arkit/arkit_interface.mm
+++ b/modules/arkit/arkit_interface.mm
@@ -430,7 +430,7 @@ void ARKitInterface::process() {
// get some info about our screen and orientation
Size2 screen_size = OS::get_singleton()->get_window_size();
- UIDeviceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
+ UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
// Grab our camera image for our backbuffer
CVPixelBufferRef pixelBuffer = current_frame.capturedImage;
@@ -531,7 +531,7 @@ void ARKitInterface::process() {
// we need to invert this, probably row v.s. column notation
affine_transform = CGAffineTransformInvert(affine_transform);
- if (orientation != UIDeviceOrientationPortrait) {
+ if (orientation != UIInterfaceOrientationPortrait) {
affine_transform.b = -affine_transform.b;
affine_transform.d = -affine_transform.d;
affine_transform.ty = 1.0 - affine_transform.ty;
@@ -582,28 +582,28 @@ void ARKitInterface::process() {
// copy our current frame transform
matrix_float4x4 m44 = camera.transform;
- if (orientation == UIDeviceOrientationLandscapeLeft) {
+ if (orientation == UIInterfaceOrientationLandscapeLeft) {
transform.basis.elements[0].x = m44.columns[0][0];
transform.basis.elements[1].x = m44.columns[0][1];
transform.basis.elements[2].x = m44.columns[0][2];
transform.basis.elements[0].y = m44.columns[1][0];
transform.basis.elements[1].y = m44.columns[1][1];
transform.basis.elements[2].y = m44.columns[1][2];
- } else if (orientation == UIDeviceOrientationPortrait) {
+ } else if (orientation == UIInterfaceOrientationPortrait) {
transform.basis.elements[0].x = m44.columns[1][0];
transform.basis.elements[1].x = m44.columns[1][1];
transform.basis.elements[2].x = m44.columns[1][2];
transform.basis.elements[0].y = -m44.columns[0][0];
transform.basis.elements[1].y = -m44.columns[0][1];
transform.basis.elements[2].y = -m44.columns[0][2];
- } else if (orientation == UIDeviceOrientationLandscapeRight) {
+ } else if (orientation == UIInterfaceOrientationLandscapeRight) {
transform.basis.elements[0].x = -m44.columns[0][0];
transform.basis.elements[1].x = -m44.columns[0][1];
transform.basis.elements[2].x = -m44.columns[0][2];
transform.basis.elements[0].y = -m44.columns[1][0];
transform.basis.elements[1].y = -m44.columns[1][1];
transform.basis.elements[2].y = -m44.columns[1][2];
- } else if (orientation == UIDeviceOrientationPortraitUpsideDown) {
+ } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
// this may not be correct
transform.basis.elements[0].x = m44.columns[1][0];
transform.basis.elements[1].x = m44.columns[1][1];
diff --git a/modules/assimp/SCsub b/modules/assimp/SCsub
index d8ef866bec..275f1ff5e9 100644
--- a/modules/assimp/SCsub
+++ b/modules/assimp/SCsub
@@ -9,6 +9,7 @@ env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/include'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code/Importer/IFC'])
env_assimp.Prepend(CPPPATH=['#thirdparty/misc'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code'])
+env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/common'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/irrXML/'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/unzip/'])
env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/code/Importer/STEPParser'])
@@ -65,11 +66,11 @@ env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_STEP_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_IFC_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_XGL_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_ASSBIN_IMPORTER'])
-env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_C4D_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_3MF_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_X3D_IMPORTER'])
-
+env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF_IMPORTER'])
+env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF2_IMPORTER'])
env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_SINGLETHREADED'])
if(env['platform'] == 'windows'):
@@ -84,7 +85,13 @@ elif(env['platform'] == 'osx'):
env_thirdparty = env_assimp.Clone()
env_thirdparty.disable_warnings()
-env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/Common/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/PostProcessing/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/Material/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/FBX/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/MMD/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/glTF/*.cpp'))
+env_thirdparty.add_source_files(env.modules_sources, Glob('#thirdparty/assimp/code/glTF2/*.cpp'))
# Godot's own source files
env_assimp.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/assimp/godot_update_assimp.sh b/modules/assimp/godot_update_assimp.sh
index dcf1e6d4a2..ff8ff59e97 100644..100755
--- a/modules/assimp/godot_update_assimp.sh
+++ b/modules/assimp/godot_update_assimp.sh
@@ -254,8 +254,9 @@ rm -rf contrib/irrXML
rm -rf contrib/Open3DGC
rm -rf contrib/openddlparser
rm -rf contrib/poly2tri
-rm -rf contrib/rapidjson
+#rm -rf contrib/rapidjson
rm -rf contrib/unzip
rm -rf contrib/zip
rm -rf contrib/stb_image
rm .travis*
+
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index 2c9bdb8b0b..f63148092f 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -305,7 +305,7 @@ public:
void reload_axis_lock();
/// Doc:
- /// http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Anti_tunneling_by_Motion_Clamping
+ /// https://web.archive.org/web/20180404091446/http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Anti_tunneling_by_Motion_Clamping
void set_continuous_collision_detection(bool p_enable);
bool is_continuous_collision_detection_enabled() const;
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index 738b415d16..9d632aaf83 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -581,6 +581,10 @@ void SpaceBullet::create_empty_world(bool p_create_soft_world) {
} else {
world_mem = malloc(sizeof(btDiscreteDynamicsWorld));
}
+ if (!world_mem) {
+ ERR_EXPLAIN("Out of memory");
+ ERR_FAIL();
+ }
if (p_create_soft_world) {
collisionConfiguration = bulletnew(GodotSoftCollisionConfiguration(static_cast<btDiscreteDynamicsWorld *>(world_mem)));
diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp
index 913c57eb56..9086121940 100644
--- a/modules/gdnative/gdnative/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -186,6 +186,20 @@ godot_bool GDAPI godot_string_ends_with(const godot_string *p_self, const godot_
return self->ends_with(*string);
}
+godot_int GDAPI godot_string_count(const godot_string *p_self, godot_string p_what, godot_int p_from, godot_int p_to) {
+ const String *self = (const String *)p_self;
+ String *what = (String *)&p_what;
+
+ return self->count(*what, p_from, p_to);
+}
+
+godot_int GDAPI godot_string_countn(const godot_string *p_self, godot_string p_what, godot_int p_from, godot_int p_to) {
+ const String *self = (const String *)p_self;
+ String *what = (String *)&p_what;
+
+ return self->countn(*what, p_from, p_to);
+}
+
godot_int GDAPI godot_string_find(const godot_string *p_self, godot_string p_what) {
const String *self = (const String *)p_self;
String *what = (String *)&p_what;
diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp
index a2ac61b35e..d82f2c692d 100644
--- a/modules/gdnative/gdnative/vector2.cpp
+++ b/modules/gdnative/gdnative/vector2.cpp
@@ -77,6 +77,14 @@ godot_bool GDAPI godot_vector2_is_normalized(const godot_vector2 *p_self) {
return self->is_normalized();
}
+godot_vector2 GDAPI godot_vector2_direction_to(const godot_vector2 *p_self, const godot_vector2 *p_to) {
+ godot_vector2 dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *to = (const Vector2 *)p_to;
+ *((Vector2 *)&dest) = self->direction_to(*to);
+ return dest;
+}
+
godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_self, const godot_vector2 *p_to) {
const Vector2 *self = (const Vector2 *)p_self;
const Vector2 *to = (const Vector2 *)p_to;
diff --git a/modules/gdnative/gdnative/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp
index 894683ab38..15a8ef9a2e 100644
--- a/modules/gdnative/gdnative/vector3.cpp
+++ b/modules/gdnative/gdnative/vector3.cpp
@@ -182,6 +182,14 @@ godot_vector3 GDAPI godot_vector3_ceil(const godot_vector3 *p_self) {
return dest;
}
+godot_vector3 GDAPI godot_vector3_direction_to(const godot_vector3 *p_self, const godot_vector3 *p_to) {
+ godot_vector3 dest;
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *to = (const Vector3 *)p_to;
+ *((Vector3 *)&dest) = self->direction_to(*to);
+ return dest;
+}
+
godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_self, const godot_vector3 *p_b) {
const Vector3 *self = (const Vector3 *)p_self;
const Vector3 *b = (const Vector3 *)p_b;
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 6c12ee6534..03258584ce 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -44,6 +44,42 @@
["const godot_vector2 *", "p_to"],
["const godot_real", "p_delta"]
]
+ },
+ {
+ "name": "godot_string_count",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"],
+ ["godot_int", "p_from"],
+ ["godot_int", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_string_countn",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_string *", "p_self"],
+ ["godot_string", "p_what"],
+ ["godot_int", "p_from"],
+ ["godot_int", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_vector3_direction_to",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"],
+ ["const godot_vector3 *", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_vector2_direction_to",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"],
+ ["const godot_vector2 *", "p_to"]
+ ]
}
]
},
@@ -6512,24 +6548,24 @@
"name": "godot_net_bind_stream_peer",
"return_type": "void",
"arguments": [
- ["godot_object *", "p_obj"],
- ["const godot_net_stream_peer *", "p_interface"]
+ ["godot_object *", "p_obj"],
+ ["const godot_net_stream_peer *", "p_interface"]
]
},
{
"name": "godot_net_bind_packet_peer",
"return_type": "void",
"arguments": [
- ["godot_object *", "p_obj"],
- ["const godot_net_packet_peer *", "p_interface"]
+ ["godot_object *", "p_obj"],
+ ["const godot_net_packet_peer *", "p_interface"]
]
},
{
"name": "godot_net_bind_multiplayer_peer",
"return_type": "void",
"arguments": [
- ["godot_object *", "p_obj"],
- ["const godot_net_multiplayer_peer *", "p_interface"]
+ ["godot_object *", "p_obj"],
+ ["const godot_net_multiplayer_peer *", "p_interface"]
]
}
]
diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp
index e2a69b1635..5d272a6cdc 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.cpp
+++ b/modules/gdnative/gdnative_library_editor_plugin.cpp
@@ -66,10 +66,18 @@ void GDNativeLibraryEditor::_update_tree() {
tree->clear();
TreeItem *root = tree->create_item();
- for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) {
+ PopupMenu *filter_list = filter->get_popup();
+ String text = "";
+ for (int i = 0; i < filter_list->get_item_count(); i++) {
- if (showing_platform != E->key() && showing_platform != "All")
+ if (!filter_list->is_item_checked(i)) {
continue;
+ }
+ Map<String, NativePlatformConfig>::Element *E = platforms.find(filter_list->get_item_metadata(i));
+ if (!text.empty()) {
+ text += ", ";
+ }
+ text += E->get().name;
TreeItem *platform = tree->create_item(root);
platform->set_text(0, E->get().name);
@@ -119,6 +127,7 @@ void GDNativeLibraryEditor::_update_tree() {
platform->set_collapsed(collapsed_items.find(E->get().name) != NULL);
}
+ filter->set_text(text);
}
void GDNativeLibraryEditor::_on_item_button(Object *item, int column, int id) {
@@ -162,9 +171,10 @@ void GDNativeLibraryEditor::_on_dependencies_selected(const PoolStringArray &fil
_set_target_value(file_dialog->get_meta("section"), file_dialog->get_meta("target"), files);
}
-void GDNativeLibraryEditor::_on_filter_selected(int id) {
+void GDNativeLibraryEditor::_on_filter_selected(int index) {
- showing_platform = filter->get_item_metadata(id);
+ PopupMenu *filter_list = filter->get_popup();
+ filter_list->set_item_checked(index, !filter_list->is_item_checked(index));
_update_tree();
}
@@ -265,8 +275,6 @@ void GDNativeLibraryEditor::_translate_to_config_file() {
GDNativeLibraryEditor::GDNativeLibraryEditor() {
- showing_platform = "All";
-
{ // Define platforms
NativePlatformConfig platform_windows;
platform_windows.name = "Windows";
@@ -336,20 +344,21 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
Label *label = memnew(Label);
label->set_text(TTR("Platform:"));
hbox->add_child(label);
- filter = memnew(OptionButton);
- hbox->add_child(filter);
+ filter = memnew(MenuButton);
filter->set_h_size_flags(SIZE_EXPAND_FILL);
+ filter->set_text_align(filter->ALIGN_LEFT);
+ hbox->add_child(filter);
+ PopupMenu *filter_list = filter->get_popup();
+ filter_list->set_hide_on_checkable_item_selection(false);
int idx = 0;
- filter->add_item(TTR("All"), idx);
- filter->set_item_metadata(idx, "All");
- idx += 1;
for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) {
- filter->add_item(E->get().name, idx);
- filter->set_item_metadata(idx, E->key());
+ filter_list->add_check_item(E->get().name, idx);
+ filter_list->set_item_metadata(idx, E->key());
+ filter_list->set_item_checked(idx, true);
idx += 1;
}
- filter->connect("item_selected", this, "_on_filter_selected");
+ filter_list->connect("index_pressed", this, "_on_filter_selected");
tree = memnew(Tree);
container->add_child(tree);
@@ -387,11 +396,9 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
void GDNativeLibraryEditorPlugin::edit(Object *p_node) {
- if (Object::cast_to<GDNativeLibrary>(p_node)) {
- library_editor->edit(Object::cast_to<GDNativeLibrary>(p_node));
- library_editor->show();
- } else
- library_editor->hide();
+ Ref<GDNativeLibrary> new_library = Object::cast_to<GDNativeLibrary>(p_node);
+ if (new_library.is_valid())
+ library_editor->edit(new_library);
}
bool GDNativeLibraryEditorPlugin::handles(Object *p_node) const {
diff --git a/modules/gdnative/gdnative_library_editor_plugin.h b/modules/gdnative/gdnative_library_editor_plugin.h
index e7d50ba29f..8c1449f55a 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.h
+++ b/modules/gdnative/gdnative_library_editor_plugin.h
@@ -61,7 +61,7 @@ class GDNativeLibraryEditor : public Control {
};
Tree *tree;
- OptionButton *filter;
+ MenuButton *filter;
EditorFileDialog *file_dialog;
ConfirmationDialog *new_architecture_dialog;
LineEdit *new_architecture_input;
diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h
index f045ac9d58..7500d70f20 100644
--- a/modules/gdnative/include/gdnative/string.h
+++ b/modules/gdnative/include/gdnative/string.h
@@ -102,6 +102,8 @@ godot_bool GDAPI godot_string_begins_with_char_array(const godot_string *p_self,
godot_array GDAPI godot_string_bigrams(const godot_string *p_self);
godot_string GDAPI godot_string_chr(wchar_t p_character);
godot_bool GDAPI godot_string_ends_with(const godot_string *p_self, const godot_string *p_string);
+godot_int GDAPI godot_string_count(const godot_string *p_self, godot_string p_what, godot_int p_from, godot_int p_to);
+godot_int GDAPI godot_string_countn(const godot_string *p_self, godot_string p_what, godot_int p_from, godot_int p_to);
godot_int GDAPI godot_string_find(const godot_string *p_self, godot_string p_what);
godot_int GDAPI godot_string_find_from(const godot_string *p_self, godot_string p_what, godot_int p_from);
godot_int GDAPI godot_string_findmk(const godot_string *p_self, const godot_array *p_keys);
diff --git a/modules/gdnative/include/gdnative/vector2.h b/modules/gdnative/include/gdnative/vector2.h
index 7a5ae6afa9..15a6c80887 100644
--- a/modules/gdnative/include/gdnative/vector2.h
+++ b/modules/gdnative/include/gdnative/vector2.h
@@ -71,6 +71,8 @@ godot_real GDAPI godot_vector2_length_squared(const godot_vector2 *p_self);
godot_bool GDAPI godot_vector2_is_normalized(const godot_vector2 *p_self);
+godot_vector2 GDAPI godot_vector2_direction_to(const godot_vector2 *p_self, const godot_vector2 *p_b);
+
godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_self, const godot_vector2 *p_to);
godot_real GDAPI godot_vector2_distance_squared_to(const godot_vector2 *p_self, const godot_vector2 *p_to);
diff --git a/modules/gdnative/include/gdnative/vector3.h b/modules/gdnative/include/gdnative/vector3.h
index 70ec6422ac..ee7d029028 100644
--- a/modules/gdnative/include/gdnative/vector3.h
+++ b/modules/gdnative/include/gdnative/vector3.h
@@ -106,6 +106,8 @@ godot_vector3 GDAPI godot_vector3_floor(const godot_vector3 *p_self);
godot_vector3 GDAPI godot_vector3_ceil(const godot_vector3 *p_self);
+godot_vector3 GDAPI godot_vector3_direction_to(const godot_vector3 *p_self, const godot_vector3 *p_b);
+
godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_self, const godot_vector3 *p_b);
godot_real GDAPI godot_vector3_distance_squared_to(const godot_vector3 *p_self, const godot_vector3 *p_b);
diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h
index f3b9f7fb31..7f52f5736c 100644
--- a/modules/gdnative/include/nativescript/godot_nativescript.h
+++ b/modules/gdnative/include/nativescript/godot_nativescript.h
@@ -56,7 +56,7 @@ typedef enum {
GODOT_PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
GODOT_PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease)
GODOT_PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer)
- GODOT_PROPERTY_HINT_SPRITE_FRAME,
+ GODOT_PROPERTY_HINT_SPRITE_FRAME, // FIXME: Obsolete: drop whenever we can break compat
GODOT_PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
GODOT_PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags)
GODOT_PROPERTY_HINT_LAYERS_2D_RENDER,
@@ -98,8 +98,8 @@ typedef enum {
GODOT_PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings
GODOT_PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor
GODOT_PROPERTY_USAGE_CATEGORY = 256,
- GODOT_PROPERTY_USAGE_STORE_IF_NONZERO = 512, //only store if nonzero
- GODOT_PROPERTY_USAGE_STORE_IF_NONONE = 1024, //only store if false
+ GODOT_PROPERTY_USAGE_STORE_IF_NONZERO = 512, // FIXME: Obsolete: drop whenever we can break compat
+ GODOT_PROPERTY_USAGE_STORE_IF_NONONE = 1024, // FIXME: Obsolete: drop whenever we can break compat
GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE = 2048,
GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED = 4096,
GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE = 8192,
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 62a3794c6d..ad47323613 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -322,6 +322,7 @@
<description>
The natural exponential function. It raises the mathematical constant [b]e[/b] to the power of [code]s[/code] and returns it.
[b]e[/b] has an approximate value of 2.71828.
+ For exponents to other bases use the method [method pow].
[codeblock]
a = exp(2) # Approximately 7.39
[/codeblock]
@@ -1095,7 +1096,7 @@
<argument index="0" name="step" type="float">
</argument>
<description>
- Returns the position of the first non-zero digit, after the decimal point.
+ Returns the position of the first non-zero digit, after the decimal point. Note that the maximum return value is 10, which is a design decision in the implementation.
[codeblock]
# n is 0
n = step_decimals(5)
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index 95715ab648..59b53b5f9a 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -517,7 +517,22 @@ void GDScriptTokenizerText::_advance() {
INCPOS(1);
column = 1;
int i = 0;
- while (GETCHAR(i) == ' ' || GETCHAR(i) == '\t') {
+ while (true) {
+ if (GETCHAR(i) == ' ') {
+ if (file_indent_type == INDENT_NONE) file_indent_type = INDENT_SPACES;
+ if (file_indent_type != INDENT_SPACES) {
+ _make_error("Spaces used for indentation in tab-indented file!");
+ return;
+ }
+ } else if (GETCHAR(i) == '\t') {
+ if (file_indent_type == INDENT_NONE) file_indent_type = INDENT_TABS;
+ if (file_indent_type != INDENT_TABS) {
+ _make_error("Tabs used for indentation in space-indented file!");
+ return;
+ }
+ } else {
+ break; // not indentation anymore
+ }
i++;
}
@@ -555,9 +570,25 @@ void GDScriptTokenizerText::_advance() {
column = 1;
line++;
int i = 0;
- while (GETCHAR(i) == ' ' || GETCHAR(i) == '\t') {
+ while (true) {
+ if (GETCHAR(i) == ' ') {
+ if (file_indent_type == INDENT_NONE) file_indent_type = INDENT_SPACES;
+ if (file_indent_type != INDENT_SPACES) {
+ _make_error("Spaces used for indentation in tab-indented file!");
+ return;
+ }
+ } else if (GETCHAR(i) == '\t') {
+ if (file_indent_type == INDENT_NONE) file_indent_type = INDENT_TABS;
+ if (file_indent_type != INDENT_TABS) {
+ _make_error("Tabs used for indentation in space-indented file!");
+ return;
+ }
+ } else {
+ break; // not indentation anymore
+ }
i++;
}
+
_make_newline(i);
return;
@@ -1082,6 +1113,7 @@ void GDScriptTokenizerText::set_code(const String &p_code) {
ignore_warnings = false;
#endif // DEBUG_ENABLED
last_error = "";
+ file_indent_type = INDENT_NONE;
for (int i = 0; i < MAX_LOOKAHEAD + 1; i++)
_advance();
}
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index 7b977ff67c..89d586b912 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -222,6 +222,12 @@ class GDScriptTokenizerText : public GDScriptTokenizer {
int tk_rb_pos;
String last_error;
bool error_flag;
+ enum {
+ INDENT_NONE,
+ INDENT_SPACES,
+ INDENT_TABS,
+ } file_indent_type;
+
#ifdef DEBUG_ENABLED
Vector<Pair<int, String> > warning_skips;
Set<String> warning_global_skips;
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 078a490b22..846c84d222 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -629,7 +629,6 @@ void CSharpLanguage::frame() {
if (exc) {
GDMonoUtils::debug_unhandled_exception(exc);
- GD_UNREACHABLE();
}
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
index 1edc426e00..233aab45b3 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
@@ -85,7 +85,7 @@ namespace GodotTools.ProjectEditor
void AddPropertyIfNotPresent(string name, string condition, string value)
{
if (root.PropertyGroups
- .Any(g => g.Condition == string.Empty || g.Condition == condition &&
+ .Any(g => (g.Condition == string.Empty || g.Condition == condition) &&
g.Properties
.Any(p => p.Name == name &&
p.Value == value &&
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
index f849356919..d8cb9024c3 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
@@ -137,7 +137,7 @@ namespace GodotTools.Build
private static string BuildArguments(string solution, string config, string loggerOutputDir, List<string> customProperties)
{
- string arguments = $@"""{solution}"" /v:normal /t:Rebuild ""/p:{"Configuration=" + config}"" " +
+ string arguments = $@"""{solution}"" /v:normal /t:Build ""/p:{"Configuration=" + config}"" " +
$@"""/l:{typeof(GodotBuildLogger).FullName},{GodotBuildLogger.AssemblyPath};{loggerOutputDir}""";
foreach (string customProperty in customProperties)
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
index f0068385f4..926aabdf89 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
@@ -15,7 +15,6 @@ namespace GodotTools.Build
{
private static string _msbuildToolsPath = string.Empty;
private static string _msbuildUnixPath = string.Empty;
- private static string _xbuildUnixPath = string.Empty;
public static string FindMsBuild()
{
@@ -44,7 +43,6 @@ namespace GodotTools.Build
return Path.Combine(_msbuildToolsPath, "MSBuild.exe");
}
-
case GodotSharpBuilds.BuildTool.MsBuildMono:
{
string msbuildPath = Path.Combine(Internal.MonoWindowsInstallRoot, "bin", "msbuild.bat");
@@ -56,19 +54,6 @@ namespace GodotTools.Build
return msbuildPath;
}
-
- case GodotSharpBuilds.BuildTool.XBuild:
- {
- string xbuildPath = Path.Combine(Internal.MonoWindowsInstallRoot, "bin", "xbuild.bat");
-
- if (!File.Exists(xbuildPath))
- {
- throw new FileNotFoundException($"Cannot find executable for '{GodotSharpBuilds.PropNameXbuild}'. Tried with path: {xbuildPath}");
- }
-
- return xbuildPath;
- }
-
default:
throw new IndexOutOfRangeException("Invalid build tool in editor settings");
}
@@ -76,20 +61,7 @@ namespace GodotTools.Build
if (OS.IsUnix())
{
- if (buildTool == GodotSharpBuilds.BuildTool.XBuild)
- {
- if (_xbuildUnixPath.Empty() || !File.Exists(_xbuildUnixPath))
- {
- // Try to search it again if it wasn't found last time or if it was removed from its location
- _xbuildUnixPath = FindBuildEngineOnUnix("msbuild");
- }
-
- if (_xbuildUnixPath.Empty())
- {
- throw new FileNotFoundException($"Cannot find binary for '{GodotSharpBuilds.PropNameXbuild}'");
- }
- }
- else
+ if (buildTool == GodotSharpBuilds.BuildTool.MsBuildMono)
{
if (_msbuildUnixPath.Empty() || !File.Exists(_msbuildUnixPath))
{
@@ -101,9 +73,13 @@ namespace GodotTools.Build
{
throw new FileNotFoundException($"Cannot find binary for '{GodotSharpBuilds.PropNameMsbuildMono}'");
}
- }
- return buildTool != GodotSharpBuilds.BuildTool.XBuild ? _msbuildUnixPath : _xbuildUnixPath;
+ return _msbuildUnixPath;
+ }
+ else
+ {
+ throw new IndexOutOfRangeException("Invalid build tool in editor settings");
+ }
}
throw new PlatformNotSupportedException();
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs
index a884b0ead0..de3a4d9a6e 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs
@@ -18,7 +18,6 @@ namespace GodotTools
public const string PropNameMsbuildMono = "MSBuild (Mono)";
public const string PropNameMsbuildVs = "MSBuild (VS Build Tools)";
- public const string PropNameXbuild = "xbuild (Deprecated)";
public const string MsBuildIssuesFileName = "msbuild_issues.csv";
public const string MsBuildLogFileName = "msbuild_log.txt";
@@ -26,8 +25,7 @@ namespace GodotTools
public enum BuildTool
{
MsBuildMono,
- MsBuildVs,
- XBuild // Deprecated
+ MsBuildVs
}
private static void RemoveOldIssuesFile(MonoBuildInfo buildInfo)
@@ -64,7 +62,7 @@ namespace GodotTools
private static string GetIssuesFilePath(MonoBuildInfo buildInfo)
{
- return Path.Combine(Godot.ProjectSettings.LocalizePath(buildInfo.LogsDirPath), MsBuildIssuesFileName);
+ return Path.Combine(buildInfo.LogsDirPath, MsBuildIssuesFileName);
}
private static void PrintVerbose(string text)
@@ -202,6 +200,9 @@ namespace GodotTools
// case the user decided to delete them at some point after they were loaded.
Internal.UpdateApiAssembliesFromPrebuilt();
+ var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
+ var buildTool = (BuildTool)editorSettings.GetSetting("mono/builds/build_tool");
+
using (var pr = new EditorProgress("mono_project_debug_build", "Building project solution...", 1))
{
pr.Step("Building project solution", 0);
@@ -209,7 +210,7 @@ namespace GodotTools
var buildInfo = new MonoBuildInfo(GodotSharpDirs.ProjectSlnPath, config);
// Add Godot defines
- string constants = OS.IsWindows() ? "GodotDefineConstants=\"" : "GodotDefineConstants=\\\"";
+ string constants = buildTool == BuildTool.MsBuildVs ? "GodotDefineConstants=\"" : "GodotDefineConstants=\\\"";
foreach (var godotDefine in godotDefines)
constants += $"GODOT_{godotDefine.ToUpper().Replace("-", "_").Replace(" ", "_").Replace(";", "_")};";
@@ -217,7 +218,7 @@ namespace GodotTools
if (Internal.GodotIsRealTDouble())
constants += "GODOT_REAL_T_IS_DOUBLE;";
- constants += OS.IsWindows() ? "\"" : "\\\"";
+ constants += buildTool == BuildTool.MsBuildVs ? "\"" : "\\\"";
buildInfo.CustomProperties.Add(constants);
@@ -267,8 +268,8 @@ namespace GodotTools
["name"] = "mono/builds/build_tool",
["hint"] = Godot.PropertyHint.Enum,
["hint_string"] = OS.IsWindows() ?
- $"{PropNameMsbuildMono},{PropNameMsbuildVs},{PropNameXbuild}" :
- $"{PropNameMsbuildMono},{PropNameXbuild}"
+ $"{PropNameMsbuildMono},{PropNameMsbuildVs}" :
+ $"{PropNameMsbuildMono}"
});
EditorDef("mono/builds/print_build_output", false);
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index 90dec43412..9b5afb94a3 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -298,7 +298,16 @@ namespace GodotTools
if (line >= 0)
scriptPath += $";{line + 1};{col}";
- GetMonoDevelopInstance(GodotSharpDirs.ProjectSlnPath).Execute(scriptPath);
+ try
+ {
+ GetMonoDevelopInstance(GodotSharpDirs.ProjectSlnPath).Execute(scriptPath);
+ }
+ catch (FileNotFoundException)
+ {
+ string editorName = editor == ExternalEditor.VisualStudioForMac ? "Visual Studio" : "MonoDevelop";
+ GD.PushError($"Cannot find code editor: {editorName}");
+ return Error.FileNotFound;
+ }
break;
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs b/modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs
index 75fdacc0da..3a74fa2f66 100644
--- a/modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs
@@ -61,41 +61,48 @@ namespace GodotTools
{
using (var file = new Godot.File())
{
- Error openError = file.Open(csvFile, Godot.File.ModeFlags.Read);
-
- if (openError != Error.Ok)
- return;
-
- while (!file.EofReached())
+ try
{
- string[] csvColumns = file.GetCsvLine();
+ Error openError = file.Open(csvFile, Godot.File.ModeFlags.Read);
- if (csvColumns.Length == 1 && csvColumns[0].Empty())
+ if (openError != Error.Ok)
return;
- if (csvColumns.Length != 7)
+ while (!file.EofReached())
{
- GD.PushError($"Expected 7 columns, got {csvColumns.Length}");
- continue;
+ string[] csvColumns = file.GetCsvLine();
+
+ if (csvColumns.Length == 1 && csvColumns[0].Empty())
+ return;
+
+ if (csvColumns.Length != 7)
+ {
+ GD.PushError($"Expected 7 columns, got {csvColumns.Length}");
+ continue;
+ }
+
+ var issue = new BuildIssue
+ {
+ Warning = csvColumns[0] == "warning",
+ File = csvColumns[1],
+ Line = int.Parse(csvColumns[2]),
+ Column = int.Parse(csvColumns[3]),
+ Code = csvColumns[4],
+ Message = csvColumns[5],
+ ProjectFile = csvColumns[6]
+ };
+
+ if (issue.Warning)
+ WarningCount += 1;
+ else
+ ErrorCount += 1;
+
+ issues.Add(issue);
}
-
- var issue = new BuildIssue
- {
- Warning = csvColumns[0] == "warning",
- File = csvColumns[1],
- Line = int.Parse(csvColumns[2]),
- Column = int.Parse(csvColumns[3]),
- Code = csvColumns[4],
- Message = csvColumns[5],
- ProjectFile = csvColumns[6]
- };
-
- if (issue.Warning)
- WarningCount += 1;
- else
- ErrorCount += 1;
-
- issues.Add(issue);
+ }
+ finally
+ {
+ file.Close(); // Disposing it is not enough. We need to call Close()
}
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoDevelopInstance.cs b/modules/mono/editor/GodotTools/GodotTools/MonoDevelopInstance.cs
index 0c8d86e799..61a0a992ce 100644
--- a/modules/mono/editor/GodotTools/GodotTools/MonoDevelopInstance.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/MonoDevelopInstance.cs
@@ -4,6 +4,7 @@ using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
using GodotTools.Internals;
+using GodotTools.Utils;
namespace GodotTools
{
@@ -30,7 +31,7 @@ namespace GodotTools
if (Utils.OS.IsOSX())
{
- string bundleId = CodeEditorBundleIds[editorId];
+ string bundleId = BundleIds[editorId];
if (Internal.IsOsxAppBundleInstalled(bundleId))
{
@@ -47,12 +48,12 @@ namespace GodotTools
}
else
{
- command = CodeEditorPaths[editorId];
+ command = OS.PathWhich(ExecutableNames[editorId]);
}
}
else
{
- command = CodeEditorPaths[editorId];
+ command = OS.PathWhich(ExecutableNames[editorId]);
}
args.Add("--ipc-tcp");
@@ -70,6 +71,9 @@ namespace GodotTools
args.Add("\"" + Path.GetFullPath(filePath.NormalizePath()) + cursor + "\"");
}
+ if (command == null)
+ throw new FileNotFoundException();
+
if (newWindow)
{
process = Process.Start(new ProcessStartInfo
@@ -99,20 +103,20 @@ namespace GodotTools
this.editorId = editorId;
}
- private static readonly IReadOnlyDictionary<EditorId, string> CodeEditorPaths;
- private static readonly IReadOnlyDictionary<EditorId, string> CodeEditorBundleIds;
+ private static readonly IReadOnlyDictionary<EditorId, string> ExecutableNames;
+ private static readonly IReadOnlyDictionary<EditorId, string> BundleIds;
static MonoDevelopInstance()
{
if (Utils.OS.IsOSX())
{
- CodeEditorPaths = new Dictionary<EditorId, string>
+ ExecutableNames = new Dictionary<EditorId, string>
{
// Rely on PATH
{EditorId.MonoDevelop, "monodevelop"},
{EditorId.VisualStudioForMac, "VisualStudio"}
};
- CodeEditorBundleIds = new Dictionary<EditorId, string>
+ BundleIds = new Dictionary<EditorId, string>
{
// TODO EditorId.MonoDevelop
{EditorId.VisualStudioForMac, "com.microsoft.visual-studio"}
@@ -120,7 +124,7 @@ namespace GodotTools
}
else if (Utils.OS.IsWindows())
{
- CodeEditorPaths = new Dictionary<EditorId, string>
+ ExecutableNames = new Dictionary<EditorId, string>
{
// XamarinStudio is no longer a thing, and the latest version is quite old
// MonoDevelop is available from source only on Windows. The recommendation
@@ -131,7 +135,7 @@ namespace GodotTools
}
else if (Utils.OS.IsUnix())
{
- CodeEditorPaths = new Dictionary<EditorId, string>
+ ExecutableNames = new Dictionary<EditorId, string>
{
// Rely on PATH
{EditorId.MonoDevelop, "monodevelop"}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs
index 3ae6c10bbf..288c65de74 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs
@@ -10,8 +10,9 @@ namespace GodotTools.Utils
{
foreach (T elem in enumerable)
{
- if (predicate(elem) != null)
- return elem;
+ T result = predicate(elem);
+ if (result != null)
+ return result;
}
return orElse;
diff --git a/modules/mono/glue/Managed/Files/Basis.cs b/modules/mono/glue/Managed/Files/Basis.cs
index 9cc31a0557..5a6a5ff658 100644
--- a/modules/mono/glue/Managed/Files/Basis.cs
+++ b/modules/mono/glue/Managed/Files/Basis.cs
@@ -225,7 +225,7 @@ namespace Godot
return orthonormalizedBasis.Quat();
}
- internal void SetQuantScale(Quat quat, Vector3 scale)
+ internal void SetQuatScale(Quat quat, Vector3 scale)
{
SetDiagonal(scale);
Rotate(quat);
@@ -241,7 +241,6 @@ namespace Godot
Row0 = new Vector3(diagonal.x, 0, 0);
Row1 = new Vector3(0, diagonal.y, 0);
Row2 = new Vector3(0, 0, diagonal.z);
-
}
public real_t Determinant()
diff --git a/modules/mono/glue/Managed/Files/NodePath.cs b/modules/mono/glue/Managed/Files/NodePath.cs
index 94a4ed1de9..4de4e1e6a9 100644
--- a/modules/mono/glue/Managed/Files/NodePath.cs
+++ b/modules/mono/glue/Managed/Files/NodePath.cs
@@ -55,7 +55,7 @@ namespace Godot
get { return ptr; }
}
- public NodePath() : this(string.Empty) { }
+ public NodePath() : this(string.Empty) {}
public NodePath(string path)
{
diff --git a/modules/mono/glue/Managed/Files/Quat.cs b/modules/mono/glue/Managed/Files/Quat.cs
index 0d4349084a..f1d97b9b5c 100644
--- a/modules/mono/glue/Managed/Files/Quat.cs
+++ b/modules/mono/glue/Managed/Files/Quat.cs
@@ -95,6 +95,7 @@ namespace Godot
return this / Length;
}
+ [Obsolete("Set is deprecated. Use the Quat(" + nameof(real_t) + ", " + nameof(real_t) + ", " + nameof(real_t) + ", " + nameof(real_t) + ") constructor instead.", error: true)]
public void Set(real_t x, real_t y, real_t z, real_t w)
{
this.x = x;
@@ -103,16 +104,19 @@ namespace Godot
this.w = w;
}
+ [Obsolete("Set is deprecated. Use the Quat(" + nameof(Quat) + ") constructor instead.", error: true)]
public void Set(Quat q)
{
this = q;
}
+ [Obsolete("SetAxisAngle is deprecated. Use the Quat(" + nameof(Vector3) + ", " + nameof(real_t) + ") constructor instead.", error: true)]
public void SetAxisAngle(Vector3 axis, real_t angle)
{
this = new Quat(axis, angle);
}
+ [Obsolete("SetEuler is deprecated. Use the Quat(" + nameof(Vector3) + ") constructor instead.", error: true)]
public void SetEuler(Vector3 eulerYXZ)
{
this = new Quat(eulerYXZ);
@@ -229,9 +233,9 @@ namespace Godot
public Quat(Vector3 eulerYXZ)
{
- real_t half_a1 = eulerYXZ.y * (real_t)0.5;
- real_t half_a2 = eulerYXZ.x * (real_t)0.5;
- real_t half_a3 = eulerYXZ.z * (real_t)0.5;
+ real_t half_a1 = eulerYXZ.y * 0.5f;
+ real_t half_a2 = eulerYXZ.x * 0.5f;
+ real_t half_a3 = eulerYXZ.z * 0.5f;
// R = Y(a1).X(a2).Z(a3) convention for Euler angles.
// Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6)
@@ -246,7 +250,7 @@ namespace Godot
x = sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3;
y = sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3;
- z = -sin_a1 * sin_a2 * cos_a3 + cos_a1 * cos_a2 * sin_a3;
+ z = cos_a1 * cos_a2 * sin_a3 - sin_a1 * sin_a2 * cos_a3;
w = sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3;
}
diff --git a/modules/mono/glue/Managed/Files/StringExtensions.cs b/modules/mono/glue/Managed/Files/StringExtensions.cs
index b43034fbb5..6045c83e95 100644
--- a/modules/mono/glue/Managed/Files/StringExtensions.cs
+++ b/modules/mono/glue/Managed/Files/StringExtensions.cs
@@ -98,6 +98,66 @@ namespace Godot
}
// <summary>
+ // Return the amount of substrings in string.
+ // </summary>
+ public static int Count(this string instance, string what, bool caseSensitive = true, int from = 0, int to = 0)
+ {
+ if (what.Length == 0)
+ {
+ return 0;
+ }
+
+ int len = instance.Length;
+ int slen = what.Length;
+
+ if (len < slen)
+ {
+ return 0;
+ }
+
+ string str;
+
+ if (from >= 0 && to >= 0)
+ {
+ if (to == 0)
+ {
+ to = len;
+ }
+ else if (from >= to)
+ {
+ return 0;
+ }
+ if (from == 0 && to == len)
+ {
+ str = instance;
+ }
+ else
+ {
+ str = instance.Substring(from, to - from);
+ }
+ }
+ else
+ {
+ return 0;
+ }
+
+ int c = 0;
+ int idx;
+
+ do
+ {
+ idx = str.IndexOf(what, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
+ if (idx != -1)
+ {
+ str = str.Substring(idx + slen);
+ ++c;
+ }
+ } while (idx != -1);
+
+ return c;
+ }
+
+ // <summary>
// Return a copy of the string with special characters escaped using the C language standard.
// </summary>
public static string CEscape(this string instance)
diff --git a/modules/mono/glue/Managed/Files/Transform.cs b/modules/mono/glue/Managed/Files/Transform.cs
index bd79144873..de70ccbe98 100644
--- a/modules/mono/glue/Managed/Files/Transform.cs
+++ b/modules/mono/glue/Managed/Files/Transform.cs
@@ -33,7 +33,7 @@ namespace Godot
Vector3 destinationLocation = transform.origin;
var interpolated = new Transform();
- interpolated.basis.SetQuantScale(sourceRotation.Slerp(destinationRotation, c).Normalized(), sourceScale.LinearInterpolate(destinationScale, c));
+ interpolated.basis.SetQuatScale(sourceRotation.Slerp(destinationRotation, c).Normalized(), sourceScale.LinearInterpolate(destinationScale, c));
interpolated.origin = sourceLocation.LinearInterpolate(destinationLocation, c);
return interpolated;
diff --git a/modules/mono/glue/Managed/Files/Transform2D.cs b/modules/mono/glue/Managed/Files/Transform2D.cs
index 33ff286769..12a3811230 100644
--- a/modules/mono/glue/Managed/Files/Transform2D.cs
+++ b/modules/mono/glue/Managed/Files/Transform2D.cs
@@ -98,6 +98,8 @@ namespace Godot
return x[columnIndex];
case 1:
return y[columnIndex];
+ case 2:
+ return origin[columnIndex];
default:
throw new IndexOutOfRangeException();
}
@@ -112,6 +114,9 @@ namespace Godot
case 1:
y[columnIndex] = value;
return;
+ case 2:
+ origin[columnIndex] = value;
+ return;
default:
throw new IndexOutOfRangeException();
}
@@ -136,7 +141,7 @@ namespace Godot
inv[0] *= new Vector2(detInv, -detInv);
inv[1] *= new Vector2(-detInv, detInv);
- inv[2] = BasisXform(-inv[2]);
+ inv[2] = inv.BasisXform(-inv[2]);
return inv;
}
diff --git a/modules/mono/glue/Managed/Files/Vector2.cs b/modules/mono/glue/Managed/Files/Vector2.cs
index a7f26283a7..3fb40d8a61 100644
--- a/modules/mono/glue/Managed/Files/Vector2.cs
+++ b/modules/mono/glue/Managed/Files/Vector2.cs
@@ -222,11 +222,13 @@ namespace Godot
return new Vector2(Mathf.Round(x), Mathf.Round(y));
}
+ [Obsolete("Set is deprecated. Use the Vector2(" + nameof(real_t) + ", " + nameof(real_t) + ") constructor instead.", error: true)]
public void Set(real_t x, real_t y)
{
this.x = x;
this.y = y;
}
+ [Obsolete("Set is deprecated. Use the Vector2(" + nameof(Vector2) + ") constructor instead.", error: true)]
public void Set(Vector2 v)
{
x = v.x;
diff --git a/modules/mono/glue/Managed/Files/Vector3.cs b/modules/mono/glue/Managed/Files/Vector3.cs
index 16803ae55c..68601da1e7 100644
--- a/modules/mono/glue/Managed/Files/Vector3.cs
+++ b/modules/mono/glue/Managed/Files/Vector3.cs
@@ -248,12 +248,14 @@ namespace Godot
return new Basis(axis, phi).Xform(this);
}
+ [Obsolete("Set is deprecated. Use the Vector3(" + nameof(real_t) + ", " + nameof(real_t) + ", " + nameof(real_t) + ") constructor instead.", error: true)]
public void Set(real_t x, real_t y, real_t z)
{
this.x = x;
this.y = y;
this.z = z;
}
+ [Obsolete("Set is deprecated. Use the Vector3(" + nameof(Vector3) + ") constructor instead.", error: true)]
public void Set(Vector3 v)
{
x = v.x;
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 571bf598f3..45f79074be 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -283,6 +283,18 @@ void GDMono::initialize() {
add_mono_shared_libs_dir_to_path();
+ {
+ PropertyInfo exc_policy_prop = PropertyInfo(Variant::INT, "mono/unhandled_exception_policy", PROPERTY_HINT_ENUM,
+ vformat("Terminate Application:%s,Log Error:%s", (int)POLICY_TERMINATE_APP, (int)POLICY_LOG_ERROR));
+ unhandled_exception_policy = (UnhandledExceptionPolicy)(int)GLOBAL_DEF(exc_policy_prop.name, (int)POLICY_TERMINATE_APP);
+ ProjectSettings::get_singleton()->set_custom_property_info(exc_policy_prop.name, exc_policy_prop);
+
+ if (Engine::get_singleton()->is_editor_hint()) {
+ // Unhandled exceptions should not terminate the editor
+ unhandled_exception_policy = POLICY_LOG_ERROR;
+ }
+ }
+
GDMonoAssembly::initialize();
gdmono_profiler_init();
@@ -645,7 +657,14 @@ bool GDMono::_load_core_api_assembly() {
#ifdef TOOLS_ENABLED
// For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date
- String assembly_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(CORE_API_ASSEMBLY_NAME ".dll");
+
+ // If running the project manager, load it from the prebuilt API directory
+ String assembly_dir = !Main::is_project_manager() ?
+ GodotSharpDirs::get_res_assemblies_dir() :
+ GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug");
+
+ String assembly_path = assembly_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
+
bool success = FileAccess::exists(assembly_path) &&
load_assembly_from(CORE_API_ASSEMBLY_NAME, assembly_path, &core_api_assembly);
#else
@@ -676,7 +695,14 @@ bool GDMono::_load_editor_api_assembly() {
return true;
// For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date
- String assembly_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
+
+ // If running the project manager, load it from the prebuilt API directory
+ String assembly_dir = !Main::is_project_manager() ?
+ GodotSharpDirs::get_res_assemblies_dir() :
+ GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug");
+
+ String assembly_path = assembly_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
+
bool success = FileAccess::exists(assembly_path) &&
load_assembly_from(EDITOR_API_ASSEMBLY_NAME, assembly_path, &editor_api_assembly);
@@ -728,6 +754,12 @@ void GDMono::_load_api_assemblies() {
// The API assemblies are out of sync. Fine, try one more time, but this time
// update them from the prebuilt assemblies directory before trying to load them.
+ // Shouldn't happen. The project manager loads the prebuilt API assemblies
+ if (Main::is_project_manager()) {
+ ERR_EXPLAIN("Failed to load one of the prebuilt API assemblies");
+ CRASH_NOW();
+ }
+
// 1. Unload the scripts domain
if (_unload_scripts_domain() != OK) {
ERR_EXPLAIN("Mono: Failed to unload scripts domain");
@@ -1063,6 +1095,8 @@ GDMono::GDMono() {
#ifdef TOOLS_ENABLED
api_editor_hash = 0;
#endif
+
+ unhandled_exception_policy = POLICY_TERMINATE_APP;
}
GDMono::~GDMono() {
diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h
index deebe5fd50..c5bcce4fa1 100644
--- a/modules/mono/mono_gd/gd_mono.h
+++ b/modules/mono/mono_gd/gd_mono.h
@@ -80,6 +80,13 @@ String to_string(Type p_type);
class GDMono {
+public:
+ enum UnhandledExceptionPolicy {
+ POLICY_TERMINATE_APP,
+ POLICY_LOG_ERROR
+ };
+
+private:
bool runtime_initialized;
bool finalizing_scripts_domain;
@@ -102,6 +109,8 @@ class GDMono {
HashMap<uint32_t, HashMap<String, GDMonoAssembly *> > assemblies;
+ UnhandledExceptionPolicy unhandled_exception_policy;
+
void _domain_assemblies_cleanup(uint32_t p_domain_id);
bool _are_api_assemblies_out_of_sync();
@@ -162,7 +171,9 @@ public:
static GDMono *get_singleton() { return singleton; }
- static void unhandled_exception_hook(MonoObject *p_exc, void *p_user_data);
+ GD_NORETURN static void unhandled_exception_hook(MonoObject *p_exc, void *p_user_data);
+
+ UnhandledExceptionPolicy get_unhandled_exception_policy() const { return unhandled_exception_policy; }
// Do not use these, unless you know what you're doing
void add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly);
diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp
index a84332d4cd..e50e3b0794 100644
--- a/modules/mono/mono_gd/gd_mono_internals.cpp
+++ b/modules/mono/mono_gd/gd_mono_internals.cpp
@@ -108,9 +108,18 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
void unhandled_exception(MonoException *p_exc) {
mono_unhandled_exception((MonoObject *)p_exc); // prints the exception as well
- // Too bad 'mono_invoke_unhandled_exception_hook' is not exposed to embedders
- GDMono::unhandled_exception_hook((MonoObject *)p_exc, NULL);
- GD_UNREACHABLE();
+
+ if (GDMono::get_singleton()->get_unhandled_exception_policy() == GDMono::POLICY_TERMINATE_APP) {
+ // Too bad 'mono_invoke_unhandled_exception_hook' is not exposed to embedders
+ GDMono::unhandled_exception_hook((MonoObject *)p_exc, NULL);
+ GD_UNREACHABLE();
+ } else {
+#ifdef DEBUG_ENABLED
+ GDMonoUtils::debug_send_unhandled_exception_error((MonoException *)p_exc);
+ if (ScriptDebugger::get_singleton())
+ ScriptDebugger::get_singleton()->idle_poll();
+#endif
+ }
}
} // namespace GDMonoInternals
diff --git a/modules/mono/mono_gd/gd_mono_internals.h b/modules/mono/mono_gd/gd_mono_internals.h
index 2d77bde27c..0d82723913 100644
--- a/modules/mono/mono_gd/gd_mono_internals.h
+++ b/modules/mono/mono_gd/gd_mono_internals.h
@@ -45,7 +45,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged);
* Do not call this function directly.
* Use GDMonoUtils::debug_unhandled_exception(MonoException *) instead.
*/
-GD_NORETURN void unhandled_exception(MonoException *p_exc);
+void unhandled_exception(MonoException *p_exc);
} // namespace GDMonoInternals
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 5987fa8ebb..7afdfc8ac8 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -37,6 +37,10 @@
#include "core/project_settings.h"
#include "core/reference.h"
+#ifdef TOOLS_ENABLED
+#include "editor/script_editor_debugger.h"
+#endif
+
#include "../csharp_script.h"
#include "../utils/macros.h"
#include "../utils/mutex_utils.h"
@@ -596,8 +600,14 @@ void debug_print_unhandled_exception(MonoException *p_exc) {
void debug_send_unhandled_exception_error(MonoException *p_exc) {
#ifdef DEBUG_ENABLED
- if (!ScriptDebugger::get_singleton())
+ if (!ScriptDebugger::get_singleton()) {
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint()) {
+ ERR_PRINTS(GDMonoUtils::get_exception_name_and_message(p_exc));
+ }
+#endif
return;
+ }
_TLS_RECURSION_GUARD_;
@@ -621,7 +631,7 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
if (unexpected_exc) {
GDMonoInternals::unhandled_exception(unexpected_exc);
- GD_UNREACHABLE();
+ return;
}
Vector<ScriptLanguage::StackInfo> _si;
@@ -655,7 +665,6 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
void debug_unhandled_exception(MonoException *p_exc) {
GDMonoInternals::unhandled_exception(p_exc); // prints the exception as well
- GD_UNREACHABLE();
}
void print_unhandled_exception(MonoException *p_exc) {
@@ -665,11 +674,9 @@ void print_unhandled_exception(MonoException *p_exc) {
void set_pending_exception(MonoException *p_exc) {
#ifdef NO_PENDING_EXCEPTIONS
debug_unhandled_exception(p_exc);
- GD_UNREACHABLE();
#else
if (get_runtime_invoke_count() == 0) {
debug_unhandled_exception(p_exc);
- GD_UNREACHABLE();
}
if (!mono_runtime_set_pending_exception(p_exc, false)) {
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index f535fbb6d0..d73743bf0b 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -289,7 +289,7 @@ void set_exception_message(MonoException *p_exc, String message);
void debug_print_unhandled_exception(MonoException *p_exc);
void debug_send_unhandled_exception_error(MonoException *p_exc);
-GD_NORETURN void debug_unhandled_exception(MonoException *p_exc);
+void debug_unhandled_exception(MonoException *p_exc);
void print_unhandled_exception(MonoException *p_exc);
/**
diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp
index 86374e8f80..af75f2a320 100644
--- a/modules/websocket/wsl_client.cpp
+++ b/modules/websocket/wsl_client.cpp
@@ -190,8 +190,8 @@ Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
Error err = _tcp->connect_to_host(addr, p_port);
if (err != OK) {
- _on_error();
_tcp->disconnect_from_host();
+ _on_error();
return err;
}
_connection = _tcp;
@@ -230,8 +230,8 @@ void WSLClient::poll() {
if (_peer->is_connected_to_host()) {
_peer->poll();
if (!_peer->is_connected_to_host()) {
- _on_disconnect(_peer->close_code != -1);
disconnect_from_host();
+ _on_disconnect(_peer->close_code != -1);
}
return;
}
@@ -242,8 +242,8 @@ void WSLClient::poll() {
switch (_tcp->get_status()) {
case StreamPeerTCP::STATUS_NONE:
// Clean close
- _on_error();
disconnect_from_host();
+ _on_error();
break;
case StreamPeerTCP::STATUS_CONNECTED: {
Ref<StreamPeerSSL> ssl;
@@ -255,8 +255,8 @@ void WSLClient::poll() {
ERR_FAIL_COND(ssl.is_null());
ssl->set_blocking_handshake_enabled(false);
if (ssl->connect_to_stream(_tcp, verify_ssl, _host) != OK) {
- _on_error();
disconnect_from_host();
+ _on_error();
return;
}
_connection = ssl;
@@ -268,8 +268,8 @@ void WSLClient::poll() {
if (ssl->get_status() == StreamPeerSSL::STATUS_HANDSHAKING)
return; // Need more polling.
else if (ssl->get_status() != StreamPeerSSL::STATUS_CONNECTED) {
- _on_error();
disconnect_from_host();
+ _on_error();
return; // Error.
}
}
@@ -277,8 +277,8 @@ void WSLClient::poll() {
_do_handshake();
} break;
case StreamPeerTCP::STATUS_ERROR:
- _on_error();
disconnect_from_host();
+ _on_error();
break;
case StreamPeerTCP::STATUS_CONNECTING:
break; // Wait for connection