summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp61
-rw-r--r--modules/gdnative/nativescript/nativescript.h12
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.cpp25
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.h2
-rw-r--r--modules/gdnavigation/gd_navigation_server.cpp32
-rw-r--r--modules/gdnavigation/gd_navigation_server.h5
-rw-r--r--modules/gdnavigation/navigation_mesh_editor_plugin.cpp6
-rw-r--r--modules/gdnavigation/navigation_mesh_editor_plugin.h6
-rw-r--r--modules/gdnavigation/navigation_mesh_generator.cpp2
-rw-r--r--modules/gdnavigation/navigation_mesh_generator.h2
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml20
-rw-r--r--modules/gdscript/gdscript.cpp167
-rw-r--r--modules/gdscript/gdscript.h2
-rw-r--r--modules/gdscript/gdscript_function.cpp19
-rw-r--r--modules/mono/csharp_script.cpp71
-rw-r--r--modules/mono/csharp_script.h10
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs7
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildManager.cs23
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs78
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs28
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp4
-rw-r--r--modules/mono/utils/mutex_utils.h67
-rw-r--r--modules/regex/doc_classes/RegEx.xml4
-rw-r--r--modules/upnp/doc_classes/UPNP.xml2
-rw-r--r--modules/visual_script/visual_script.cpp26
-rw-r--r--modules/visual_script/visual_script.h2
26 files changed, 235 insertions, 448 deletions
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index 8240ae2f83..0ec6ad71d9 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -222,15 +222,11 @@ ScriptInstance *NativeScript::instance_create(Object *p_this) {
nsi->userdata = script_data->create_func.create_func((godot_object *)p_this, script_data->create_func.method_data);
#endif
-#ifndef NO_THREADS
- owners_lock->lock();
-#endif
-
- instance_owners.insert(p_this);
+ {
+ MutexLock lock(owners_lock);
-#ifndef NO_THREADS
- owners_lock->unlock();
-#endif
+ instance_owners.insert(p_this);
+ }
return nsi;
}
@@ -782,17 +778,10 @@ NativeScript::NativeScript() {
library = Ref<GDNative>();
lib_path = "";
class_name = "";
-#ifndef NO_THREADS
- owners_lock = Mutex::create();
-#endif
}
NativeScript::~NativeScript() {
NSL->unregister_script(this);
-
-#ifndef NO_THREADS
- memdelete(owners_lock);
-#endif
}
#define GET_SCRIPT_DESC() script->get_script_desc()
@@ -1140,16 +1129,9 @@ NativeScriptInstance::~NativeScriptInstance() {
script_data->destroy_func.destroy_func((godot_object *)owner, script_data->destroy_func.method_data, userdata);
if (owner) {
-
-#ifndef NO_THREADS
- script->owners_lock->lock();
-#endif
+ MutexLock lock(script->owners_lock);
script->instance_owners.erase(owner);
-
-#ifndef NO_THREADS
- script->owners_lock->unlock();
-#endif
}
}
@@ -1246,7 +1228,6 @@ NativeScriptLanguage::NativeScriptLanguage() {
NativeScriptLanguage::singleton = this;
#ifndef NO_THREADS
has_objects_to_register = false;
- mutex = Mutex::create();
#endif
#ifdef DEBUG_ENABLED
@@ -1283,10 +1264,6 @@ NativeScriptLanguage::~NativeScriptLanguage() {
NSL->library_classes.clear();
NSL->library_gdnatives.clear();
NSL->library_script_users.clear();
-
-#ifndef NO_THREADS
- memdelete(mutex);
-#endif
}
String NativeScriptLanguage::get_name() const {
@@ -1413,9 +1390,7 @@ void NativeScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_
void NativeScriptLanguage::profiling_start() {
#ifdef DEBUG_ENABLED
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
profile_data.clear();
profiling = true;
@@ -1424,9 +1399,7 @@ void NativeScriptLanguage::profiling_start() {
void NativeScriptLanguage::profiling_stop() {
#ifdef DEBUG_ENABLED
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
profiling = false;
#endif
@@ -1434,9 +1407,8 @@ void NativeScriptLanguage::profiling_stop() {
int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) {
#ifdef DEBUG_ENABLED
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
+
int current = 0;
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
@@ -1458,9 +1430,8 @@ int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_a
int NativeScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) {
#ifdef DEBUG_ENABLED
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
+
int current = 0;
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
@@ -1484,9 +1455,7 @@ int NativeScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, in
void NativeScriptLanguage::profiling_add_data(StringName p_signature, uint64_t p_time) {
#ifdef DEBUG_ENABLED
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
Map<StringName, ProfileData>::Element *d = profile_data.find(p_signature);
if (d) {
@@ -1705,9 +1674,8 @@ void NativeScriptLanguage::defer_init_library(Ref<GDNativeLibrary> lib, NativeSc
#endif
void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
+
// See if this library was "registered" already.
const String &lib_path = lib->get_current_library_path();
ERR_FAIL_COND_MSG(lib_path.length() == 0, lib->get_name() + " does not have a library for the current platform.");
@@ -1743,16 +1711,14 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
}
void NativeScriptLanguage::register_script(NativeScript *script) {
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
+
library_script_users[script->lib_path].insert(script);
}
void NativeScriptLanguage::unregister_script(NativeScript *script) {
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
+
Map<String, Set<NativeScript *> >::Element *S = library_script_users.find(script->lib_path);
if (S) {
S->get().erase(script);
@@ -1803,9 +1769,7 @@ void NativeScriptLanguage::frame() {
#ifdef DEBUG_ENABLED
{
-#ifndef NO_THREADS
MutexLock lock(mutex);
-#endif
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
d->get().last_frame_call_count = d->get().frame_call_count;
@@ -1867,9 +1831,7 @@ void NativeReloadNode::_notification(int p_what) {
if (unloaded)
break;
-#ifndef NO_THREADS
MutexLock lock(NSL->mutex);
-#endif
NSL->_unload_stuff(true);
for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
@@ -1904,9 +1866,8 @@ void NativeReloadNode::_notification(int p_what) {
if (!unloaded)
break;
-#ifndef NO_THREADS
MutexLock lock(NSL->mutex);
-#endif
+
Set<StringName> libs_to_remove;
for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h
index 609ffa2bd4..04670b952b 100644
--- a/modules/gdnative/nativescript/nativescript.h
+++ b/modules/gdnative/nativescript/nativescript.h
@@ -35,6 +35,7 @@
#include "core/io/resource_saver.h"
#include "core/oa_hash_map.h"
#include "core/ordered_hash_map.h"
+#include "core/os/mutex.h"
#include "core/os/thread_safe.h"
#include "core/resource.h"
#include "core/script_language.h"
@@ -44,10 +45,6 @@
#include "modules/gdnative/gdnative.h"
#include <nativescript/godot_nativescript.h>
-#ifndef NO_THREADS
-#include "core/os/mutex.h"
-#endif
-
struct NativeScriptDesc {
struct Method {
@@ -127,9 +124,7 @@ class NativeScript : public Script {
String script_class_name;
String script_class_icon_path;
-#ifndef NO_THREADS
- Mutex *owners_lock;
-#endif
+ Mutex owners_lock;
Set<Object *> instance_owners;
protected:
@@ -266,9 +261,8 @@ private:
void _unload_stuff(bool p_reload = false);
+ Mutex mutex;
#ifndef NO_THREADS
- Mutex *mutex;
-
Set<Ref<GDNativeLibrary> > libs_to_init;
Set<NativeScript *> scripts_to_register;
volatile bool has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed
diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp
index 4e39f4b0a8..a40b59bb2e 100644
--- a/modules/gdnative/pluginscript/pluginscript_language.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_language.cpp
@@ -399,39 +399,18 @@ void PluginScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool
}
void PluginScriptLanguage::lock() {
-#ifndef NO_THREADS
- if (_lock) {
- _lock->lock();
- }
-#endif
+ _lock.lock();
}
void PluginScriptLanguage::unlock() {
-#ifndef NO_THREADS
- if (_lock) {
- _lock->unlock();
- }
-#endif
+ _lock.unlock();
}
PluginScriptLanguage::PluginScriptLanguage(const godot_pluginscript_language_desc *desc) :
_desc(*desc) {
_resource_loader = Ref<ResourceFormatLoaderPluginScript>(memnew(ResourceFormatLoaderPluginScript(this)));
_resource_saver = Ref<ResourceFormatSaverPluginScript>(memnew(ResourceFormatSaverPluginScript(this)));
-
-// TODO: totally remove _lock attribute if NO_THREADS is set
-#ifdef NO_THREADS
- _lock = NULL;
-#else
- _lock = Mutex::create();
-#endif
}
PluginScriptLanguage::~PluginScriptLanguage() {
-#ifndef NO_THREADS
- if (_lock) {
- memdelete(_lock);
- _lock = NULL;
- }
-#endif
}
diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h
index 037d7a4948..3f0d2b8d3d 100644
--- a/modules/gdnative/pluginscript/pluginscript_language.h
+++ b/modules/gdnative/pluginscript/pluginscript_language.h
@@ -53,7 +53,7 @@ class PluginScriptLanguage : public ScriptLanguage {
const godot_pluginscript_language_desc _desc;
godot_pluginscript_language_data *_data;
- Mutex *_lock;
+ Mutex _lock;
SelfList<PluginScript>::List _script_list;
public:
diff --git a/modules/gdnavigation/gd_navigation_server.cpp b/modules/gdnavigation/gd_navigation_server.cpp
index 4129d1f65a..4db10cda78 100644
--- a/modules/gdnavigation/gd_navigation_server.cpp
+++ b/modules/gdnavigation/gd_navigation_server.cpp
@@ -115,31 +115,27 @@
GdNavigationServer::GdNavigationServer() :
NavigationServer(),
- commands_mutex(Mutex::create()),
- operations_mutex(Mutex::create()),
active(true) {
}
GdNavigationServer::~GdNavigationServer() {
flush_queries();
- memdelete(operations_mutex);
- memdelete(commands_mutex);
}
void GdNavigationServer::add_command(SetCommand *command) const {
auto mut_this = const_cast<GdNavigationServer *>(this);
- commands_mutex->lock();
- mut_this->commands.push_back(command);
- commands_mutex->unlock();
+ {
+ MutexLock lock(commands_mutex);
+ mut_this->commands.push_back(command);
+ }
}
RID GdNavigationServer::map_create() const {
auto mut_this = const_cast<GdNavigationServer *>(this);
- mut_this->operations_mutex->lock();
+ MutexLock lock(mut_this->operations_mutex);
NavMap *space = memnew(NavMap);
RID rid = map_owner.make_rid(space);
space->set_self(rid);
- mut_this->operations_mutex->unlock();
return rid;
}
@@ -242,11 +238,10 @@ RID GdNavigationServer::map_get_closest_point_owner(RID p_map, const Vector3 &p_
RID GdNavigationServer::region_create() const {
auto mut_this = const_cast<GdNavigationServer *>(this);
- mut_this->operations_mutex->lock();
+ MutexLock lock(mut_this->operations_mutex);
NavRegion *reg = memnew(NavRegion);
RID rid = region_owner.make_rid(reg);
reg->set_self(rid);
- mut_this->operations_mutex->unlock();
return rid;
}
@@ -298,11 +293,10 @@ void GdNavigationServer::region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p
RID GdNavigationServer::agent_create() const {
auto mut_this = const_cast<GdNavigationServer *>(this);
- mut_this->operations_mutex->lock();
+ MutexLock lock(mut_this->operations_mutex);
RvoAgent *agent = memnew(RvoAgent());
RID rid = agent_owner.make_rid(agent);
agent->set_self(rid);
- mut_this->operations_mutex->unlock();
return rid;
}
@@ -470,23 +464,20 @@ COMMAND_1(free, RID, p_object) {
void GdNavigationServer::set_active(bool p_active) const {
auto mut_this = const_cast<GdNavigationServer *>(this);
- mut_this->operations_mutex->lock();
+ MutexLock lock(mut_this->operations_mutex);
mut_this->active = p_active;
- mut_this->operations_mutex->unlock();
}
void GdNavigationServer::flush_queries() {
// In c++ we can't be sure that this is performed in the main thread
// even with mutable functions.
- commands_mutex->lock();
- operations_mutex->lock();
+ MutexLock lock(commands_mutex);
+ MutexLock lock2(operations_mutex);
for (size_t i(0); i < commands.size(); i++) {
commands[i]->exec(this);
memdelete(commands[i]);
}
commands.clear();
- operations_mutex->unlock();
- commands_mutex->unlock();
}
void GdNavigationServer::process(real_t p_delta_time) {
@@ -498,13 +489,12 @@ void GdNavigationServer::process(real_t p_delta_time) {
// In c++ we can't be sure that this is performed in the main thread
// even with mutable functions.
- operations_mutex->lock();
+ MutexLock lock(operations_mutex);
for (int i(0); i < active_maps.size(); i++) {
active_maps[i]->sync();
active_maps[i]->step(p_delta_time);
active_maps[i]->dispatch_callbacks();
}
- operations_mutex->unlock();
}
#undef COMMAND_1
diff --git a/modules/gdnavigation/gd_navigation_server.h b/modules/gdnavigation/gd_navigation_server.h
index 0400acf1a3..e9f5c1ffe6 100644
--- a/modules/gdnavigation/gd_navigation_server.h
+++ b/modules/gdnavigation/gd_navigation_server.h
@@ -61,7 +61,6 @@
void MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3)
class GdNavigationServer;
-class Mutex;
struct SetCommand {
virtual ~SetCommand() {}
@@ -69,9 +68,9 @@ struct SetCommand {
};
class GdNavigationServer : public NavigationServer {
- Mutex *commands_mutex;
+ Mutex commands_mutex;
/// Mutex used to make any operation threadsafe.
- Mutex *operations_mutex;
+ Mutex operations_mutex;
std::vector<SetCommand *> commands;
diff --git a/modules/gdnavigation/navigation_mesh_editor_plugin.cpp b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp
index 28fe0bfd06..4ab90ac7eb 100644
--- a/modules/gdnavigation/navigation_mesh_editor_plugin.cpp
+++ b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp
@@ -84,7 +84,7 @@ void NavigationMeshEditor::_clear_pressed() {
}
}
-void NavigationMeshEditor::edit(NavigationMeshInstance *p_nav_mesh_instance) {
+void NavigationMeshEditor::edit(NavigationRegion *p_nav_mesh_instance) {
if (p_nav_mesh_instance == NULL || node == p_nav_mesh_instance) {
return;
@@ -128,12 +128,12 @@ NavigationMeshEditor::~NavigationMeshEditor() {
void NavigationMeshEditorPlugin::edit(Object *p_object) {
- navigation_mesh_editor->edit(Object::cast_to<NavigationMeshInstance>(p_object));
+ navigation_mesh_editor->edit(Object::cast_to<NavigationRegion>(p_object));
}
bool NavigationMeshEditorPlugin::handles(Object *p_object) const {
- return p_object->is_class("NavigationMeshInstance");
+ return p_object->is_class("NavigationRegion");
}
void NavigationMeshEditorPlugin::make_visible(bool p_visible) {
diff --git a/modules/gdnavigation/navigation_mesh_editor_plugin.h b/modules/gdnavigation/navigation_mesh_editor_plugin.h
index f5833f3d7f..7c3faebf57 100644
--- a/modules/gdnavigation/navigation_mesh_editor_plugin.h
+++ b/modules/gdnavigation/navigation_mesh_editor_plugin.h
@@ -36,7 +36,7 @@
#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
-class NavigationMeshInstance;
+class NavigationRegion;
class NavigationMeshEditor : public Control {
friend class NavigationMeshEditorPlugin;
@@ -50,7 +50,7 @@ class NavigationMeshEditor : public Control {
ToolButton *button_reset;
Label *bake_info;
- NavigationMeshInstance *node;
+ NavigationRegion *node;
void _bake_pressed();
void _clear_pressed();
@@ -61,7 +61,7 @@ protected:
void _notification(int p_option);
public:
- void edit(NavigationMeshInstance *p_nav_mesh_instance);
+ void edit(NavigationRegion *p_nav_mesh_instance);
NavigationMeshEditor();
~NavigationMeshEditor();
};
diff --git a/modules/gdnavigation/navigation_mesh_generator.cpp b/modules/gdnavigation/navigation_mesh_generator.cpp
index 7f8761dac8..e7038b38a2 100644
--- a/modules/gdnavigation/navigation_mesh_generator.cpp
+++ b/modules/gdnavigation/navigation_mesh_generator.cpp
@@ -42,10 +42,10 @@
#include "scene/resources/concave_polygon_shape.h"
#include "scene/resources/convex_polygon_shape.h"
#include "scene/resources/cylinder_shape.h"
-#include "scene/resources/plane_shape.h"
#include "scene/resources/primitive_meshes.h"
#include "scene/resources/shape.h"
#include "scene/resources/sphere_shape.h"
+#include "scene/resources/world_margin_shape.h"
#include "modules/modules_enabled.gen.h"
#ifdef TOOLS_ENABLED
diff --git a/modules/gdnavigation/navigation_mesh_generator.h b/modules/gdnavigation/navigation_mesh_generator.h
index 27a56e1d7a..d1f2e4b56f 100644
--- a/modules/gdnavigation/navigation_mesh_generator.h
+++ b/modules/gdnavigation/navigation_mesh_generator.h
@@ -33,7 +33,7 @@
#ifndef _3D_DISABLED
-#include "scene/3d/navigation_mesh_instance.h"
+#include "scene/3d/navigation_region.h"
#include <Recast.h>
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index cf76c09294..2f6f9f30a4 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -481,9 +481,13 @@
<argument index="2" name="weight" type="float">
</argument>
<description>
- Returns a normalized value considering the given range.
+ Returns a normalized value considering the given range. This is the opposite of [method lerp].
[codeblock]
- inverse_lerp(3, 5, 4) # Returns 0.5
+ var middle = lerp(20, 30, 0.75)
+ # `middle` is now 27.5.
+ # Now, we pretend to have forgotten the original ratio and want to get it back.
+ var ratio = inverse_lerp(20, 30, 27.5)
+ # `ratio` is now 0.75.
[/codeblock]
</description>
</method>
@@ -558,7 +562,7 @@
<argument index="2" name="weight" type="float">
</argument>
<description>
- Linearly interpolates between two values by a normalized value.
+ Linearly interpolates between two values by a normalized value. This is the opposite of [method inverse_lerp].
If the [code]from[/code] and [code]to[/code] arguments are of type [int] or [float], the return value is a [float].
If both are of the same vector type ([Vector2], [Vector3] or [Color]), the return value will be of the same type ([code]lerp[/code] then calls the vector type's [code]linear_interpolate[/code] method).
[codeblock]
@@ -578,7 +582,7 @@
</argument>
<description>
Linearly interpolates between two angles (in radians) by a normalized value.
- Similar to [method lerp] but interpolate correctly when the angles wrap around [constant @GDScript.TAU].
+ Similar to [method lerp], but interpolates correctly when the angles wrap around [constant @GDScript.TAU].
[codeblock]
extends Sprite
var elapsed = 0.0
@@ -596,7 +600,13 @@
<argument index="0" name="nrg" type="float">
</argument>
<description>
- Converts from linear energy to decibels (audio).
+ Converts from linear energy to decibels (audio). This can be used to implement volume sliders that behave as expected (since volume isn't linear). Example:
+ [codeblock]
+ # "Slider" refers to a node that inherits Range such as HSlider or VSlider.
+ # Its range must be configured to go from 0 to 1.
+ # Change the bus name if you'd like to change the volume of a specific bus only.
+ AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), linear2db($Slider.value))
+ [/codeblock]
</description>
</method>
<method name="load">
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index a72bb7ba49..6a4bf801f3 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -104,28 +104,21 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
/* STEP 2, INITIALIZE AND CONSTRUCT */
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->lock();
-#endif
-
- instances.insert(instance->owner);
+ {
+ MutexLock lock(GDScriptLanguage::singleton->lock);
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->unlock();
-#endif
+ instances.insert(instance->owner);
+ }
initializer->call(instance, p_args, p_argcount, r_error);
if (r_error.error != Callable::CallError::CALL_OK) {
instance->script = Ref<GDScript>();
instance->owner->set_script_instance(NULL);
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->lock();
-#endif
- instances.erase(p_owner);
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->unlock();
-#endif
+ {
+ MutexLock lock(GDScriptLanguage::singleton->lock);
+ instances.erase(p_owner);
+ }
ERR_FAIL_COND_V(r_error.error != Callable::CallError::CALL_OK, NULL); //error constructing
}
@@ -346,16 +339,9 @@ PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this)
bool GDScript::instance_has(const Object *p_this) const {
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->lock();
-#endif
- bool hasit = instances.has((Object *)p_this);
-
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->unlock();
-#endif
+ MutexLock lock(GDScriptLanguage::singleton->lock);
- return hasit;
+ return instances.has((Object *)p_this);
}
bool GDScript::has_source_code() const {
@@ -544,14 +530,12 @@ void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) {
Error GDScript::reload(bool p_keep_state) {
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->lock();
-#endif
- bool has_instances = instances.size();
+ bool has_instances;
+ {
+ MutexLock lock(GDScriptLanguage::singleton->lock);
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->unlock();
-#endif
+ has_instances = instances.size();
+ }
ERR_FAIL_COND_V(!p_keep_state && has_instances, ERR_ALREADY_IN_USE);
@@ -1007,13 +991,10 @@ GDScript::GDScript() :
#endif
#ifdef DEBUG_ENABLED
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->lock();
- }
- GDScriptLanguage::get_singleton()->script_list.add(&script_list);
+ {
+ MutexLock lock(GDScriptLanguage::get_singleton()->lock);
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->unlock();
+ GDScriptLanguage::get_singleton()->script_list.add(&script_list);
}
#endif
}
@@ -1057,13 +1038,10 @@ GDScript::~GDScript() {
_save_orphaned_subclasses();
#ifdef DEBUG_ENABLED
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->lock();
- }
- GDScriptLanguage::get_singleton()->script_list.remove(&script_list);
+ {
+ MutexLock lock(GDScriptLanguage::get_singleton()->lock);
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->unlock();
+ GDScriptLanguage::get_singleton()->script_list.remove(&script_list);
}
#endif
}
@@ -1472,14 +1450,9 @@ GDScriptInstance::GDScriptInstance() {
GDScriptInstance::~GDScriptInstance() {
if (script.is_valid() && owner) {
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->lock();
-#endif
+ MutexLock lock(GDScriptLanguage::singleton->lock);
script->instances.erase(owner);
-#ifndef NO_THREADS
- GDScriptLanguage::singleton->lock->unlock();
-#endif
}
}
@@ -1580,9 +1553,7 @@ void GDScriptLanguage::finish() {
void GDScriptLanguage::profiling_start() {
#ifdef DEBUG_ENABLED
- if (lock) {
- lock->lock();
- }
+ MutexLock lock(this->lock);
SelfList<GDScriptFunction> *elem = function_list.first();
while (elem) {
@@ -1599,25 +1570,15 @@ void GDScriptLanguage::profiling_start() {
}
profiling = true;
- if (lock) {
- lock->unlock();
- }
-
#endif
}
void GDScriptLanguage::profiling_stop() {
#ifdef DEBUG_ENABLED
- if (lock) {
- lock->lock();
- }
+ MutexLock lock(this->lock);
profiling = false;
- if (lock) {
- lock->unlock();
- }
-
#endif
}
@@ -1625,9 +1586,8 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr,
int current = 0;
#ifdef DEBUG_ENABLED
- if (lock) {
- lock->lock();
- }
+
+ MutexLock lock(this->lock);
SelfList<GDScriptFunction> *elem = function_list.first();
while (elem) {
@@ -1640,11 +1600,6 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr,
elem = elem->next();
current++;
}
-
- if (lock) {
- lock->unlock();
- }
-
#endif
return current;
@@ -1655,9 +1610,7 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_
int current = 0;
#ifdef DEBUG_ENABLED
- if (lock) {
- lock->lock();
- }
+ MutexLock lock(this->lock);
SelfList<GDScriptFunction> *elem = function_list.first();
while (elem) {
@@ -1672,11 +1625,6 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_
}
elem = elem->next();
}
-
- if (lock) {
- lock->unlock();
- }
-
#endif
return current;
@@ -1707,23 +1655,18 @@ void GDScriptLanguage::reload_all_scripts() {
#ifdef DEBUG_ENABLED
print_verbose("GDScript: Reloading all scripts");
- if (lock) {
- lock->lock();
- }
-
List<Ref<GDScript> > scripts;
+ {
+ MutexLock lock(this->lock);
- SelfList<GDScript> *elem = script_list.first();
- while (elem) {
- if (elem->self()->get_path().is_resource_file()) {
- print_verbose("GDScript: Found: " + elem->self()->get_path());
- scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
+ SelfList<GDScript> *elem = script_list.first();
+ while (elem) {
+ if (elem->self()->get_path().is_resource_file()) {
+ print_verbose("GDScript: Found: " + elem->self()->get_path());
+ scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
+ }
+ elem = elem->next();
}
- elem = elem->next();
- }
-
- if (lock) {
- lock->unlock();
}
//as scripts are going to be reloaded, must proceed without locking here
@@ -1743,23 +1686,18 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
#ifdef DEBUG_ENABLED
- if (lock) {
- lock->lock();
- }
-
List<Ref<GDScript> > scripts;
+ {
+ MutexLock lock(this->lock);
- SelfList<GDScript> *elem = script_list.first();
- while (elem) {
- if (elem->self()->get_path().is_resource_file()) {
+ SelfList<GDScript> *elem = script_list.first();
+ while (elem) {
+ if (elem->self()->get_path().is_resource_file()) {
- scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
+ scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
+ }
+ elem = elem->next();
}
- elem = elem->next();
- }
-
- if (lock) {
- lock->unlock();
}
//when someone asks you why dynamically typed languages are easier to write....
@@ -1879,9 +1817,7 @@ void GDScriptLanguage::frame() {
#ifdef DEBUG_ENABLED
if (profiling) {
- if (lock) {
- lock->lock();
- }
+ MutexLock lock(this->lock);
SelfList<GDScriptFunction> *elem = function_list.first();
while (elem) {
@@ -1893,10 +1829,6 @@ void GDScriptLanguage::frame() {
elem->self()->profile.frame_total_time = 0;
elem = elem->next();
}
-
- if (lock) {
- lock->unlock();
- }
}
#endif
@@ -2262,11 +2194,6 @@ GDScriptLanguage::GDScriptLanguage() {
_debug_parse_err_line = -1;
_debug_parse_err_file = "";
-#ifdef NO_THREADS
- lock = NULL;
-#else
- lock = Mutex::create();
-#endif
profiling = false;
script_frame_time = 0;
@@ -2300,10 +2227,6 @@ GDScriptLanguage::GDScriptLanguage() {
GDScriptLanguage::~GDScriptLanguage() {
- if (lock) {
- memdelete(lock);
- lock = NULL;
- }
if (_call_stack) {
memdelete_arr(_call_stack);
}
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 6598a0023b..6b53acd064 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -369,7 +369,7 @@ class GDScriptLanguage : public ScriptLanguage {
friend class GDScriptInstance;
- Mutex *lock;
+ Mutex lock;
friend class GDScript;
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index 27857ea91f..79c550c81c 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -1769,13 +1769,10 @@ GDScriptFunction::GDScriptFunction() :
#ifdef DEBUG_ENABLED
_func_cname = NULL;
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->lock();
- }
- GDScriptLanguage::get_singleton()->function_list.add(&function_list);
+ {
+ MutexLock lock(GDScriptLanguage::get_singleton()->lock);
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->unlock();
+ GDScriptLanguage::get_singleton()->function_list.add(&function_list);
}
profile.call_count = 0;
@@ -1793,14 +1790,10 @@ GDScriptFunction::GDScriptFunction() :
GDScriptFunction::~GDScriptFunction() {
#ifdef DEBUG_ENABLED
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->lock();
- }
- GDScriptLanguage::get_singleton()->function_list.remove(&function_list);
- if (GDScriptLanguage::get_singleton()->lock) {
- GDScriptLanguage::get_singleton()->lock->unlock();
- }
+ MutexLock lock(GDScriptLanguage::get_singleton()->lock);
+
+ GDScriptLanguage::get_singleton()->function_list.remove(&function_list);
#endif
}
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 5c1c098e3e..404d2eb022 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -35,6 +35,7 @@
#include "core/io/json.h"
#include "core/os/file_access.h"
+#include "core/os/mutex.h"
#include "core/os/os.h"
#include "core/os/thread.h"
#include "core/project_settings.h"
@@ -58,7 +59,6 @@
#include "mono_gd/gd_mono_utils.h"
#include "signal_awaiter_utils.h"
#include "utils/macros.h"
-#include "utils/mutex_utils.h"
#include "utils/string_utils.h"
#include "utils/thread_local.h"
@@ -633,7 +633,7 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec
void CSharpLanguage::post_unsafe_reference(Object *p_obj) {
#ifdef DEBUG_ENABLED
- SCOPED_MUTEX_LOCK(unsafe_object_references_lock);
+ MutexLock lock(unsafe_object_references_lock);
ObjectID id = p_obj->get_instance_id();
unsafe_object_references[id]++;
#endif
@@ -641,7 +641,7 @@ void CSharpLanguage::post_unsafe_reference(Object *p_obj) {
void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) {
#ifdef DEBUG_ENABLED
- SCOPED_MUTEX_LOCK(unsafe_object_references_lock);
+ MutexLock lock(unsafe_object_references_lock);
ObjectID id = p_obj->get_instance_id();
Map<ObjectID, int>::Element *elem = unsafe_object_references.find(id);
ERR_FAIL_NULL(elem);
@@ -764,7 +764,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
List<Ref<CSharpScript> > scripts;
{
- SCOPED_MUTEX_LOCK(script_instances_mutex);
+ MutexLock lock(script_instances_mutex);
for (SelfList<CSharpScript> *elem = script_list.first(); elem; elem = elem->next()) {
// Cast to CSharpScript to avoid being erased by accident
@@ -1204,7 +1204,7 @@ void CSharpLanguage::set_language_index(int p_idx) {
void CSharpLanguage::release_script_gchandle(Ref<MonoGCHandle> &p_gchandle) {
if (!p_gchandle->is_released()) { // Do not lock unnecessarily
- SCOPED_MUTEX_LOCK(get_singleton()->script_gchandle_release_mutex);
+ MutexLock lock(get_singleton()->script_gchandle_release_mutex);
p_gchandle->release();
}
}
@@ -1214,7 +1214,7 @@ void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, Ref<Mon
uint32_t pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(p_expected_obj); // We might lock after this, so pin it
if (!p_gchandle->is_released()) { // Do not lock unnecessarily
- SCOPED_MUTEX_LOCK(get_singleton()->script_gchandle_release_mutex);
+ MutexLock lock(get_singleton()->script_gchandle_release_mutex);
MonoObject *target = p_gchandle->get_target();
@@ -1239,24 +1239,6 @@ CSharpLanguage::CSharpLanguage() {
gdmono = NULL;
-#ifdef NO_THREADS
- script_instances_mutex = NULL;
- script_gchandle_release_mutex = NULL;
- language_bind_mutex = NULL;
-#else
- script_instances_mutex = Mutex::create();
- script_gchandle_release_mutex = Mutex::create();
- language_bind_mutex = Mutex::create();
-#endif
-
-#ifdef DEBUG_ENABLED
-#ifdef NO_THREADS
- unsafe_object_references_lock = NULL;
-#else
- unsafe_object_references_lock = Mutex::create();
-#endif
-#endif
-
lang_idx = -1;
scripts_metadata_invalidated = true;
@@ -1269,29 +1251,6 @@ CSharpLanguage::CSharpLanguage() {
CSharpLanguage::~CSharpLanguage() {
finish();
-
- if (script_instances_mutex) {
- memdelete(script_instances_mutex);
- script_instances_mutex = NULL;
- }
-
- if (language_bind_mutex) {
- memdelete(language_bind_mutex);
- language_bind_mutex = NULL;
- }
-
- if (script_gchandle_release_mutex) {
- memdelete(script_gchandle_release_mutex);
- script_gchandle_release_mutex = NULL;
- }
-
-#ifdef DEBUG_ENABLED
- if (unsafe_object_references_lock) {
- memdelete(unsafe_object_references_lock);
- unsafe_object_references_lock = NULL;
- }
-#endif
-
singleton = NULL;
}
@@ -1346,7 +1305,7 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b
void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
- SCOPED_MUTEX_LOCK(language_bind_mutex);
+ MutexLock lock(language_bind_mutex);
Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object);
if (match)
@@ -1381,7 +1340,7 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
GD_MONO_ASSERT_THREAD_ATTACHED;
{
- SCOPED_MUTEX_LOCK(language_bind_mutex);
+ MutexLock lock(language_bind_mutex);
Map<Object *, CSharpScriptBinding>::Element *data = (Map<Object *, CSharpScriptBinding>::Element *)p_data;
@@ -2187,7 +2146,7 @@ CSharpInstance::~CSharpInstance() {
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get();
if (!script_binding.inited) {
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->get_language_bind_mutex());
+ MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex());
if (!script_binding.inited) { // Other thread may have set it up
// Already had a binding that needs to be setup
@@ -2203,7 +2162,7 @@ CSharpInstance::~CSharpInstance() {
}
if (script.is_valid() && owner) {
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+ MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
#ifdef DEBUG_ENABLED
// CSharpInstance must not be created unless it's going to be added to the list for sure
@@ -2979,7 +2938,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
instance->_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback)
{
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+ MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
instances.insert(instance->owner);
}
@@ -3067,7 +3026,7 @@ PlaceHolderScriptInstance *CSharpScript::placeholder_instance_create(Object *p_t
bool CSharpScript::instance_has(const Object *p_this) const {
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+ MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
return instances.has((Object *)p_this);
}
@@ -3140,7 +3099,7 @@ Error CSharpScript::reload(bool p_keep_state) {
bool has_instances;
{
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+ MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
has_instances = instances.size();
}
@@ -3476,7 +3435,7 @@ CSharpScript::CSharpScript() :
#ifdef DEBUG_ENABLED
{
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+ MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
CSharpLanguage::get_singleton()->script_list.add(&this->script_list);
}
#endif
@@ -3485,7 +3444,7 @@ CSharpScript::CSharpScript() :
CSharpScript::~CSharpScript() {
#ifdef DEBUG_ENABLED
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex);
+ MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
CSharpLanguage::get_singleton()->script_list.remove(&this->script_list);
#endif
}
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index 627218eaf5..f44c4aebc4 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -325,16 +325,16 @@ class CSharpLanguage : public ScriptLanguage {
GDMono *gdmono;
SelfList<CSharpScript>::List script_list;
- Mutex *script_instances_mutex;
- Mutex *script_gchandle_release_mutex;
- Mutex *language_bind_mutex;
+ Mutex script_instances_mutex;
+ Mutex script_gchandle_release_mutex;
+ Mutex language_bind_mutex;
Map<Object *, CSharpScriptBinding> script_bindings;
#ifdef DEBUG_ENABLED
// List of unsafe object references
Map<ObjectID, int> unsafe_object_references;
- Mutex *unsafe_object_references_lock;
+ Mutex unsafe_object_references_lock;
#endif
struct StringNameCache {
@@ -376,7 +376,7 @@ class CSharpLanguage : public ScriptLanguage {
public:
StringNameCache string_names;
- Mutex *get_language_bind_mutex() { return language_bind_mutex; }
+ const Mutex &get_language_bind_mutex() { return language_bind_mutex; }
_FORCE_INLINE_ int get_language_index() { return lang_idx; }
void set_language_index(int p_idx);
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
index c3db52aa9e..af8d070cbd 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using Godot;
+using GodotTools.Ides.Rider;
using GodotTools.Internals;
using Directory = System.IO.Directory;
using Environment = System.Environment;
@@ -54,6 +55,12 @@ namespace GodotTools.Build
return msbuildPath;
}
+ case BuildManager.BuildTool.JetBrainsMsBuild:
+ var editorPath = (string)editorSettings.GetSetting(RiderPathManager.EditorPathSettingName);
+ if (!File.Exists(editorPath))
+ throw new FileNotFoundException($"Cannot find Rider executable. Tried with path: {editorPath}");
+ var riderDir = new FileInfo(editorPath).Directory.Parent;
+ return Path.Combine(riderDir.FullName, @"tools\MSBuild\Current\Bin\MSBuild.exe");
default:
throw new IndexOutOfRangeException("Invalid build tool in editor settings");
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
index fa6bf4dafd..69a8c9cf4a 100644
--- a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using GodotTools.Build;
+using GodotTools.Ides.Rider;
using GodotTools.Internals;
using GodotTools.Utils;
using static GodotTools.Internals.Globals;
@@ -16,6 +17,7 @@ namespace GodotTools
public const string PropNameMsbuildMono = "MSBuild (Mono)";
public const string PropNameMsbuildVs = "MSBuild (VS Build Tools)";
+ public const string PropNameMsbuildJetBrains = "MSBuild (JetBrains Rider)";
public const string MsBuildIssuesFileName = "msbuild_issues.csv";
public const string MsBuildLogFileName = "msbuild_log.txt";
@@ -23,7 +25,8 @@ namespace GodotTools
public enum BuildTool
{
MsBuildMono,
- MsBuildVs
+ MsBuildVs,
+ JetBrainsMsBuild
}
private static void RemoveOldIssuesFile(BuildInfo buildInfo)
@@ -181,7 +184,7 @@ namespace GodotTools
var buildInfo = new BuildInfo(GodotSharpDirs.ProjectSlnPath, config);
// Add Godot defines
- string constants = buildTool == BuildTool.MsBuildVs ? "GodotDefineConstants=\"" : "GodotDefineConstants=\\\"";
+ string constants = buildTool != BuildTool.MsBuildMono ? "GodotDefineConstants=\"" : "GodotDefineConstants=\\\"";
foreach (var godotDefine in godotDefines)
constants += $"GODOT_{godotDefine.ToUpper().Replace("-", "_").Replace(" ", "_").Replace(";", "_")};";
@@ -189,7 +192,7 @@ namespace GodotTools
if (Internal.GodotIsRealTDouble())
constants += "GODOT_REAL_T_IS_DOUBLE;";
- constants += buildTool == BuildTool.MsBuildVs ? "\"" : "\\\"";
+ constants += buildTool != BuildTool.MsBuildMono ? "\"" : "\\\"";
buildInfo.CustomProperties.Add(constants);
@@ -245,18 +248,22 @@ namespace GodotTools
public static void Initialize()
{
// Build tool settings
-
- EditorDef("mono/builds/build_tool", OS.IsWindows ? BuildTool.MsBuildVs : BuildTool.MsBuildMono);
-
var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
-
+ var msbuild = BuildTool.MsBuildMono;
+ if (OS.IsWindows)
+ msbuild = RiderPathManager.IsRider((string) editorSettings.GetSetting(RiderPathManager.EditorPathSettingName))
+ ? BuildTool.JetBrainsMsBuild
+ : BuildTool.MsBuildVs;
+
+ EditorDef("mono/builds/build_tool", msbuild);
+
editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
{
["type"] = Godot.Variant.Type.Int,
["name"] = "mono/builds/build_tool",
["hint"] = Godot.PropertyHint.Enum,
["hint_string"] = OS.IsWindows ?
- $"{PropNameMsbuildMono},{PropNameMsbuildVs}" :
+ $"{PropNameMsbuildMono},{PropNameMsbuildVs},{PropNameMsbuildJetBrains}" :
$"{PropNameMsbuildMono}"
});
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
index 9038333d38..5965e0fbcf 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
@@ -11,6 +11,10 @@ using Environment = System.Environment;
using File = System.IO.File;
using Path = System.IO.Path;
using OS = GodotTools.Utils.OS;
+// ReSharper disable UnassignedField.Local
+// ReSharper disable InconsistentNaming
+// ReSharper disable UnassignedField.Global
+// ReSharper disable MemberHidesStaticFromOuterClass
namespace GodotTools.Ides.Rider
{
@@ -131,28 +135,45 @@ namespace GodotTools.Ides.Rider
if (OS.IsWindows)
{
var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
- return Path.Combine(localAppData, @"JetBrains\Toolbox\apps\Rider");
+ return GetToolboxRiderRootPath(localAppData);
}
if (OS.IsOSX)
{
var home = Environment.GetEnvironmentVariable("HOME");
- if (!string.IsNullOrEmpty(home))
- {
- return Path.Combine(home, @"Library/Application Support/JetBrains/Toolbox/apps/Rider");
- }
+ if (string.IsNullOrEmpty(home))
+ return string.Empty;
+ var localAppData = Path.Combine(home, @"Library/Application Support");
+ return GetToolboxRiderRootPath(localAppData);
}
if (OS.IsUnixLike())
{
var home = Environment.GetEnvironmentVariable("HOME");
- if (!string.IsNullOrEmpty(home))
- {
- return Path.Combine(home, @".local/share/JetBrains/Toolbox/apps/Rider");
- }
+ if (string.IsNullOrEmpty(home))
+ return string.Empty;
+ var localAppData = Path.Combine(home, @".local/share");
+ return GetToolboxRiderRootPath(localAppData);
+ }
+
+ return string.Empty;
+ }
+
+
+ private static string GetToolboxRiderRootPath(string localAppData)
+ {
+ var toolboxPath = Path.Combine(localAppData, @"JetBrains\Toolbox");
+ var settingsJson = Path.Combine(toolboxPath, ".settings.json");
+
+ if (File.Exists(settingsJson))
+ {
+ var path = SettingsJson.GetInstallLocationFromJson(File.ReadAllText(settingsJson));
+ if (!string.IsNullOrEmpty(path))
+ toolboxPath = path;
}
- throw new Exception("Unexpected OS.");
+ var toolboxRiderRootPath = Path.Combine(toolboxPath, @"apps\Rider");
+ return toolboxRiderRootPath;
}
internal static ProductInfo GetBuildVersion(string path)
@@ -226,8 +247,8 @@ namespace GodotTools.Ides.Rider
{
try
{
- // use history.json - last entry stands for the active build https://jetbrains.slack.com/archives/C07KNP99D/p1547807024066500?thread_ts=1547731708.057700&cid=C07KNP99D
- var historyFile = Path.Combine(channelDir, ".history.json");
+ // use history.json - last entry stands for the active build https://jetbrains.slack.com/archives/C07KNP99D/p1547807024066500?thread_ts=1547731708.057700&cid=C07KNP99D
+ var historyFile = Path.Combine(channelDir, ".history.json");
if (File.Exists(historyFile))
{
var json = File.ReadAllText(historyFile);
@@ -255,14 +276,14 @@ namespace GodotTools.Ides.Rider
}
}
- // changes in toolbox json files format may brake the logic above, so return all found Rider installations
- return Directory.GetDirectories(channelDir)
- .SelectMany(buildDir => GetExecutablePaths(dirName, searchPattern, isMac, buildDir));
+ // changes in toolbox json files format may brake the logic above, so return all found Rider installations
+ return Directory.GetDirectories(channelDir)
+ .SelectMany(buildDir => GetExecutablePaths(dirName, searchPattern, isMac, buildDir));
}
catch (Exception e)
{
- // do not write to Debug.Log, just log it.
- Logger.Warn($"Failed to get RiderPath from {channelDir}", e);
+ // do not write to Debug.Log, just log it.
+ Logger.Warn($"Failed to get RiderPath from {channelDir}", e);
}
return new string[0];
@@ -289,6 +310,27 @@ namespace GodotTools.Ides.Rider
#pragma warning disable 0649
[Serializable]
+ class SettingsJson
+ {
+ public string install_location;
+
+ [CanBeNull]
+ public static string GetInstallLocationFromJson(string json)
+ {
+ try
+ {
+ return JsonConvert.DeserializeObject<SettingsJson>(json).install_location;
+ }
+ catch (Exception)
+ {
+ Logger.Warn($"Failed to get install_location from json {json}");
+ }
+
+ return null;
+ }
+ }
+
+ [Serializable]
class ToolboxHistory
{
public List<ItemNode> history;
@@ -372,7 +414,6 @@ namespace GodotTools.Ides.Rider
[Serializable]
class ActiveApplication
{
- // ReSharper disable once InconsistentNaming
public List<string> builds;
}
@@ -380,6 +421,7 @@ namespace GodotTools.Ides.Rider
public struct RiderInfo
{
+ // ReSharper disable once NotAccessedField.Global
public bool IsToolbox;
public string Presentation;
public Version BuildNumber;
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
index 558a242bf9..ee5677a6a8 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathManager.cs
@@ -9,13 +9,13 @@ namespace GodotTools.Ides.Rider
{
public static class RiderPathManager
{
- private static readonly string editorPathSettingName = "mono/editor/editor_path_optional";
+ public static readonly string EditorPathSettingName = "mono/editor/editor_path_optional";
private static string GetRiderPathFromSettings()
{
var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
- if (editorSettings.HasSetting(editorPathSettingName))
- return (string)editorSettings.GetSetting(editorPathSettingName);
+ if (editorSettings.HasSetting(EditorPathSettingName))
+ return (string)editorSettings.GetSetting(EditorPathSettingName);
return null;
}
@@ -25,22 +25,22 @@ namespace GodotTools.Ides.Rider
var editor = (ExternalEditorId)editorSettings.GetSetting("mono/editor/external_editor");
if (editor == ExternalEditorId.Rider)
{
- if (!editorSettings.HasSetting(editorPathSettingName))
+ if (!editorSettings.HasSetting(EditorPathSettingName))
{
- Globals.EditorDef(editorPathSettingName, "Optional");
+ Globals.EditorDef(EditorPathSettingName, "Optional");
editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
{
["type"] = Variant.Type.String,
- ["name"] = editorPathSettingName,
+ ["name"] = EditorPathSettingName,
["hint"] = PropertyHint.File,
["hint_string"] = ""
});
}
- var riderPath = (string)editorSettings.GetSetting(editorPathSettingName);
+ var riderPath = (string)editorSettings.GetSetting(EditorPathSettingName);
if (IsRiderAndExists(riderPath))
{
- Globals.EditorDef(editorPathSettingName, riderPath);
+ Globals.EditorDef(EditorPathSettingName, riderPath);
return;
}
@@ -50,17 +50,15 @@ namespace GodotTools.Ides.Rider
return;
var newPath = paths.Last().Path;
- Globals.EditorDef(editorPathSettingName, newPath);
- editorSettings.SetSetting(editorPathSettingName, newPath);
+ Globals.EditorDef(EditorPathSettingName, newPath);
+ editorSettings.SetSetting(EditorPathSettingName, newPath);
}
}
- private static bool IsRider(string path)
+ public static bool IsRider(string path)
{
if (string.IsNullOrEmpty(path))
- {
return false;
- }
var fileInfo = new FileInfo(path);
var filename = fileInfo.Name.ToLowerInvariant();
@@ -81,8 +79,8 @@ namespace GodotTools.Ides.Rider
return null;
var newPath = paths.Last().Path;
- editorSettings.SetSetting(editorPathSettingName, newPath);
- Globals.EditorDef(editorPathSettingName, newPath);
+ editorSettings.SetSetting(EditorPathSettingName, newPath);
+ Globals.EditorDef(EditorPathSettingName, newPath);
return newPath;
}
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index ae6625a6c6..41f49d8ac9 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -33,6 +33,7 @@
#include <mono/metadata/exception.h>
#include "core/os/dir_access.h"
+#include "core/os/mutex.h"
#include "core/os/os.h"
#include "core/project_settings.h"
#include "core/reference.h"
@@ -43,7 +44,6 @@
#include "../csharp_script.h"
#include "../utils/macros.h"
-#include "../utils/mutex_utils.h"
#include "gd_mono.h"
#include "gd_mono_cache.h"
#include "gd_mono_class.h"
@@ -74,7 +74,7 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) {
CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->value();
if (!script_binding.inited) {
- SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->get_language_bind_mutex());
+ MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex());
if (!script_binding.inited) { // Other thread may have set it up
// Already had a binding that needs to be setup
diff --git a/modules/mono/utils/mutex_utils.h b/modules/mono/utils/mutex_utils.h
deleted file mode 100644
index bafd875395..0000000000
--- a/modules/mono/utils/mutex_utils.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*************************************************************************/
-/* mutex_utils.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 MUTEX_UTILS_H
-#define MUTEX_UTILS_H
-
-#include "core/error_macros.h"
-#include "core/os/mutex.h"
-
-#include "macros.h"
-
-class ScopedMutexLock {
- Mutex *mutex;
-
-public:
- ScopedMutexLock(Mutex *mutex) {
- this->mutex = mutex;
-#ifndef NO_THREADS
-#ifdef DEBUG_ENABLED
- CRASH_COND(!mutex);
-#endif
- this->mutex->lock();
-#endif
- }
-
- ~ScopedMutexLock() {
-#ifndef NO_THREADS
-#ifdef DEBUG_ENABLED
- CRASH_COND(!mutex);
-#endif
- mutex->unlock();
-#endif
- }
-};
-
-#define SCOPED_MUTEX_LOCK(m_mutex) ScopedMutexLock GD_UNIQUE_NAME(__scoped_mutex_lock__)(m_mutex);
-
-// TODO: Add version that receives a lambda instead, once C++11 is allowed
-
-#endif // MUTEX_UTILS_H
diff --git a/modules/regex/doc_classes/RegEx.xml b/modules/regex/doc_classes/RegEx.xml
index e9f46b9853..3130c53331 100644
--- a/modules/regex/doc_classes/RegEx.xml
+++ b/modules/regex/doc_classes/RegEx.xml
@@ -10,7 +10,7 @@
var regex = RegEx.new()
regex.compile("\\w-(\\d+)")
[/codeblock]
- The search pattern must be escaped first for gdscript before it is escaped for the expression. For example, [code]compile("\\d+")[/code] would be read by RegEx as [code]\d+[/code]. Similarly, [code]compile("\"(?:\\\\.|[^\"])*\"")[/code] would be read as [code]"(?:\\.|[^"])*"[/code].
+ The search pattern must be escaped first for GDScript before it is escaped for the expression. For example, [code]compile("\\d+")[/code] would be read by RegEx as [code]\d+[/code]. Similarly, [code]compile("\"(?:\\\\.|[^\"])*\"")[/code] would be read as [code]"(?:\\.|[^"])*"[/code].
Using [method search] you can find the pattern within the given text. If a pattern is found, [RegExMatch] is returned and you can retrieve details of the results using functions such as [method RegExMatch.get_string] and [method RegExMatch.get_start].
[codeblock]
var regex = RegEx.new()
@@ -35,6 +35,8 @@
# Would print 01 03 3f 42
# Note that d0c would not match
[/codeblock]
+ [b]Note:[/b] Godot's regex implementation is based on the [url=https://www.pcre.org/]PCRE2[/url] library. You can view the full pattern reference [url=https://www.pcre.org/current/doc/html/pcre2pattern.html]here[/url].
+ [b]Tip:[/b] You can use [url=https://regexr.com/]Regexr[/url] to test regular expressions online.
</description>
<tutorials>
</tutorials>
diff --git a/modules/upnp/doc_classes/UPNP.xml b/modules/upnp/doc_classes/UPNP.xml
index 8549c173db..785c8dad50 100644
--- a/modules/upnp/doc_classes/UPNP.xml
+++ b/modules/upnp/doc_classes/UPNP.xml
@@ -45,7 +45,7 @@
<description>
Adds a mapping to forward the external [code]port[/code] (between 1 and 65535) on the default gateway (see [method get_gateway]) to the [code]internal_port[/code] on the local machine for the given protocol [code]proto[/code] (either [code]TCP[/code] or [code]UDP[/code], with UDP being the default). If a port mapping for the given port and protocol combination already exists on that gateway device, this method tries to overwrite it. If that is not desired, you can retrieve the gateway manually with [method get_gateway] and call [method add_port_mapping] on it, if any.
If [code]internal_port[/code] is [code]0[/code] (the default), the same port number is used for both the external and the internal port (the [code]port[/code] value).
- The description ([code]desc[/code]) is shown in some router UIs and can be used to point out which application added the mapping, and the lifetime of the mapping can be limited by [code]duration[/code]. However, some routers are incompatible with one or both of these, so use with caution and add fallback logic in case of errors to retry without them if in doubt.
+ The description ([code]desc[/code]) is shown in some router UIs and can be used to point out which application added the mapping. The mapping's lease duration can be limited by specifying a [code]duration[/code] (in seconds). However, some routers are incompatible with one or both of these, so use with caution and add fallback logic in case of errors to retry without them if in doubt.
See [enum UPNPResult] for possible return values.
</description>
</method>
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index 70f650cfd3..5036840413 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -928,13 +928,11 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) {
VisualScriptInstance *instance = memnew(VisualScriptInstance);
instance->create(Ref<VisualScript>(this), p_this);
- if (VisualScriptLanguage::singleton->lock)
- VisualScriptLanguage::singleton->lock->lock();
-
- instances[p_this] = instance;
+ {
+ MutexLock lock(VisualScriptLanguage::singleton->lock);
- if (VisualScriptLanguage::singleton->lock)
- VisualScriptLanguage::singleton->lock->unlock();
+ instances[p_this] = instance;
+ }
return instance;
}
@@ -2391,13 +2389,11 @@ VisualScriptInstance::VisualScriptInstance() {
VisualScriptInstance::~VisualScriptInstance() {
- if (VisualScriptLanguage::singleton->lock)
- VisualScriptLanguage::singleton->lock->lock();
-
- script->instances.erase(owner);
+ {
+ MutexLock lock(VisualScriptLanguage::singleton->lock);
- if (VisualScriptLanguage::singleton->lock)
- VisualScriptLanguage::singleton->lock->unlock();
+ script->instances.erase(owner);
+ }
for (Map<int, VisualScriptNodeInstance *>::Element *E = instances.front(); E; E = E->next()) {
memdelete(E->get());
@@ -2836,9 +2832,6 @@ VisualScriptLanguage::VisualScriptLanguage() {
_step = "_step";
_subcall = "_subcall";
singleton = this;
-#ifndef NO_THREADS
- lock = Mutex::create();
-#endif
_debug_parse_err_node = -1;
_debug_parse_err_file = "";
@@ -2859,9 +2852,6 @@ VisualScriptLanguage::VisualScriptLanguage() {
VisualScriptLanguage::~VisualScriptLanguage() {
- if (lock)
- memdelete(lock);
-
if (_call_stack) {
memdelete_arr(_call_stack);
}
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 08b84bce1d..0a6daba64f 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -530,7 +530,7 @@ public:
static VisualScriptLanguage *singleton;
- Mutex *lock;
+ Mutex lock;
bool debug_break(const String &p_error, bool p_allow_continue = true);
bool debug_break_parse(const String &p_file, int p_node, const String &p_error);