summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/SCsub4
-rw-r--r--core/config/project_settings.cpp20
-rw-r--r--core/config/project_settings.h1
-rw-r--r--core/core_bind.cpp2
-rw-r--r--core/extension/gdextension.cpp16
-rw-r--r--core/extension/gdextension.h1
-rw-r--r--core/extension/gdextension_interface.h3
-rw-r--r--core/io/dir_access.cpp4
-rw-r--r--core/io/file_access_zip.cpp2
-rw-r--r--core/object/class_db.cpp5
-rw-r--r--core/object/object.cpp11
-rw-r--r--core/object/object.h3
-rw-r--r--core/object/undo_redo.cpp4
-rw-r--r--core/os/os.cpp5
-rw-r--r--core/os/os.h1
-rw-r--r--core/templates/command_queue_mt.cpp29
-rw-r--r--core/templates/command_queue_mt.h73
-rw-r--r--core/templates/ring_buffer.h4
-rw-r--r--core/templates/safe_refcount.h2
-rw-r--r--core/variant/method_ptrcall.h10
-rw-r--r--core/variant/variant.cpp44
-rw-r--r--core/variant/variant.h23
-rw-r--r--core/variant/variant_setget.cpp14
23 files changed, 123 insertions, 158 deletions
diff --git a/core/SCsub b/core/SCsub
index ec4658e8ca..91620cb075 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -29,8 +29,8 @@ if "SCRIPT_AES256_ENCRYPTION_KEY" in os.environ:
ec_valid = False
txt += txts
if not ec_valid:
- print("Error: Invalid AES256 encryption key, not 64 hexadecimal characters: '" + key + "'.")
- print(
+ methods.print_error(
+ f'Invalid AES256 encryption key, not 64 hexadecimal characters: "{key}".\n'
"Unset 'SCRIPT_AES256_ENCRYPTION_KEY' in your environment "
"or make sure that it contains exactly 64 hexadecimal characters."
)
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 104b17961d..ee20aea35d 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -1017,7 +1017,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
}
}
// Check for the existence of a csproj file.
- if (_csproj_exists(get_resource_path())) {
+ if (_csproj_exists(p_path.get_base_dir())) {
// If there is a csproj file, add the C# feature if it doesn't already exist.
if (!project_features.has("C#")) {
project_features.append("C#");
@@ -1473,7 +1473,9 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "0,4320,1,or_greater"), 0); // 8K resolution
GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true);
- GLOBAL_DEF("display/window/energy_saving/keep_screen_on.editor", false);
+#ifdef TOOLS_ENABLED
+ GLOBAL_DEF("display/window/energy_saving/keep_screen_on.editor_hint", false);
+#endif
GLOBAL_DEF("animation/warnings/check_invalid_track_paths", true);
GLOBAL_DEF("animation/warnings/check_angle_interpolation_type_conflicting", true);
@@ -1531,6 +1533,10 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF_BASIC("internationalization/rendering/root_node_auto_translate", true);
GLOBAL_DEF(PropertyInfo(Variant::INT, "gui/timers/incremental_search_max_interval_msec", PROPERTY_HINT_RANGE, "0,10000,1,or_greater"), 2000);
+ GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"), 0.5);
+#ifdef TOOLS_ENABLED
+ GLOBAL_DEF("gui/timers/tooltip_delay_sec.editor_hint", 0.5);
+#endif
GLOBAL_DEF_BASIC("gui/common/snap_controls_to_pixels", true);
GLOBAL_DEF_BASIC("gui/fonts/dynamic_fonts/use_oversampling", true);
@@ -1568,6 +1574,14 @@ ProjectSettings::ProjectSettings() {
ProjectSettings::get_singleton()->add_hidden_prefix("input/");
}
+ProjectSettings::ProjectSettings(const String &p_path) {
+ if (load_custom(p_path) == OK) {
+ project_loaded = true;
+ }
+}
+
ProjectSettings::~ProjectSettings() {
- singleton = nullptr;
+ if (singleton == this) {
+ singleton = nullptr;
+ }
}
diff --git a/core/config/project_settings.h b/core/config/project_settings.h
index 1bad76acb1..922c88c151 100644
--- a/core/config/project_settings.h
+++ b/core/config/project_settings.h
@@ -224,6 +224,7 @@ public:
#endif
ProjectSettings();
+ ProjectSettings(const String &p_path);
~ProjectSettings();
};
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index 467b696eae..0996db9d89 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -1921,7 +1921,7 @@ void EngineDebugger::send_message(const String &p_msg, const Array &p_data) {
Error EngineDebugger::call_capture(void *p_user, const String &p_cmd, const Array &p_data, bool &r_captured) {
Callable &capture = *(Callable *)p_user;
- if (capture.is_null()) {
+ if (!capture.is_valid()) {
return FAILED;
}
Variant cmd = p_cmd, data = p_data;
diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp
index 22a5df9935..b48ea97040 100644
--- a/core/extension/gdextension.cpp
+++ b/core/extension/gdextension.cpp
@@ -387,7 +387,7 @@ void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library
p_extension_funcs->set_func, // GDExtensionClassSet set_func;
p_extension_funcs->get_func, // GDExtensionClassGet get_func;
p_extension_funcs->get_property_list_func, // GDExtensionClassGetPropertyList get_property_list_func;
- p_extension_funcs->free_property_list_func, // GDExtensionClassFreePropertyList free_property_list_func;
+ nullptr, // GDExtensionClassFreePropertyList2 free_property_list_func;
p_extension_funcs->property_can_revert_func, // GDExtensionClassPropertyCanRevert property_can_revert_func;
p_extension_funcs->property_get_revert_func, // GDExtensionClassPropertyGetRevert property_get_revert_func;
nullptr, // GDExtensionClassValidateProperty validate_property_func;
@@ -406,7 +406,8 @@ void GDExtension::_register_extension_class(GDExtensionClassLibraryPtr p_library
};
const ClassCreationDeprecatedInfo legacy = {
- p_extension_funcs->notification_func,
+ p_extension_funcs->notification_func, // GDExtensionClassNotification notification_func;
+ p_extension_funcs->free_property_list_func, // GDExtensionClassFreePropertyList free_property_list_func;
};
_register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info3, &legacy);
}
@@ -420,7 +421,7 @@ void GDExtension::_register_extension_class2(GDExtensionClassLibraryPtr p_librar
p_extension_funcs->set_func, // GDExtensionClassSet set_func;
p_extension_funcs->get_func, // GDExtensionClassGet get_func;
p_extension_funcs->get_property_list_func, // GDExtensionClassGetPropertyList get_property_list_func;
- p_extension_funcs->free_property_list_func, // GDExtensionClassFreePropertyList free_property_list_func;
+ nullptr, // GDExtensionClassFreePropertyList2 free_property_list_func;
p_extension_funcs->property_can_revert_func, // GDExtensionClassPropertyCanRevert property_can_revert_func;
p_extension_funcs->property_get_revert_func, // GDExtensionClassPropertyGetRevert property_get_revert_func;
p_extension_funcs->validate_property_func, // GDExtensionClassValidateProperty validate_property_func;
@@ -438,7 +439,11 @@ void GDExtension::_register_extension_class2(GDExtensionClassLibraryPtr p_librar
p_extension_funcs->class_userdata, // void *class_userdata;
};
- _register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info3);
+ const ClassCreationDeprecatedInfo legacy = {
+ nullptr, // GDExtensionClassNotification notification_func;
+ p_extension_funcs->free_property_list_func, // GDExtensionClassFreePropertyList free_property_list_func;
+ };
+ _register_extension_class_internal(p_library, p_class_name, p_parent_class_name, &class_info3, &legacy);
}
#endif // DISABLE_DEPRECATED
@@ -514,13 +519,14 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr
extension->gdextension.set = p_extension_funcs->set_func;
extension->gdextension.get = p_extension_funcs->get_func;
extension->gdextension.get_property_list = p_extension_funcs->get_property_list_func;
- extension->gdextension.free_property_list = p_extension_funcs->free_property_list_func;
+ extension->gdextension.free_property_list2 = p_extension_funcs->free_property_list_func;
extension->gdextension.property_can_revert = p_extension_funcs->property_can_revert_func;
extension->gdextension.property_get_revert = p_extension_funcs->property_get_revert_func;
extension->gdextension.validate_property = p_extension_funcs->validate_property_func;
#ifndef DISABLE_DEPRECATED
if (p_deprecated_funcs) {
extension->gdextension.notification = p_deprecated_funcs->notification_func;
+ extension->gdextension.free_property_list = p_deprecated_funcs->free_property_list_func;
}
#endif // DISABLE_DEPRECATED
extension->gdextension.notification2 = p_extension_funcs->notification_func;
diff --git a/core/extension/gdextension.h b/core/extension/gdextension.h
index 23b1f51208..3b15639890 100644
--- a/core/extension/gdextension.h
+++ b/core/extension/gdextension.h
@@ -71,6 +71,7 @@ class GDExtension : public Resource {
struct ClassCreationDeprecatedInfo {
#ifndef DISABLE_DEPRECATED
GDExtensionClassNotification notification_func = nullptr;
+ GDExtensionClassFreePropertyList free_property_list_func = nullptr;
#endif // DISABLE_DEPRECATED
};
diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h
index e9c570e994..00a98af4e2 100644
--- a/core/extension/gdextension_interface.h
+++ b/core/extension/gdextension_interface.h
@@ -256,6 +256,7 @@ typedef struct {
typedef const GDExtensionPropertyInfo *(*GDExtensionClassGetPropertyList)(GDExtensionClassInstancePtr p_instance, uint32_t *r_count);
typedef void (*GDExtensionClassFreePropertyList)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list);
+typedef void (*GDExtensionClassFreePropertyList2)(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count);
typedef GDExtensionBool (*GDExtensionClassPropertyCanRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name);
typedef GDExtensionBool (*GDExtensionClassPropertyGetRevert)(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name, GDExtensionVariantPtr r_ret);
typedef GDExtensionBool (*GDExtensionClassValidateProperty)(GDExtensionClassInstancePtr p_instance, GDExtensionPropertyInfo *p_property);
@@ -333,7 +334,7 @@ typedef struct {
GDExtensionClassSet set_func;
GDExtensionClassGet get_func;
GDExtensionClassGetPropertyList get_property_list_func;
- GDExtensionClassFreePropertyList free_property_list_func;
+ GDExtensionClassFreePropertyList2 free_property_list_func;
GDExtensionClassPropertyCanRevert property_can_revert_func;
GDExtensionClassPropertyGetRevert property_get_revert_func;
GDExtensionClassValidateProperty validate_property_func;
diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp
index e99885befa..5df67b1103 100644
--- a/core/io/dir_access.cpp
+++ b/core/io/dir_access.cpp
@@ -582,6 +582,10 @@ void DirAccess::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove", "path"), &DirAccess::remove);
ClassDB::bind_static_method("DirAccess", D_METHOD("remove_absolute", "path"), &DirAccess::remove_absolute);
+ ClassDB::bind_method(D_METHOD("is_link", "path"), &DirAccess::is_link);
+ ClassDB::bind_method(D_METHOD("read_link", "path"), &DirAccess::read_link);
+ ClassDB::bind_method(D_METHOD("create_link", "source", "target"), &DirAccess::create_link);
+
ClassDB::bind_method(D_METHOD("set_include_navigational", "enable"), &DirAccess::set_include_navigational);
ClassDB::bind_method(D_METHOD("get_include_navigational"), &DirAccess::get_include_navigational);
ClassDB::bind_method(D_METHOD("set_include_hidden", "enable"), &DirAccess::set_include_hidden);
diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp
index 3c7f67664d..c0d1afc8e1 100644
--- a/core/io/file_access_zip.cpp
+++ b/core/io/file_access_zip.cpp
@@ -277,7 +277,7 @@ void FileAccessZip::seek_end(int64_t p_position) {
uint64_t FileAccessZip::get_position() const {
ERR_FAIL_NULL_V(zfile, 0);
- return unztell(zfile);
+ return unztell64(zfile);
}
uint64_t FileAccessZip::get_length() const {
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index 7ef1ce74ed..876635529c 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -138,7 +138,7 @@ public:
return nullptr;
}
- static void placeholder_instance_free_property_list(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list) {
+ static void placeholder_instance_free_property_list(GDExtensionClassInstancePtr p_instance, const GDExtensionPropertyInfo *p_list, uint32_t p_count) {
}
static GDExtensionBool placeholder_instance_property_can_revert(GDExtensionClassInstancePtr p_instance, GDExtensionConstStringNamePtr p_name) {
@@ -600,12 +600,13 @@ ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &p_class)
placeholder_extension->set = &PlaceholderExtensionInstance::placeholder_instance_set;
placeholder_extension->get = &PlaceholderExtensionInstance::placeholder_instance_get;
placeholder_extension->get_property_list = &PlaceholderExtensionInstance::placeholder_instance_get_property_list;
- placeholder_extension->free_property_list = &PlaceholderExtensionInstance::placeholder_instance_free_property_list;
+ placeholder_extension->free_property_list2 = &PlaceholderExtensionInstance::placeholder_instance_free_property_list;
placeholder_extension->property_can_revert = &PlaceholderExtensionInstance::placeholder_instance_property_can_revert;
placeholder_extension->property_get_revert = &PlaceholderExtensionInstance::placeholder_instance_property_get_revert;
placeholder_extension->validate_property = &PlaceholderExtensionInstance::placeholder_instance_validate_property;
#ifndef DISABLE_DEPRECATED
placeholder_extension->notification = nullptr;
+ placeholder_extension->free_property_list = nullptr;
#endif // DISABLE_DEPRECATED
placeholder_extension->notification2 = &PlaceholderExtensionInstance::placeholder_instance_notification;
placeholder_extension->to_string = &PlaceholderExtensionInstance::placeholder_instance_to_string;
diff --git a/core/object/object.cpp b/core/object/object.cpp
index f8d2feb5a8..b6c8a87a22 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -503,9 +503,14 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons
for (uint32_t i = 0; i < pcount; i++) {
p_list->push_back(PropertyInfo(pinfo[i]));
}
- if (current_extension->free_property_list) {
+ if (current_extension->free_property_list2) {
+ current_extension->free_property_list2(_extension_instance, pinfo, pcount);
+ }
+#ifndef DISABLE_DEPRECATED
+ else if (current_extension->free_property_list) {
current_extension->free_property_list(_extension_instance, pinfo);
}
+#endif // DISABLE_DEPRECATED
#ifdef TOOLS_ENABLED
}
#endif
@@ -1455,7 +1460,7 @@ Error Object::connect(const StringName &p_signal, const Callable &p_callable, ui
}
bool Object::is_connected(const StringName &p_signal, const Callable &p_callable) const {
- ERR_FAIL_COND_V_MSG(p_callable.is_null(), false, "Cannot determine if connected to '" + p_signal + "': the provided callable is null.");
+ ERR_FAIL_COND_V_MSG(p_callable.is_null(), false, "Cannot determine if connected to '" + p_signal + "': the provided callable is null."); // Should use `is_null`, see note in `connect` about the use of `is_valid`.
const SignalData *s = signal_map.getptr(p_signal);
if (!s) {
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal);
@@ -1478,7 +1483,7 @@ void Object::disconnect(const StringName &p_signal, const Callable &p_callable)
}
bool Object::_disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force) {
- ERR_FAIL_COND_V_MSG(p_callable.is_null(), false, "Cannot disconnect from '" + p_signal + "': the provided callable is null.");
+ ERR_FAIL_COND_V_MSG(p_callable.is_null(), false, "Cannot disconnect from '" + p_signal + "': the provided callable is null."); // Should use `is_null`, see note in `connect` about the use of `is_valid`.
SignalData *s = signal_map.getptr(p_signal);
if (!s) {
diff --git a/core/object/object.h b/core/object/object.h
index 915c3a8c25..adb50268d2 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -324,12 +324,13 @@ struct ObjectGDExtension {
GDExtensionClassSet set;
GDExtensionClassGet get;
GDExtensionClassGetPropertyList get_property_list;
- GDExtensionClassFreePropertyList free_property_list;
+ GDExtensionClassFreePropertyList2 free_property_list2;
GDExtensionClassPropertyCanRevert property_can_revert;
GDExtensionClassPropertyGetRevert property_get_revert;
GDExtensionClassValidateProperty validate_property;
#ifndef DISABLE_DEPRECATED
GDExtensionClassNotification notification;
+ GDExtensionClassFreePropertyList free_property_list;
#endif // DISABLE_DEPRECATED
GDExtensionClassNotification2 notification2;
GDExtensionClassToString to_string;
diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp
index 6a1385e268..4d67cd930e 100644
--- a/core/object/undo_redo.cpp
+++ b/core/object/undo_redo.cpp
@@ -144,7 +144,7 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode, bool p_back
}
void UndoRedo::add_do_method(const Callable &p_callable) {
- ERR_FAIL_COND(p_callable.is_null());
+ ERR_FAIL_COND(!p_callable.is_valid());
ERR_FAIL_COND(action_level <= 0);
ERR_FAIL_COND((current_action + 1) >= actions.size());
@@ -169,7 +169,7 @@ void UndoRedo::add_do_method(const Callable &p_callable) {
}
void UndoRedo::add_undo_method(const Callable &p_callable) {
- ERR_FAIL_COND(p_callable.is_null());
+ ERR_FAIL_COND(!p_callable.is_valid());
ERR_FAIL_COND(action_level <= 0);
ERR_FAIL_COND((current_action + 1) >= actions.size());
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 8582888740..fa7f23ded0 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -398,6 +398,11 @@ bool OS::has_feature(const String &p_feature) {
if (p_feature == "editor") {
return true;
}
+ if (p_feature == "editor_hint") {
+ return _in_editor;
+ } else if (p_feature == "editor_runtime") {
+ return !_in_editor;
+ }
#else
if (p_feature == "template") {
return true;
diff --git a/core/os/os.h b/core/os/os.h
index 069a3876af..d20f84b4ff 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -63,6 +63,7 @@ class OS {
bool _stdout_enabled = true;
bool _stderr_enabled = true;
bool _writing_movie = false;
+ bool _in_editor = false;
CompositeLogger *_logger = nullptr;
diff --git a/core/templates/command_queue_mt.cpp b/core/templates/command_queue_mt.cpp
index 0c5c6394a1..d9e5e0b217 100644
--- a/core/templates/command_queue_mt.cpp
+++ b/core/templates/command_queue_mt.cpp
@@ -41,35 +41,6 @@ void CommandQueueMT::unlock() {
mutex.unlock();
}
-void CommandQueueMT::wait_for_flush() {
- // wait one millisecond for a flush to happen
- OS::get_singleton()->delay_usec(1000);
-}
-
-CommandQueueMT::SyncSemaphore *CommandQueueMT::_alloc_sync_sem() {
- int idx = -1;
-
- while (true) {
- lock();
- for (int i = 0; i < SYNC_SEMAPHORES; i++) {
- if (!sync_sems[i].in_use) {
- sync_sems[i].in_use = true;
- idx = i;
- break;
- }
- }
- unlock();
-
- if (idx == -1) {
- wait_for_flush();
- } else {
- break;
- }
- }
-
- return &sync_sems[idx];
-}
-
CommandQueueMT::CommandQueueMT() {
}
diff --git a/core/templates/command_queue_mt.h b/core/templates/command_queue_mt.h
index a4ac338bed..c149861467 100644
--- a/core/templates/command_queue_mt.h
+++ b/core/templates/command_queue_mt.h
@@ -32,9 +32,9 @@
#define COMMAND_QUEUE_MT_H
#include "core/object/worker_thread_pool.h"
+#include "core/os/condition_variable.h"
#include "core/os/memory.h"
#include "core/os/mutex.h"
-#include "core/os/semaphore.h"
#include "core/string/print_string.h"
#include "core/templates/local_vector.h"
#include "core/templates/simple_type.h"
@@ -251,14 +251,14 @@
#define DECL_PUSH(N) \
template <typename T, typename M COMMA(N) COMMA_SEP_LIST(TYPE_PARAM, N)> \
void push(T *p_instance, M p_method COMMA(N) COMMA_SEP_LIST(PARAM, N)) { \
- CMD_TYPE(N) *cmd = allocate_and_lock<CMD_TYPE(N)>(); \
+ MutexLock mlock(mutex); \
+ CMD_TYPE(N) *cmd = allocate<CMD_TYPE(N)>(); \
cmd->instance = p_instance; \
cmd->method = p_method; \
SEMIC_SEP_LIST(CMD_ASSIGN_PARAM, N); \
if (pump_task_id != WorkerThreadPool::INVALID_TASK_ID) { \
WorkerThreadPool::get_singleton()->notify_yield_over(pump_task_id); \
} \
- unlock(); \
}
#define CMD_RET_TYPE(N) CommandRet##N<T, M, COMMA_SEP_LIST(TYPE_ARG, N) COMMA(N) R>
@@ -266,19 +266,17 @@
#define DECL_PUSH_AND_RET(N) \
template <typename T, typename M, COMMA_SEP_LIST(TYPE_PARAM, N) COMMA(N) typename R> \
void push_and_ret(T *p_instance, M p_method, COMMA_SEP_LIST(PARAM, N) COMMA(N) R *r_ret) { \
- SyncSemaphore *ss = _alloc_sync_sem(); \
- CMD_RET_TYPE(N) *cmd = allocate_and_lock<CMD_RET_TYPE(N)>(); \
+ MutexLock mlock(mutex); \
+ CMD_RET_TYPE(N) *cmd = allocate<CMD_RET_TYPE(N)>(); \
cmd->instance = p_instance; \
cmd->method = p_method; \
SEMIC_SEP_LIST(CMD_ASSIGN_PARAM, N); \
cmd->ret = r_ret; \
- cmd->sync_sem = ss; \
if (pump_task_id != WorkerThreadPool::INVALID_TASK_ID) { \
WorkerThreadPool::get_singleton()->notify_yield_over(pump_task_id); \
} \
- unlock(); \
- ss->sem.wait(); \
- ss->in_use = false; \
+ sync_tail++; \
+ _wait_for_sync(mlock); \
}
#define CMD_SYNC_TYPE(N) CommandSync##N<T, M COMMA(N) COMMA_SEP_LIST(TYPE_ARG, N)>
@@ -286,39 +284,31 @@
#define DECL_PUSH_AND_SYNC(N) \
template <typename T, typename M COMMA(N) COMMA_SEP_LIST(TYPE_PARAM, N)> \
void push_and_sync(T *p_instance, M p_method COMMA(N) COMMA_SEP_LIST(PARAM, N)) { \
- SyncSemaphore *ss = _alloc_sync_sem(); \
- CMD_SYNC_TYPE(N) *cmd = allocate_and_lock<CMD_SYNC_TYPE(N)>(); \
+ MutexLock mlock(mutex); \
+ CMD_SYNC_TYPE(N) *cmd = allocate<CMD_SYNC_TYPE(N)>(); \
cmd->instance = p_instance; \
cmd->method = p_method; \
SEMIC_SEP_LIST(CMD_ASSIGN_PARAM, N); \
- cmd->sync_sem = ss; \
if (pump_task_id != WorkerThreadPool::INVALID_TASK_ID) { \
WorkerThreadPool::get_singleton()->notify_yield_over(pump_task_id); \
} \
- unlock(); \
- ss->sem.wait(); \
- ss->in_use = false; \
+ sync_tail++; \
+ _wait_for_sync(mlock); \
}
#define MAX_CMD_PARAMS 15
class CommandQueueMT {
- struct SyncSemaphore {
- Semaphore sem;
- bool in_use = false;
- };
-
struct CommandBase {
+ bool sync = false;
virtual void call() = 0;
- virtual SyncSemaphore *get_sync_semaphore() { return nullptr; }
virtual ~CommandBase() = default; // Won't be called.
};
struct SyncCommand : public CommandBase {
- SyncSemaphore *sync_sem = nullptr;
-
- virtual SyncSemaphore *get_sync_semaphore() override {
- return sync_sem;
+ virtual void call() override {}
+ SyncCommand() {
+ sync = true;
}
};
@@ -340,9 +330,11 @@ class CommandQueueMT {
SYNC_SEMAPHORES = 8
};
+ BinaryMutex mutex;
LocalVector<uint8_t> command_mem;
- SyncSemaphore sync_sems[SYNC_SEMAPHORES];
- Mutex mutex;
+ ConditionVariable sync_cond_var;
+ uint32_t sync_head = 0;
+ uint32_t sync_tail = 0;
WorkerThreadPool::TaskID pump_task_id = WorkerThreadPool::INVALID_TASK_ID;
uint64_t flush_read_ptr = 0;
@@ -357,32 +349,23 @@ class CommandQueueMT {
return cmd;
}
- template <typename T>
- T *allocate_and_lock() {
- lock();
- T *ret = allocate<T>();
- return ret;
- }
-
void _flush() {
- lock();
-
if (unlikely(flush_read_ptr)) {
// Re-entrant call.
- unlock();
return;
}
+ lock();
+
WorkerThreadPool::thread_enter_command_queue_mt_flush(this);
while (flush_read_ptr < command_mem.size()) {
uint64_t size = *(uint64_t *)&command_mem[flush_read_ptr];
flush_read_ptr += 8;
CommandBase *cmd = reinterpret_cast<CommandBase *>(&command_mem[flush_read_ptr]);
-
- SyncSemaphore *sync_sem = cmd->get_sync_semaphore();
cmd->call();
- if (sync_sem) {
- sync_sem->sem.post(); // Release in case it needs sync/ret.
+ if (unlikely(cmd->sync)) {
+ sync_head++;
+ sync_cond_var.notify_all();
}
flush_read_ptr += size;
@@ -394,8 +377,12 @@ class CommandQueueMT {
unlock();
}
- void wait_for_flush();
- SyncSemaphore *_alloc_sync_sem();
+ _FORCE_INLINE_ void _wait_for_sync(MutexLock<BinaryMutex> &p_lock) {
+ uint32_t sync_head_goal = sync_tail;
+ do {
+ sync_cond_var.wait(p_lock);
+ } while (sync_head != sync_head_goal); // Can't use lower-than because of wraparound.
+ }
public:
void lock();
diff --git a/core/templates/ring_buffer.h b/core/templates/ring_buffer.h
index 54148a59bf..f5161cefa4 100644
--- a/core/templates/ring_buffer.h
+++ b/core/templates/ring_buffer.h
@@ -211,10 +211,10 @@ public:
size_mask = mask;
}
- RingBuffer<T>(int p_power = 0) {
+ RingBuffer(int p_power = 0) {
resize(p_power);
}
- ~RingBuffer<T>() {}
+ ~RingBuffer() {}
};
#endif // RING_BUFFER_H
diff --git a/core/templates/safe_refcount.h b/core/templates/safe_refcount.h
index 637b068da9..16b605eaff 100644
--- a/core/templates/safe_refcount.h
+++ b/core/templates/safe_refcount.h
@@ -146,7 +146,7 @@ public:
}
}
- _ALWAYS_INLINE_ explicit SafeNumeric<T>(T p_value = static_cast<T>(0)) {
+ _ALWAYS_INLINE_ explicit SafeNumeric(T p_value = static_cast<T>(0)) {
set(p_value);
}
};
diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h
index 123f2067e2..c8d1241d3d 100644
--- a/core/variant/method_ptrcall.h
+++ b/core/variant/method_ptrcall.h
@@ -159,10 +159,7 @@ MAKE_PTRARG_BY_REFERENCE(Variant);
template <typename T>
struct PtrToArg<T *> {
_FORCE_INLINE_ static T *convert(const void *p_ptr) {
- if (p_ptr == nullptr) {
- return nullptr;
- }
- return const_cast<T *>(*reinterpret_cast<T *const *>(p_ptr));
+ return likely(p_ptr) ? const_cast<T *>(*reinterpret_cast<T *const *>(p_ptr)) : nullptr;
}
typedef Object *EncodeT;
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
@@ -173,10 +170,7 @@ struct PtrToArg<T *> {
template <typename T>
struct PtrToArg<const T *> {
_FORCE_INLINE_ static const T *convert(const void *p_ptr) {
- if (p_ptr == nullptr) {
- return nullptr;
- }
- return *reinterpret_cast<T *const *>(p_ptr);
+ return likely(p_ptr) ? *reinterpret_cast<T *const *>(p_ptr) : nullptr;
}
typedef const Object *EncodeT;
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index 8e702ce8bb..fcbfdd4741 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -3495,50 +3495,6 @@ bool Variant::is_ref_counted() const {
return type == OBJECT && _get_obj().id.is_ref_counted();
}
-Vector<Variant> varray() {
- return Vector<Variant>();
-}
-
-Vector<Variant> varray(const Variant &p_arg1) {
- Vector<Variant> v;
- v.push_back(p_arg1);
- return v;
-}
-
-Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2) {
- Vector<Variant> v;
- v.push_back(p_arg1);
- v.push_back(p_arg2);
- return v;
-}
-
-Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3) {
- Vector<Variant> v;
- v.push_back(p_arg1);
- v.push_back(p_arg2);
- v.push_back(p_arg3);
- return v;
-}
-
-Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4) {
- Vector<Variant> v;
- v.push_back(p_arg1);
- v.push_back(p_arg2);
- v.push_back(p_arg3);
- v.push_back(p_arg4);
- return v;
-}
-
-Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5) {
- Vector<Variant> v;
- v.push_back(p_arg1);
- v.push_back(p_arg2);
- v.push_back(p_arg3);
- v.push_back(p_arg4);
- v.push_back(p_arg5);
- return v;
-}
-
void Variant::static_assign(const Variant &p_variant) {
}
diff --git a/core/variant/variant.h b/core/variant/variant.h
index e40df3171f..ea6ae02c1e 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -798,12 +798,23 @@ public:
//typedef Dictionary Dictionary; no
//typedef Array Array;
-Vector<Variant> varray();
-Vector<Variant> varray(const Variant &p_arg1);
-Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2);
-Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3);
-Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4);
-Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5);
+template <typename... VarArgs>
+Vector<Variant> varray(VarArgs... p_args) {
+ Vector<Variant> v;
+
+ Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
+ uint32_t argc = sizeof...(p_args);
+
+ if (argc > 0) {
+ v.resize(argc);
+ Variant *vw = v.ptrw();
+
+ for (uint32_t i = 0; i < argc; i++) {
+ vw[i] = args[i];
+ }
+ }
+ return v;
+}
struct VariantHasher {
static _FORCE_INLINE_ uint32_t hash(const Variant &p_variant) { return p_variant.hash(); }
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index 9d5ed22b1a..f49e9e54b3 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -251,15 +251,21 @@ void Variant::set_named(const StringName &p_member, const Variant &p_value, bool
return;
}
} else if (type == Variant::DICTIONARY) {
- Variant *v = VariantGetInternalPtr<Dictionary>::get_ptr(this)->getptr(p_member);
+ Dictionary &dict = *VariantGetInternalPtr<Dictionary>::get_ptr(this);
+
+ if (dict.is_read_only()) {
+ r_valid = false;
+ return;
+ }
+
+ Variant *v = dict.getptr(p_member);
if (v) {
*v = p_value;
- r_valid = true;
} else {
- VariantGetInternalPtr<Dictionary>::get_ptr(this)->operator[](p_member) = p_value;
- r_valid = true;
+ dict[p_member] = p_value;
}
+ r_valid = true;
} else {
r_valid = false;
}