diff options
Diffstat (limited to 'modules')
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); |