diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/SCsub | 4 | ||||
-rw-r--r-- | core/config/project_settings.cpp | 20 | ||||
-rw-r--r-- | core/config/project_settings.h | 1 | ||||
-rw-r--r-- | core/core_bind.cpp | 2 | ||||
-rw-r--r-- | core/extension/gdextension.cpp | 16 | ||||
-rw-r--r-- | core/extension/gdextension.h | 1 | ||||
-rw-r--r-- | core/extension/gdextension_interface.h | 3 | ||||
-rw-r--r-- | core/io/dir_access.cpp | 4 | ||||
-rw-r--r-- | core/io/file_access_zip.cpp | 2 | ||||
-rw-r--r-- | core/object/class_db.cpp | 5 | ||||
-rw-r--r-- | core/object/object.cpp | 11 | ||||
-rw-r--r-- | core/object/object.h | 3 | ||||
-rw-r--r-- | core/object/undo_redo.cpp | 4 | ||||
-rw-r--r-- | core/os/os.cpp | 5 | ||||
-rw-r--r-- | core/os/os.h | 1 | ||||
-rw-r--r-- | core/templates/command_queue_mt.cpp | 29 | ||||
-rw-r--r-- | core/templates/command_queue_mt.h | 73 | ||||
-rw-r--r-- | core/templates/ring_buffer.h | 4 | ||||
-rw-r--r-- | core/templates/safe_refcount.h | 2 | ||||
-rw-r--r-- | core/variant/method_ptrcall.h | 10 | ||||
-rw-r--r-- | core/variant/variant.cpp | 44 | ||||
-rw-r--r-- | core/variant/variant.h | 23 | ||||
-rw-r--r-- | core/variant/variant_setget.cpp | 14 |
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; } |