summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/core_bind.cpp11
-rw-r--r--core/core_bind.h3
-rw-r--r--core/debugger/remote_debugger_peer.cpp8
-rw-r--r--core/debugger/remote_debugger_peer.h8
-rw-r--r--core/input/godotcontrollerdb.txt1
-rw-r--r--core/os/mutex.cpp4
-rw-r--r--core/os/mutex.h27
-rw-r--r--core/os/os.cpp8
-rw-r--r--core/os/os.h2
-rw-r--r--core/os/rw_lock.h17
-rw-r--r--core/os/semaphore.h13
-rw-r--r--core/os/thread.cpp4
-rw-r--r--core/os/thread.h21
-rw-r--r--core/os/threaded_array_processor.h19
-rw-r--r--core/templates/cowdata.h2
-rw-r--r--core/templates/safe_list.h159
-rw-r--r--core/templates/safe_refcount.h139
-rw-r--r--doc/classes/FileAccess.xml10
-rw-r--r--doc/classes/MenuButton.xml6
-rw-r--r--doc/classes/OS.xml14
-rw-r--r--doc/classes/OptionButton.xml6
-rw-r--r--drivers/unix/os_unix.cpp2
-rw-r--r--drivers/unix/thread_posix.cpp4
-rw-r--r--drivers/unix/thread_posix.h2
-rw-r--r--editor/editor_spin_slider.cpp2
-rw-r--r--editor/plugins/script_editor_plugin.cpp14
-rw-r--r--editor/plugins/script_editor_plugin.h1
-rw-r--r--editor/plugins/script_text_editor.cpp1
-rw-r--r--editor/plugins/text_editor.cpp1
-rw-r--r--main/main.cpp6
-rw-r--r--modules/noise/noise_texture_2d.cpp3
-rw-r--r--modules/websocket/remote_debugger_peer_websocket.h1
-rw-r--r--platform/web/audio_driver_web.cpp46
-rw-r--r--platform/web/audio_driver_web.h41
-rw-r--r--platform/web/os_web.cpp3
-rw-r--r--scene/3d/navigation_region_3d.cpp7
-rw-r--r--scene/gui/menu_button.cpp34
-rw-r--r--scene/gui/menu_button.h4
-rw-r--r--scene/gui/option_button.cpp61
-rw-r--r--scene/gui/option_button.h1
-rw-r--r--servers/audio/effects/audio_effect_record.cpp8
-rw-r--r--tests/core/templates/test_command_queue.h4
42 files changed, 103 insertions, 625 deletions
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index a164221fc2..723217875d 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -253,6 +253,10 @@ Error OS::shell_open(String p_uri) {
return ::OS::get_singleton()->shell_open(p_uri);
}
+String OS::read_string_from_stdin(bool p_block) {
+ return ::OS::get_singleton()->get_stdin_string(true);
+}
+
int OS::execute(const String &p_path, const Vector<String> &p_arguments, Array r_output, bool p_read_stderr, bool p_open_console) {
List<String> args;
for (int i = 0; i < p_arguments.size(); i++) {
@@ -425,10 +429,6 @@ void OS::delay_msec(int p_msec) const {
::OS::get_singleton()->delay_usec(int64_t(p_msec) * 1000);
}
-bool OS::can_use_threads() const {
- return ::OS::get_singleton()->can_use_threads();
-}
-
bool OS::is_userfs_persistent() const {
return ::OS::get_singleton()->is_userfs_persistent();
}
@@ -530,6 +530,7 @@ void OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_system_fonts"), &OS::get_system_fonts);
ClassDB::bind_method(D_METHOD("get_system_font_path", "font_name", "bold", "italic"), &OS::get_system_font_path, DEFVAL(false), DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_executable_path"), &OS::get_executable_path);
+ ClassDB::bind_method(D_METHOD("read_string_from_stdin", "block"), &OS::read_string_from_stdin, DEFVAL(true));
ClassDB::bind_method(D_METHOD("execute", "path", "arguments", "output", "read_stderr", "open_console"), &OS::execute, DEFVAL(Array()), DEFVAL(false), DEFVAL(false));
ClassDB::bind_method(D_METHOD("create_process", "path", "arguments", "open_console"), &OS::create_process, DEFVAL(false));
ClassDB::bind_method(D_METHOD("create_instance", "arguments"), &OS::create_instance);
@@ -561,8 +562,6 @@ void OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_userfs_persistent"), &OS::is_userfs_persistent);
ClassDB::bind_method(D_METHOD("is_stdout_verbose"), &OS::is_stdout_verbose);
- ClassDB::bind_method(D_METHOD("can_use_threads"), &OS::can_use_threads);
-
ClassDB::bind_method(D_METHOD("is_debug_build"), &OS::is_debug_build);
ClassDB::bind_method(D_METHOD("get_static_memory_usage"), &OS::get_static_memory_usage);
diff --git a/core/core_bind.h b/core/core_bind.h
index ba22971d78..a63ed91137 100644
--- a/core/core_bind.h
+++ b/core/core_bind.h
@@ -172,6 +172,7 @@ public:
Vector<String> get_system_fonts() const;
String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const;
String get_executable_path() const;
+ String read_string_from_stdin(bool p_block = true);
int execute(const String &p_path, const Vector<String> &p_arguments, Array r_output = Array(), bool p_read_stderr = false, bool p_open_console = false);
int create_process(const String &p_path, const Vector<String> &p_arguments, bool p_open_console = false);
int create_instance(const Vector<String> &p_arguments);
@@ -218,8 +219,6 @@ public:
uint64_t get_ticks_msec() const;
uint64_t get_ticks_usec() const;
- bool can_use_threads() const;
-
bool is_userfs_persistent() const;
bool is_stdout_verbose() const;
diff --git a/core/debugger/remote_debugger_peer.cpp b/core/debugger/remote_debugger_peer.cpp
index e9362b4ea4..525362ec7c 100644
--- a/core/debugger/remote_debugger_peer.cpp
+++ b/core/debugger/remote_debugger_peer.cpp
@@ -79,10 +79,8 @@ RemoteDebuggerPeerTCP::RemoteDebuggerPeerTCP(Ref<StreamPeerTCP> p_tcp) {
tcp_client = p_tcp;
if (tcp_client.is_valid()) { // Attaching to an already connected stream.
connected = true;
-#ifndef NO_THREADS
running = true;
thread.start(_thread_func, this);
-#endif
} else {
tcp_client.instantiate();
}
@@ -183,10 +181,8 @@ Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_po
return FAILED;
}
connected = true;
-#ifndef NO_THREADS
running = true;
thread.start(_thread_func, this);
-#endif
return OK;
}
@@ -208,9 +204,7 @@ void RemoteDebuggerPeerTCP::_thread_func(void *p_ud) {
}
void RemoteDebuggerPeerTCP::poll() {
-#ifdef NO_THREADS
- _poll();
-#endif
+ // Nothing to do, polling is done in thread.
}
void RemoteDebuggerPeerTCP::_poll() {
diff --git a/core/debugger/remote_debugger_peer.h b/core/debugger/remote_debugger_peer.h
index 473fd8d712..2ab641d537 100644
--- a/core/debugger/remote_debugger_peer.h
+++ b/core/debugger/remote_debugger_peer.h
@@ -43,12 +43,12 @@ protected:
public:
virtual bool is_peer_connected() = 0;
+ virtual int get_max_message_size() const = 0;
virtual bool has_message() = 0;
virtual Error put_message(const Array &p_arr) = 0;
virtual Array get_message() = 0;
virtual void close() = 0;
virtual void poll() = 0;
- virtual int get_max_message_size() const = 0;
virtual bool can_block() const { return true; } // If blocking io is allowed on main thread (debug).
RemoteDebuggerPeer();
@@ -81,12 +81,12 @@ public:
Error connect_to_host(const String &p_host, uint16_t p_port);
- void poll() override;
bool is_peer_connected() override;
+ int get_max_message_size() const override;
bool has_message() override;
- Array get_message() override;
Error put_message(const Array &p_arr) override;
- int get_max_message_size() const override;
+ Array get_message() override;
+ void poll() override;
void close() override;
RemoteDebuggerPeerTCP(Ref<StreamPeerTCP> p_stream = Ref<StreamPeerTCP>());
diff --git a/core/input/godotcontrollerdb.txt b/core/input/godotcontrollerdb.txt
index b2a6160c6c..e11099f380 100644
--- a/core/input/godotcontrollerdb.txt
+++ b/core/input/godotcontrollerdb.txt
@@ -32,6 +32,7 @@ Linux046dc216,046d-c216-Logitech Logitech Dual Action,a:b1,b:b2,y:b3,x:b0,start:
Linux20d6a713,Bensussen Deutsch & Associates Inc.(BDA) NSW Wired controller,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:-a5,dpleft:-a4,dpdown:+a5,dpright:+a4,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Web
Linux054c05c4,Sony Computer Entertainment Wireless Controller,a:b0,b:b1,y:b2,x:b3,start:b9,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Web
Linux18d19400,18d1-9400-Google LLC Stadia Controller rev. A,a:b0,b:b1,y:b3,x:b2,start:b7,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,platform:Web
+Linux054c0268,054c-0268-Sony PLAYSTATION(R)3 Controller,a:b0,b:b1,y:b2,x:b3,start:b9,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Web
# UWP
__UWP_GAMEPAD__,Xbox Controller,a:b2,b:b3,x:b4,y:b5,start:b0,back:b1,leftstick:b12,rightstick:b13,leftshoulder:b10,rightshoulder:b11,dpup:b6,dpdown:b7,dpleft:b8,dpright:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:UWP,
diff --git a/core/os/mutex.cpp b/core/os/mutex.cpp
index 1d4400bfc1..512db1737a 100644
--- a/core/os/mutex.cpp
+++ b/core/os/mutex.cpp
@@ -40,11 +40,7 @@ void _global_unlock() {
_global_mutex.unlock();
}
-#ifndef NO_THREADS
-
template class MutexImpl<std::recursive_mutex>;
template class MutexImpl<std::mutex>;
template class MutexLock<MutexImpl<std::recursive_mutex>>;
template class MutexLock<MutexImpl<std::mutex>>;
-
-#endif
diff --git a/core/os/mutex.h b/core/os/mutex.h
index a51248807b..eb58418bd6 100644
--- a/core/os/mutex.h
+++ b/core/os/mutex.h
@@ -34,8 +34,6 @@
#include "core/error/error_list.h"
#include "core/typedefs.h"
-#if !defined(NO_THREADS)
-
#include <mutex>
template <class StdMutexT>
@@ -79,29 +77,4 @@ extern template class MutexImpl<std::mutex>;
extern template class MutexLock<MutexImpl<std::recursive_mutex>>;
extern template class MutexLock<MutexImpl<std::mutex>>;
-#else
-
-class FakeMutex {
- FakeMutex() {}
-};
-
-template <class MutexT>
-class MutexImpl {
-public:
- _ALWAYS_INLINE_ void lock() const {}
- _ALWAYS_INLINE_ void unlock() const {}
- _ALWAYS_INLINE_ Error try_lock() const { return OK; }
-};
-
-template <class MutexT>
-class MutexLock {
-public:
- explicit MutexLock(const MutexT &p_mutex) {}
-};
-
-using Mutex = MutexImpl<FakeMutex>;
-using BinaryMutex = MutexImpl<FakeMutex>; // Non-recursive, handle with care
-
-#endif // !NO_THREADS
-
#endif // MUTEX_H
diff --git a/core/os/os.cpp b/core/os/os.cpp
index ee8da21751..2bdede889f 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -328,14 +328,6 @@ String OS::get_processor_name() const {
return "";
}
-bool OS::can_use_threads() const {
-#ifdef NO_THREADS
- return false;
-#else
- return true;
-#endif
-}
-
void OS::set_has_server_feature_callback(HasServerFeatureCallback p_callback) {
has_server_feature_callback = p_callback;
}
diff --git a/core/os/os.h b/core/os/os.h
index aa45a3b8a8..1a5e45968d 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -299,8 +299,6 @@ public:
virtual String get_unique_id() const;
- virtual bool can_use_threads() const;
-
bool has_feature(const String &p_feature);
void set_has_server_feature_callback(HasServerFeatureCallback p_callback);
diff --git a/core/os/rw_lock.h b/core/os/rw_lock.h
index a046f474ea..d3206547c7 100644
--- a/core/os/rw_lock.h
+++ b/core/os/rw_lock.h
@@ -33,8 +33,6 @@
#include "core/error/error_list.h"
-#if !defined(NO_THREADS)
-
#include <shared_mutex>
class RWLock {
@@ -72,21 +70,6 @@ public:
}
};
-#else
-
-class RWLock {
-public:
- void read_lock() const {}
- void read_unlock() const {}
- Error read_try_lock() const { return OK; }
-
- void write_lock() {}
- void write_unlock() {}
- Error write_try_lock() { return OK; }
-};
-
-#endif
-
class RWLockRead {
const RWLock &lock;
diff --git a/core/os/semaphore.h b/core/os/semaphore.h
index 72df52dd34..1a93d3ee2c 100644
--- a/core/os/semaphore.h
+++ b/core/os/semaphore.h
@@ -34,8 +34,6 @@
#include "core/error/error_list.h"
#include "core/typedefs.h"
-#if !defined(NO_THREADS)
-
#include <condition_variable>
#include <mutex>
@@ -70,15 +68,4 @@ public:
}
};
-#else
-
-class Semaphore {
-public:
- _ALWAYS_INLINE_ void post() const {}
- _ALWAYS_INLINE_ void wait() const {}
- _ALWAYS_INLINE_ bool try_wait() const { return true; }
-};
-
-#endif
-
#endif // SEMAPHORE_H
diff --git a/core/os/thread.cpp b/core/os/thread.cpp
index c8072b7280..e8ebb4597f 100644
--- a/core/os/thread.cpp
+++ b/core/os/thread.cpp
@@ -34,9 +34,6 @@
#include "thread.h"
#include "core/object/script_language.h"
-
-#if !defined(NO_THREADS)
-
#include "core/templates/safe_refcount.h"
Error (*Thread::set_name_func)(const String &) = nullptr;
@@ -128,5 +125,4 @@ Thread::~Thread() {
}
}
-#endif
#endif // PLATFORM_THREAD_OVERRIDE
diff --git a/core/os/thread.h b/core/os/thread.h
index 0fb283e224..7462ec17fb 100644
--- a/core/os/thread.h
+++ b/core/os/thread.h
@@ -35,15 +35,14 @@
#ifdef PLATFORM_THREAD_OVERRIDE
#include "platform_thread.h"
#else
+
#ifndef THREAD_H
#define THREAD_H
+#include "core/templates/safe_refcount.h"
#include "core/typedefs.h"
-#if !defined(NO_THREADS)
-#include "core/templates/safe_refcount.h"
#include <thread>
-#endif
class String;
@@ -65,7 +64,6 @@ public:
};
private:
-#if !defined(NO_THREADS)
friend class Main;
static ID main_thread_id;
@@ -82,7 +80,6 @@ private:
static void (*set_priority_func)(Thread::Priority);
static void (*init_func)();
static void (*term_func)();
-#endif
public:
static void _set_platform_funcs(
@@ -91,7 +88,6 @@ public:
void (*p_init_func)() = nullptr,
void (*p_term_func)() = nullptr);
-#if !defined(NO_THREADS)
_FORCE_INLINE_ ID get_id() const { return id; }
// get the ID of the caller thread
_FORCE_INLINE_ static ID get_caller_id() { return caller_id; }
@@ -107,19 +103,6 @@ public:
Thread();
~Thread();
-#else
- _FORCE_INLINE_ ID get_id() const { return 0; }
- // get the ID of the caller thread
- _FORCE_INLINE_ static ID get_caller_id() { return 0; }
- // get the ID of the main thread
- _FORCE_INLINE_ static ID get_main_id() { return 0; }
-
- static Error set_name(const String &p_name) { return ERR_UNAVAILABLE; }
-
- void start(Thread::Callback p_callback, void *p_user, const Settings &p_settings = Settings()) {}
- bool is_started() const { return false; }
- void wait_to_finish() {}
-#endif
};
#endif // THREAD_H
diff --git a/core/os/threaded_array_processor.h b/core/os/threaded_array_processor.h
index 935fc7a360..95a2253f14 100644
--- a/core/os/threaded_array_processor.h
+++ b/core/os/threaded_array_processor.h
@@ -49,8 +49,6 @@ struct ThreadArrayProcessData {
}
};
-#ifndef NO_THREADS
-
template <class T>
void process_array_thread(void *ud) {
T &data = *(T *)ud;
@@ -86,21 +84,4 @@ void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_us
memdelete_arr(threads);
}
-#else
-
-template <class C, class M, class U>
-void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) {
- ThreadArrayProcessData<C, U> data;
- data.method = p_method;
- data.instance = p_instance;
- data.userdata = p_userdata;
- data.index.set(0);
- data.elements = p_elements;
- for (uint32_t i = 0; i < p_elements; i++) {
- data.process(i);
- }
-}
-
-#endif
-
#endif // THREADED_ARRAY_PROCESSOR_H
diff --git a/core/templates/cowdata.h b/core/templates/cowdata.h
index f98b2308c9..1482e3eef1 100644
--- a/core/templates/cowdata.h
+++ b/core/templates/cowdata.h
@@ -46,9 +46,7 @@ class CharString;
template <class T, class V>
class VMap;
-#if !defined(NO_THREADS)
SAFE_NUMERIC_TYPE_PUN_GUARANTEES(uint32_t)
-#endif
// Silence a false positive warning (see GH-52119).
#if defined(__GNUC__) && !defined(__clang__)
diff --git a/core/templates/safe_list.h b/core/templates/safe_list.h
index e850f3bd5e..95e8ca1a14 100644
--- a/core/templates/safe_list.h
+++ b/core/templates/safe_list.h
@@ -33,11 +33,9 @@
#include "core/os/memory.h"
#include "core/typedefs.h"
-#include <functional>
-
-#if !defined(NO_THREADS)
#include <atomic>
+#include <functional>
#include <type_traits>
// Design goals for these classes:
@@ -239,159 +237,4 @@ public:
}
};
-#else // NO_THREADS
-
-// Effectively the same structure without the atomics. It's probably possible to simplify it but the semantics shouldn't differ greatly.
-template <class T, class A = DefaultAllocator>
-class SafeList {
- struct SafeListNode {
- SafeListNode *next = nullptr;
-
- // If the node is logically deleted, this pointer will typically point to the previous list item in time that was also logically deleted.
- SafeListNode *graveyard_next = nullptr;
-
- std::function<void(T)> deletion_fn = [](T t) { return; };
-
- T val;
- };
-
- SafeListNode *head = nullptr;
- SafeListNode *graveyard_head = nullptr;
-
- unsigned int active_iterator_count = 0;
-
-public:
- class Iterator {
- friend class SafeList;
-
- SafeListNode *cursor = nullptr;
- SafeList *list = nullptr;
-
- public:
- Iterator(SafeListNode *p_cursor, SafeList *p_list) :
- cursor(p_cursor), list(p_list) {
- list->active_iterator_count++;
- }
-
- ~Iterator() {
- list->active_iterator_count--;
- }
-
- T &operator*() {
- return cursor->val;
- }
-
- Iterator &operator++() {
- cursor = cursor->next;
- return *this;
- }
-
- // These two operators are mostly useful for comparisons to nullptr.
- bool operator==(const void *p_other) const {
- return cursor == p_other;
- }
-
- bool operator!=(const void *p_other) const {
- return cursor != p_other;
- }
-
- // These two allow easy range-based for loops.
- bool operator==(const Iterator &p_other) const {
- return cursor == p_other.cursor;
- }
-
- bool operator!=(const Iterator &p_other) const {
- return cursor != p_other.cursor;
- }
- };
-
-public:
- // Calling this will cause an allocation.
- void insert(T p_value) {
- SafeListNode *new_node = memnew_allocator(SafeListNode, A);
- new_node->val = p_value;
- new_node->next = head;
- head = new_node;
- }
-
- Iterator find(T p_value) {
- for (Iterator it = begin(); it != end(); ++it) {
- if (*it == p_value) {
- return it;
- }
- }
- return end();
- }
-
- void erase(T p_value, std::function<void(T)> p_deletion_fn) {
- erase(find(p_value), p_deletion_fn);
- }
-
- void erase(T p_value) {
- erase(find(p_value), [](T t) { return; });
- }
-
- void erase(Iterator p_iterator, std::function<void(T)> p_deletion_fn) {
- p_iterator.cursor->deletion_fn = p_deletion_fn;
- erase(p_iterator);
- }
-
- void erase(Iterator p_iterator) {
- Iterator prev = begin();
- for (; prev != end(); ++prev) {
- if (prev.cursor && prev.cursor->next == p_iterator.cursor) {
- break;
- }
- }
- if (prev == end()) {
- // Not in the list, nothing to do.
- return;
- }
- // First, remove the node from the list.
- prev.cursor->next = p_iterator.cursor->next;
-
- // Then queue it for deletion by putting it in the node graveyard. Don't touch `next` because an iterator might still be pointing at this node.
- p_iterator.cursor->graveyard_next = graveyard_head;
- graveyard_head = p_iterator.cursor;
- }
-
- Iterator begin() {
- return Iterator(head, this);
- }
-
- Iterator end() {
- return Iterator(nullptr, this);
- }
-
- // Calling this will cause zero to many deallocations.
- bool maybe_cleanup() {
- SafeListNode *cursor = graveyard_head;
- if (active_iterator_count != 0) {
- // It's not safe to clean up with an active iterator, because that iterator could be pointing to an element that we want to delete.
- return false;
- }
- graveyard_head = nullptr;
- // Our graveyard list is now unreachable by any active iterators, detached from the main graveyard head and ready for deletion.
- while (cursor) {
- SafeListNode *tmp = cursor;
- cursor = cursor->next;
- tmp->deletion_fn(tmp->val);
- memdelete_allocator<SafeListNode, A>(tmp);
- }
- return true;
- }
-
- ~SafeList() {
-#ifdef DEBUG_ENABLED
- if (!maybe_cleanup()) {
- ERR_PRINT("There are still iterators around when destructing a SafeList. Memory will be leaked. This is a bug.");
- }
-#else
- maybe_cleanup();
-#endif
- }
-};
-
-#endif
-
#endif // SAFE_LIST_H
diff --git a/core/templates/safe_refcount.h b/core/templates/safe_refcount.h
index 1f6551762e..c4ffe5ca02 100644
--- a/core/templates/safe_refcount.h
+++ b/core/templates/safe_refcount.h
@@ -33,8 +33,6 @@
#include "core/typedefs.h"
-#if !defined(NO_THREADS)
-
#include <atomic>
#include <type_traits>
@@ -191,141 +189,4 @@ public:
}
};
-#else
-
-template <class T>
-class SafeNumeric {
-protected:
- T value;
-
-public:
- _ALWAYS_INLINE_ void set(T p_value) {
- value = p_value;
- }
-
- _ALWAYS_INLINE_ T get() const {
- return value;
- }
-
- _ALWAYS_INLINE_ T increment() {
- return ++value;
- }
-
- _ALWAYS_INLINE_ T postincrement() {
- return value++;
- }
-
- _ALWAYS_INLINE_ T decrement() {
- return --value;
- }
-
- _ALWAYS_INLINE_ T postdecrement() {
- return value--;
- }
-
- _ALWAYS_INLINE_ T add(T p_value) {
- return value += p_value;
- }
-
- _ALWAYS_INLINE_ T postadd(T p_value) {
- T old = value;
- value += p_value;
- return old;
- }
-
- _ALWAYS_INLINE_ T sub(T p_value) {
- return value -= p_value;
- }
-
- _ALWAYS_INLINE_ T postsub(T p_value) {
- T old = value;
- value -= p_value;
- return old;
- }
-
- _ALWAYS_INLINE_ T exchange_if_greater(T p_value) {
- if (value < p_value) {
- value = p_value;
- }
- return value;
- }
-
- _ALWAYS_INLINE_ T conditional_increment() {
- if (value == 0) {
- return 0;
- } else {
- return ++value;
- }
- }
-
- _ALWAYS_INLINE_ explicit SafeNumeric<T>(T p_value = static_cast<T>(0)) :
- value(p_value) {
- }
-};
-
-class SafeFlag {
-protected:
- bool flag;
-
-public:
- _ALWAYS_INLINE_ bool is_set() const {
- return flag;
- }
-
- _ALWAYS_INLINE_ void set() {
- flag = true;
- }
-
- _ALWAYS_INLINE_ void clear() {
- flag = false;
- }
-
- _ALWAYS_INLINE_ void set_to(bool p_value) {
- flag = p_value;
- }
-
- _ALWAYS_INLINE_ explicit SafeFlag(bool p_value = false) :
- flag(p_value) {}
-};
-
-class SafeRefCount {
- uint32_t count = 0;
-
-public:
- _ALWAYS_INLINE_ bool ref() { // true on success
- if (count != 0) {
- ++count;
- return true;
- } else {
- return false;
- }
- }
-
- _ALWAYS_INLINE_ uint32_t refval() { // none-zero on success
- if (count != 0) {
- return ++count;
- } else {
- return 0;
- }
- }
-
- _ALWAYS_INLINE_ bool unref() { // true if must be disposed of
- return --count == 0;
- }
-
- _ALWAYS_INLINE_ uint32_t unrefval() { // 0 if must be disposed of
- return --count;
- }
-
- _ALWAYS_INLINE_ uint32_t get() const {
- return count;
- }
-
- _ALWAYS_INLINE_ void init(uint32_t p_value = 1) {
- count = p_value;
- }
-};
-
-#endif
-
#endif // SAFE_REFCOUNT_H
diff --git a/doc/classes/FileAccess.xml b/doc/classes/FileAccess.xml
index f4ae70cf22..e52f897164 100644
--- a/doc/classes/FileAccess.xml
+++ b/doc/classes/FileAccess.xml
@@ -20,13 +20,13 @@
[csharp]
public void Save(string content)
{
- using var file = FileAccess.Open("user://save_game.dat", File.ModeFlags.Write);
+ using var file = FileAccess.Open("user://save_game.dat", FileAccess.ModeFlags.Write);
file.StoreString(content);
}
public string Load()
{
- using var file = FileAccess.Open("user://save_game.dat", File.ModeFlags.Read);
+ using var file = FileAccess.Open("user://save_game.dat", FileAccess.ModeFlags.Read);
string content = file.GetAsText();
return content;
}
@@ -316,8 +316,7 @@
return (unsigned + MAX_15B) % MAX_16B - MAX_15B
func _ready():
- var f = File.new()
- f.open("user://file.dat", File.WRITE_READ)
+ var f = FileAccess.open("user://file.dat", FileAccess.WRITE_READ)
f.store_16(-42) # This wraps around and stores 65494 (2^16 - 42).
f.store_16(121) # In bounds, will store 121.
f.seek(0) # Go back to start to read the stored value.
@@ -329,8 +328,7 @@
[csharp]
public override void _Ready()
{
- var f = new File();
- f.Open("user://file.dat", File.ModeFlags.WriteRead);
+ using var f = FileAccess.Open("user://file.dat", FileAccess.ModeFlags.WriteRead);
f.Store16(unchecked((ushort)-42)); // This wraps around and stores 65494 (2^16 - 42).
f.Store16(121); // In bounds, will store 121.
f.Seek(0); // Go back to start to read the stored value.
diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml
index 1f38510e83..4d5d5a011b 100644
--- a/doc/classes/MenuButton.xml
+++ b/doc/classes/MenuButton.xml
@@ -25,6 +25,12 @@
If [code]true[/code], shortcuts are disabled and cannot be used to trigger the button.
</description>
</method>
+ <method name="show_popup">
+ <return type="void" />
+ <description>
+ Adjusts popup position and sizing for the [MenuButton], then shows the [PopupMenu]. Prefer this over using [code]get_popup().popup()[/code].
+ </description>
+ </method>
</methods>
<members>
<member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" overrides="BaseButton" enum="BaseButton.ActionMode" default="0" />
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index 313f3ab6db..bc6ac8012f 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -18,12 +18,6 @@
Displays a modal dialog box using the host OS' facilities. Execution is blocked until the dialog is closed.
</description>
</method>
- <method name="can_use_threads" qualifiers="const">
- <return type="bool" />
- <description>
- Returns [code]true[/code] if the current host platform is using multiple threads.
- </description>
- </method>
<method name="close_midi_inputs">
<return type="void" />
<description>
@@ -544,6 +538,14 @@
[b]Note:[/b] This method is implemented on Linux, macOS and Windows.
</description>
</method>
+ <method name="read_string_from_stdin">
+ <return type="String" />
+ <param index="0" name="block" type="bool" default="true" />
+ <description>
+ Reads a user input string from the standard input (usually the terminal).
+ [b]Note:[/b] This method is implemented on Linux, macOS and Windows. Non-blocking reads are not currently supported on any platform.
+ </description>
+ </method>
<method name="request_permission">
<return type="bool" />
<param index="0" name="name" type="String" />
diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml
index f10c096c1b..199535298c 100644
--- a/doc/classes/OptionButton.xml
+++ b/doc/classes/OptionButton.xml
@@ -190,6 +190,12 @@
Sets the tooltip of the item at index [param idx].
</description>
</method>
+ <method name="show_popup">
+ <return type="void" />
+ <description>
+ Adjusts popup position and sizing for the [OptionButton], then shows the [PopupMenu]. Prefer this over using [code]get_popup().popup()[/code].
+ </description>
+ </method>
</methods>
<members>
<member name="action_mode" type="int" setter="set_action_mode" getter="get_action_mode" overrides="BaseButton" enum="BaseButton.ActionMode" default="0" />
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index c8a42e925e..1151c2232e 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -126,9 +126,7 @@ int OS_Unix::unix_initialize_audio(int p_audio_driver) {
}
void OS_Unix::initialize_core() {
-#if !defined(NO_THREADS)
init_thread_posix();
-#endif
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_USERDATA);
diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp
index cb5f261e6e..6292d8b3bc 100644
--- a/drivers/unix/thread_posix.cpp
+++ b/drivers/unix/thread_posix.cpp
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(NO_THREADS)
+#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)
#include "thread_posix.h"
@@ -73,4 +73,4 @@ void init_thread_posix() {
Thread::_set_platform_funcs(&set_name, nullptr);
}
-#endif
+#endif // UNIX_ENABLED || PTHREAD_ENABLED
diff --git a/drivers/unix/thread_posix.h b/drivers/unix/thread_posix.h
index 672adcba72..87e42b3870 100644
--- a/drivers/unix/thread_posix.h
+++ b/drivers/unix/thread_posix.h
@@ -31,8 +31,6 @@
#ifndef THREAD_POSIX_H
#define THREAD_POSIX_H
-#if !defined(NO_THREADS)
void init_thread_posix();
-#endif
#endif // THREAD_POSIX_H
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index 4cd046e811..5edb6d877c 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -398,7 +398,7 @@ void EditorSpinSlider::_draw_spin_slider() {
grabbing_spinner_mouse_pos = get_global_position() + grabber_rect.get_center();
- bool display_grabber = (mouse_over_spin || mouse_over_grabber) && !grabbing_spinner && !(value_input_popup && value_input_popup->is_visible());
+ bool display_grabber = (grabbing_grabber || mouse_over_spin || mouse_over_grabber) && !grabbing_spinner && !(value_input_popup && value_input_popup->is_visible());
if (grabber->is_visible() != display_grabber) {
if (display_grabber) {
grabber->show();
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 4dcd0573e6..f70f0dc0aa 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -1613,7 +1613,7 @@ void ScriptEditor::_notification(int p_what) {
EditorNode::get_singleton()->disconnect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop));
} break;
- case NOTIFICATION_WM_WINDOW_FOCUS_IN: {
+ case NOTIFICATION_APPLICATION_FOCUS_IN: {
_test_script_times_on_disk();
_update_modified_scripts_for_external_editor();
} break;
@@ -2136,16 +2136,6 @@ void ScriptEditor::_update_script_names() {
_update_script_colors();
}
-void ScriptEditor::_update_script_connections() {
- for (int i = 0; i < tab_container->get_tab_count(); i++) {
- ScriptTextEditor *ste = Object::cast_to<ScriptTextEditor>(tab_container->get_tab_control(i));
- if (!ste) {
- continue;
- }
- ste->_update_connected_methods();
- }
-}
-
Ref<TextFile> ScriptEditor::_load_text_file(const String &p_path, Error *r_error) const {
if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
@@ -2819,7 +2809,6 @@ void ScriptEditor::_tree_changed() {
waiting_update_names = true;
call_deferred(SNAME("_update_script_names"));
- call_deferred(SNAME("_update_script_connections"));
}
void ScriptEditor::_split_dragged(float) {
@@ -3616,7 +3605,6 @@ void ScriptEditor::_bind_methods() {
ClassDB::bind_method("_goto_script_line2", &ScriptEditor::_goto_script_line2);
ClassDB::bind_method("_copy_script_path", &ScriptEditor::_copy_script_path);
- ClassDB::bind_method("_update_script_connections", &ScriptEditor::_update_script_connections);
ClassDB::bind_method("_help_class_open", &ScriptEditor::_help_class_open);
ClassDB::bind_method("_help_tab_goto", &ScriptEditor::_help_tab_goto);
ClassDB::bind_method("_live_auto_reload_running_scripts", &ScriptEditor::_live_auto_reload_running_scripts);
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 1e78dc4ec4..233baa9bd3 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -403,7 +403,6 @@ class ScriptEditor : public PanelContainer {
void _filter_scripts_text_changed(const String &p_newtext);
void _filter_methods_text_changed(const String &p_newtext);
void _update_script_names();
- void _update_script_connections();
bool _sort_list_on_update;
void _members_overview_selected(int p_idx);
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index c21b4356f8..a1d24907e5 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -289,6 +289,7 @@ void ScriptTextEditor::reload_text() {
te->tag_saved_version();
code_editor->update_line_and_column();
+ _validate_script();
}
void ScriptTextEditor::add_callback(const String &p_function, PackedStringArray p_args) {
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index 20809763d0..9846cd4a84 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -150,6 +150,7 @@ void TextEditor::reload_text() {
te->tag_saved_version();
code_editor->update_line_and_column();
+ _validate_script();
}
void TextEditor::_validate_script() {
diff --git a/main/main.cpp b/main/main.cpp
index 28a73ce585..5c2259bf7c 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1706,13 +1706,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
if (rtm >= 0 && rtm < 3) {
-#ifdef NO_THREADS
- rtm = OS::RENDER_THREAD_UNSAFE; // No threads available on this platform.
-#else
if (editor) {
rtm = OS::RENDER_THREAD_SAFE;
}
-#endif
OS::get_singleton()->_render_thread_mode = OS::RenderThreadMode(rtm);
}
@@ -1932,11 +1928,9 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
// Print engine name and version
print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE));
-#if !defined(NO_THREADS)
if (p_main_tid_override) {
Thread::main_thread_id = p_main_tid_override;
}
-#endif
#ifdef TOOLS_ENABLED
if (editor || project_manager || cmdline_tool) {
diff --git a/modules/noise/noise_texture_2d.cpp b/modules/noise/noise_texture_2d.cpp
index 8d279f9dd3..101a66371b 100644
--- a/modules/noise/noise_texture_2d.cpp
+++ b/modules/noise/noise_texture_2d.cpp
@@ -197,9 +197,6 @@ void NoiseTexture2D::_update_texture() {
use_thread = false;
first_time = false;
}
-#ifdef NO_THREADS
- use_thread = false;
-#endif
if (use_thread) {
if (!noise_thread.is_started()) {
noise_thread.start(_thread_function, this);
diff --git a/modules/websocket/remote_debugger_peer_websocket.h b/modules/websocket/remote_debugger_peer_websocket.h
index a37a789cbe..0292de68ad 100644
--- a/modules/websocket/remote_debugger_peer_websocket.h
+++ b/modules/websocket/remote_debugger_peer_websocket.h
@@ -51,6 +51,7 @@ public:
static RemoteDebuggerPeer *create(const String &p_uri);
Error connect_to_host(const String &p_uri);
+
bool is_peer_connected() override;
int get_max_message_size() const override;
bool has_message() override;
diff --git a/platform/web/audio_driver_web.cpp b/platform/web/audio_driver_web.cpp
index 0e37afc2cc..c4b27c782d 100644
--- a/platform/web/audio_driver_web.cpp
+++ b/platform/web/audio_driver_web.cpp
@@ -184,51 +184,6 @@ Error AudioDriverWeb::capture_stop() {
return OK;
}
-#ifdef NO_THREADS
-/// ScriptProcessorNode implementation
-AudioDriverScriptProcessor *AudioDriverScriptProcessor::singleton = nullptr;
-
-void AudioDriverScriptProcessor::_process_callback() {
- AudioDriverScriptProcessor::singleton->_audio_driver_capture();
- AudioDriverScriptProcessor::singleton->_audio_driver_process();
-}
-
-Error AudioDriverScriptProcessor::create(int &p_buffer_samples, int p_channels) {
- if (!godot_audio_has_script_processor()) {
- return ERR_UNAVAILABLE;
- }
- return (Error)godot_audio_script_create(&p_buffer_samples, p_channels);
-}
-
-void AudioDriverScriptProcessor::start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) {
- godot_audio_script_start(p_in_buf, p_in_buf_size, p_out_buf, p_out_buf_size, &_process_callback);
-}
-
-/// AudioWorkletNode implementation (no threads)
-AudioDriverWorklet *AudioDriverWorklet::singleton = nullptr;
-
-Error AudioDriverWorklet::create(int &p_buffer_size, int p_channels) {
- if (!godot_audio_has_worklet()) {
- return ERR_UNAVAILABLE;
- }
- return (Error)godot_audio_worklet_create(p_channels);
-}
-
-void AudioDriverWorklet::start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) {
- _audio_driver_process();
- godot_audio_worklet_start_no_threads(p_out_buf, p_out_buf_size, &_process_callback, p_in_buf, p_in_buf_size, &_capture_callback);
-}
-
-void AudioDriverWorklet::_process_callback(int p_pos, int p_samples) {
- AudioDriverWorklet *driver = AudioDriverWorklet::singleton;
- driver->_audio_driver_process(p_pos, p_samples);
-}
-
-void AudioDriverWorklet::_capture_callback(int p_pos, int p_samples) {
- AudioDriverWorklet *driver = AudioDriverWorklet::singleton;
- driver->_audio_driver_capture(p_pos, p_samples);
-}
-#else
/// AudioWorkletNode implementation (threads)
void AudioDriverWorklet::_audio_thread_func(void *p_data) {
AudioDriverWorklet *driver = static_cast<AudioDriverWorklet *>(p_data);
@@ -290,4 +245,3 @@ void AudioDriverWorklet::finish_driver() {
quit = true; // Ask thread to quit.
thread.wait_to_finish();
}
-#endif
diff --git a/platform/web/audio_driver_web.h b/platform/web/audio_driver_web.h
index dfce277c0c..0a322d61b4 100644
--- a/platform/web/audio_driver_web.h
+++ b/platform/web/audio_driver_web.h
@@ -89,46 +89,6 @@ public:
AudioDriverWeb() {}
};
-#ifdef NO_THREADS
-class AudioDriverScriptProcessor : public AudioDriverWeb {
-private:
- static void _process_callback();
-
- static AudioDriverScriptProcessor *singleton;
-
-protected:
- Error create(int &p_buffer_samples, int p_channels) override;
- void start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) override;
-
-public:
- virtual const char *get_name() const override { return "ScriptProcessor"; }
-
- virtual void lock() override {}
- virtual void unlock() override {}
-
- AudioDriverScriptProcessor() { singleton = this; }
-};
-
-class AudioDriverWorklet : public AudioDriverWeb {
-private:
- static void _process_callback(int p_pos, int p_samples);
- static void _capture_callback(int p_pos, int p_samples);
-
- static AudioDriverWorklet *singleton;
-
-protected:
- virtual Error create(int &p_buffer_size, int p_output_channels) override;
- virtual void start(float *p_out_buf, int p_out_buf_size, float *p_in_buf, int p_in_buf_size) override;
-
-public:
- virtual const char *get_name() const override { return "AudioWorklet"; }
-
- virtual void lock() override {}
- virtual void unlock() override {}
-
- AudioDriverWorklet() { singleton = this; }
-};
-#else
class AudioDriverWorklet : public AudioDriverWeb {
private:
enum {
@@ -156,6 +116,5 @@ public:
void lock() override;
void unlock() override;
};
-#endif
#endif // AUDIO_DRIVER_WEB_H
diff --git a/platform/web/os_web.cpp b/platform/web/os_web.cpp
index ebe56924df..c263ee094b 100644
--- a/platform/web/os_web.cpp
+++ b/platform/web/os_web.cpp
@@ -239,9 +239,6 @@ OS_Web::OS_Web() {
godot_js_pwa_cb(&OS_Web::update_pwa_state_callback);
if (AudioDriverWeb::is_available()) {
-#ifdef NO_THREADS
- audio_drivers.push_back(memnew(AudioDriverScriptProcessor));
-#endif
audio_drivers.push_back(memnew(AudioDriverWorklet));
}
for (int i = 0; i < audio_drivers.size(); i++) {
diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp
index b060d314ba..06182d921c 100644
--- a/scene/3d/navigation_region_3d.cpp
+++ b/scene/3d/navigation_region_3d.cpp
@@ -261,12 +261,7 @@ void NavigationRegion3D::bake_navigation_mesh(bool p_on_thread) {
BakeThreadsArgs *args = memnew(BakeThreadsArgs);
args->nav_region = this;
- if (p_on_thread && !OS::get_singleton()->can_use_threads()) {
- WARN_PRINT("NavigationMesh bake 'on_thread' will be disabled as the current OS does not support multiple threads."
- "\nAs a fallback the navigation mesh will bake on the main thread which can cause framerate issues.");
- }
-
- if (p_on_thread && OS::get_singleton()->can_use_threads()) {
+ if (p_on_thread) {
bake_thread.start(_bake_navigation_mesh, args);
} else {
_bake_navigation_mesh(args);
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index 67a36240a2..fa8df48412 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -44,15 +44,12 @@ void MenuButton::shortcut_input(const Ref<InputEvent> &p_event) {
return;
}
- if (p_event->is_pressed() && !p_event->is_echo() && (Object::cast_to<InputEventKey>(p_event.ptr()) || Object::cast_to<InputEventJoypadButton>(p_event.ptr()) || Object::cast_to<InputEventAction>(*p_event) || Object::cast_to<InputEventShortcut>(*p_event))) {
- if (!get_parent() || !is_visible_in_tree() || is_disabled()) {
- return;
- }
-
- if (popup->activate_item_by_event(p_event, false)) {
- accept_event();
- }
+ if (p_event->is_pressed() && !p_event->is_echo() && !is_disabled() && is_visible_in_tree() && popup->activate_item_by_event(p_event, false)) {
+ accept_event();
+ return;
}
+
+ Button::shortcut_input(p_event);
}
void MenuButton::_popup_visibility_changed(bool p_visible) {
@@ -91,6 +88,18 @@ void MenuButton::pressed() {
return;
}
+ show_popup();
+}
+
+PopupMenu *MenuButton::get_popup() const {
+ return popup;
+}
+
+void MenuButton::show_popup() {
+ if (!get_viewport()) {
+ return;
+ }
+
emit_signal(SNAME("about_to_popup"));
Size2 size = get_size() * get_viewport()->get_canvas_transform().get_scale();
@@ -116,14 +125,6 @@ void MenuButton::pressed() {
popup->popup();
}
-void MenuButton::gui_input(const Ref<InputEvent> &p_event) {
- BaseButton::gui_input(p_event);
-}
-
-PopupMenu *MenuButton::get_popup() const {
- return popup;
-}
-
void MenuButton::set_switch_on_hover(bool p_enabled) {
switch_on_hover = p_enabled;
}
@@ -226,6 +227,7 @@ void MenuButton::_get_property_list(List<PropertyInfo> *p_list) const {
void MenuButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_popup"), &MenuButton::get_popup);
+ ClassDB::bind_method(D_METHOD("show_popup"), &MenuButton::show_popup);
ClassDB::bind_method(D_METHOD("set_switch_on_hover", "enable"), &MenuButton::set_switch_on_hover);
ClassDB::bind_method(D_METHOD("is_switch_on_hover"), &MenuButton::is_switch_on_hover);
ClassDB::bind_method(D_METHOD("set_disable_shortcuts", "disabled"), &MenuButton::set_disable_shortcuts);
diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h
index 97c0d21f1e..3aacbca3a8 100644
--- a/scene/gui/menu_button.h
+++ b/scene/gui/menu_button.h
@@ -44,8 +44,6 @@ class MenuButton : public Button {
Vector2i mouse_pos_adjusted;
- virtual void gui_input(const Ref<InputEvent> &p_event) override;
-
void _popup_visibility_changed(bool p_visible);
protected:
@@ -60,6 +58,8 @@ public:
virtual void pressed() override;
PopupMenu *get_popup() const;
+ void show_popup();
+
void set_switch_on_hover(bool p_enabled);
bool is_switch_on_hover();
void set_disable_shortcuts(bool p_disabled);
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 08f5e0bbfb..2cbece69f2 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -231,32 +231,7 @@ void OptionButton::pressed() {
return;
}
- Size2 size = get_size() * get_viewport()->get_canvas_transform().get_scale();
- popup->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y));
- popup->set_size(Size2(size.width, 0));
-
- // If not triggered by the mouse, start the popup with the checked item (or the first enabled one) focused.
- if (current != NONE_SELECTED && !popup->is_item_disabled(current)) {
- if (!_was_pressed_by_mouse()) {
- popup->set_focused_item(current);
- } else {
- popup->scroll_to_item(current);
- }
- } else {
- for (int i = 0; i < popup->get_item_count(); i++) {
- if (!popup->is_item_disabled(i)) {
- if (!_was_pressed_by_mouse()) {
- popup->set_focused_item(i);
- } else {
- popup->scroll_to_item(i);
- }
-
- break;
- }
- }
- }
-
- popup->popup();
+ show_popup();
}
void OptionButton::add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id) {
@@ -511,6 +486,39 @@ PopupMenu *OptionButton::get_popup() const {
return popup;
}
+void OptionButton::show_popup() {
+ if (!get_viewport()) {
+ return;
+ }
+
+ Size2 size = get_size() * get_viewport()->get_canvas_transform().get_scale();
+ popup->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y));
+ popup->set_size(Size2(size.width, 0));
+
+ // If not triggered by the mouse, start the popup with the checked item (or the first enabled one) focused.
+ if (current != NONE_SELECTED && !popup->is_item_disabled(current)) {
+ if (!_was_pressed_by_mouse()) {
+ popup->set_focused_item(current);
+ } else {
+ popup->scroll_to_item(current);
+ }
+ } else {
+ for (int i = 0; i < popup->get_item_count(); i++) {
+ if (!popup->is_item_disabled(i)) {
+ if (!_was_pressed_by_mouse()) {
+ popup->set_focused_item(i);
+ } else {
+ popup->scroll_to_item(i);
+ }
+
+ break;
+ }
+ }
+ }
+
+ popup->popup();
+}
+
void OptionButton::get_translatable_strings(List<String> *p_strings) const {
popup->get_translatable_strings(p_strings);
}
@@ -548,6 +556,7 @@ void OptionButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("_select_int", "idx"), &OptionButton::_select_int);
ClassDB::bind_method(D_METHOD("get_popup"), &OptionButton::get_popup);
+ ClassDB::bind_method(D_METHOD("show_popup"), &OptionButton::show_popup);
ClassDB::bind_method(D_METHOD("set_item_count", "count"), &OptionButton::set_item_count);
ClassDB::bind_method(D_METHOD("get_item_count"), &OptionButton::get_item_count);
diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h
index 2c7e0510f5..b76a31d37e 100644
--- a/scene/gui/option_button.h
+++ b/scene/gui/option_button.h
@@ -123,6 +123,7 @@ public:
void remove_item(int p_idx);
PopupMenu *get_popup() const;
+ void show_popup();
virtual void get_translatable_strings(List<String> *p_strings) const override;
diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp
index fff6dbc32a..b2e57c9a01 100644
--- a/servers/audio/effects/audio_effect_record.cpp
+++ b/servers/audio/effects/audio_effect_record.cpp
@@ -116,19 +116,11 @@ void AudioEffectRecordInstance::init() {
recording_data.clear(); //Clear data completely and reset length
is_recording = true;
-#ifdef NO_THREADS
- AudioServer::get_singleton()->add_update_callback(&AudioEffectRecordInstance::_update, this);
-#else
io_thread.start(_thread_callback, this);
-#endif
}
void AudioEffectRecordInstance::finish() {
-#ifdef NO_THREADS
- AudioServer::get_singleton()->remove_update_callback(&AudioEffectRecordInstance::_update, this);
-#else
io_thread.wait_to_finish();
-#endif
}
AudioEffectRecordInstance::~AudioEffectRecordInstance() {
diff --git a/tests/core/templates/test_command_queue.h b/tests/core/templates/test_command_queue.h
index 0d016f5d06..db1e436ed9 100644
--- a/tests/core/templates/test_command_queue.h
+++ b/tests/core/templates/test_command_queue.h
@@ -38,8 +38,6 @@
#include "core/templates/command_queue_mt.h"
#include "tests/test_macros.h"
-#if !defined(NO_THREADS)
-
namespace TestCommandQueue {
class ThreadWork {
@@ -426,6 +424,4 @@ TEST_CASE("[Stress][CommandQueue] Stress test command queue") {
}
} // namespace TestCommandQueue
-#endif // !defined(NO_THREADS)
-
#endif // TEST_COMMAND_QUEUE_H