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/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/visual_script/visual_script.cpp26
-rw-r--r--modules/visual_script/visual_script.h2
21 files changed, 139 insertions, 406 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/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/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);