diff --git a/include/godot_cpp/core/mutex_lock.hpp b/include/godot_cpp/core/mutex_lock.hpp index 4d0029a9b..94f361ce8 100644 --- a/include/godot_cpp/core/mutex_lock.hpp +++ b/include/godot_cpp/core/mutex_lock.hpp @@ -35,22 +35,22 @@ namespace godot { class MutexLock { - const Mutex &mutex; + const Ref &mutex; public: - _ALWAYS_INLINE_ explicit MutexLock(const Mutex &p_mutex) : + _ALWAYS_INLINE_ explicit MutexLock(const Ref &p_mutex) : mutex(p_mutex) { - const_cast(&mutex)->lock(); + const_cast(*mutex)->lock(); } _ALWAYS_INLINE_ ~MutexLock() { - const_cast(&mutex)->unlock(); + const_cast(*mutex)->unlock(); } }; -#define _THREAD_SAFE_CLASS_ mutable Mutex _thread_safe_; +#define _THREAD_SAFE_CLASS_ mutable Ref _thread_safe_ = Ref(memnew(Mutex)); #define _THREAD_SAFE_METHOD_ MutexLock _thread_safe_method_(_thread_safe_); -#define _THREAD_SAFE_LOCK_ _thread_safe_.lock(); -#define _THREAD_SAFE_UNLOCK_ _thread_safe_.unlock(); +#define _THREAD_SAFE_LOCK_ _thread_safe_->lock(); +#define _THREAD_SAFE_UNLOCK_ _thread_safe_->unlock(); } // namespace godot diff --git a/test/build_profile.json b/test/build_profile.json index b4de43479..984091026 100644 --- a/test/build_profile.json +++ b/test/build_profile.json @@ -5,6 +5,7 @@ "Label", "MultiplayerAPI", "MultiplayerPeer", + "Mutex", "OS", "TileMap", "TileSet", diff --git a/test/project/main.gd b/test/project/main.gd index 52d7c0f13..140d87a4b 100644 --- a/test/project/main.gd +++ b/test/project/main.gd @@ -310,6 +310,12 @@ func _ready(): var przykład = ClassDB.instantiate("ExamplePrzykład") assert_equal(przykład.get_the_word(), "słowo to przykład") + # Test call some methods on a thread safe class. + var example_thread_safe = ExampleThreadSafeClass.new() + assert_equal(example_thread_safe.test(), 123) + assert_equal(example_thread_safe.test_const(), 456) + assert_equal(example_thread_safe.test_manual(), 789) + exit_with_status() func _on_Example_custom_signal(signal_name, value): diff --git a/test/src/example.cpp b/test/src/example.cpp index 43f781c4e..f87f8dc95 100644 --- a/test/src/example.cpp +++ b/test/src/example.cpp @@ -816,3 +816,25 @@ void ExampleInternal::_bind_methods() { int ExampleInternal::get_the_answer() const { return 42; } + +void ExampleThreadSafeClass::_bind_methods() { + ClassDB::bind_method(D_METHOD("test"), &ExampleThreadSafeClass::test); + ClassDB::bind_method(D_METHOD("test_const"), &ExampleThreadSafeClass::test_const); + ClassDB::bind_method(D_METHOD("test_manual"), &ExampleThreadSafeClass::test_manual); +} + +int ExampleThreadSafeClass::test() { + _THREAD_SAFE_METHOD_ + return 123; +} + +int ExampleThreadSafeClass::test_const() const { + _THREAD_SAFE_METHOD_ + return 456; +} + +int ExampleThreadSafeClass::test_manual() { + _THREAD_SAFE_LOCK_ + _THREAD_SAFE_UNLOCK_ + return 789; +} diff --git a/test/src/example.h b/test/src/example.h index d75abbd8f..2684d5dcc 100644 --- a/test/src/example.h +++ b/test/src/example.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -313,3 +314,17 @@ class ExampleInternal : public RefCounted { public: int get_the_answer() const; }; + +class ExampleThreadSafeClass : public RefCounted { + GDCLASS(ExampleThreadSafeClass, RefCounted); + + _THREAD_SAFE_CLASS_ + +protected: + static void _bind_methods(); + +public: + int test(); + int test_const() const; + int test_manual(); +}; diff --git a/test/src/register_types.cpp b/test/src/register_types.cpp index c68176d92..b9a9f7128 100644 --- a/test/src/register_types.cpp +++ b/test/src/register_types.cpp @@ -32,6 +32,7 @@ void initialize_example_module(ModuleInitializationLevel p_level) { GDREGISTER_RUNTIME_CLASS(ExampleRuntime); GDREGISTER_CLASS(ExamplePrzykład); GDREGISTER_INTERNAL_CLASS(ExampleInternal); + GDREGISTER_CLASS(ExampleThreadSafeClass); } void uninitialize_example_module(ModuleInitializationLevel p_level) {