diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/SCsub | 2 | ||||
-rw-r--r-- | core/input/input_event.cpp | 2 | ||||
-rw-r--r-- | core/io/compression.cpp | 8 | ||||
-rw-r--r-- | core/io/file_access_zip.cpp | 2 | ||||
-rw-r--r-- | core/io/json.cpp | 8 | ||||
-rw-r--r-- | core/io/resource_loader.cpp | 25 | ||||
-rw-r--r-- | core/io/resource_loader.h | 2 | ||||
-rw-r--r-- | core/object/object.cpp | 8 | ||||
-rw-r--r-- | core/object/undo_redo.h | 2 | ||||
-rw-r--r-- | core/object/worker_thread_pool.cpp | 9 | ||||
-rw-r--r-- | core/os/os.cpp | 10 | ||||
-rw-r--r-- | core/os/threaded_array_processor.h | 87 | ||||
-rw-r--r-- | core/string/ustring.cpp | 9 | ||||
-rw-r--r-- | core/variant/callable_bind.cpp | 22 | ||||
-rw-r--r-- | core/variant/callable_bind.h | 2 | ||||
-rw-r--r-- | core/variant/native_ptr.h | 70 |
16 files changed, 118 insertions, 150 deletions
diff --git a/core/SCsub b/core/SCsub index a0176f6c33..7e9cd97351 100644 --- a/core/SCsub +++ b/core/SCsub @@ -65,7 +65,7 @@ thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_mis env_thirdparty.add_source_files(thirdparty_obj, thirdparty_misc_sources) # Brotli -if env["brotli"]: +if env["brotli"] and env["builtin_brotli"]: thirdparty_brotli_dir = "#thirdparty/brotli/" thirdparty_brotli_sources = [ "common/constants.c", diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index e547b04d0b..e37886cbe9 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -1192,7 +1192,7 @@ static const char *_joy_button_descriptions[(size_t)JoyButton::SDL_MAX] = { TTRC("Top Action, Sony Triangle, Xbox Y, Nintendo X"), TTRC("Back, Sony Select, Xbox Back, Nintendo -"), TTRC("Guide, Sony PS, Xbox Home"), - TTRC("Start, Nintendo +"), + TTRC("Start, Xbox Menu, Nintendo +"), TTRC("Left Stick, Sony L3, Xbox L/LS"), TTRC("Right Stick, Sony R3, Xbox R/RS"), TTRC("Left Shoulder, Sony L1, Xbox LB"), diff --git a/core/io/compression.cpp b/core/io/compression.cpp index ac4a637597..e36fb0afa4 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -35,13 +35,13 @@ #include "thirdparty/misc/fastlz.h" -#ifdef BROTLI_ENABLED -#include "thirdparty/brotli/include/brotli/decode.h" -#endif - #include <zlib.h> #include <zstd.h> +#ifdef BROTLI_ENABLED +#include <brotli/decode.h> +#endif + int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode) { switch (p_mode) { case MODE_BROTLI: { diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index 064353476f..c7f1a73f97 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -47,7 +47,7 @@ static void *godot_open(voidpf opaque, const char *p_fname, int mode) { return nullptr; } - Ref<FileAccess> f = FileAccess::open(p_fname, FileAccess::READ); + Ref<FileAccess> f = FileAccess::open(String::utf8(p_fname), FileAccess::READ); ERR_FAIL_COND_V(f.is_null(), nullptr); ZipData *zd = memnew(ZipData); diff --git a/core/io/json.cpp b/core/io/json.cpp index a6e054a9fe..496400a5ea 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -299,9 +299,15 @@ Error JSON::_get_token(const char32_t *p_str, int &index, int p_len, Token &r_to } } break; - default: { + case '"': + case '\\': + case '/': { res = next; } break; + default: { + r_err_str = "Invalid escape sequence."; + return ERR_PARSE_ERROR; + } } str += res; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 525c41cf87..1fe662b1fa 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -239,15 +239,15 @@ ResourceLoader::LoadToken::~LoadToken() { Ref<Resource> ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, ResourceFormatLoader::CacheMode p_cache_mode, Error *r_error, bool p_use_sub_threads, float *r_progress) { load_nesting++; - if (load_paths_stack.size()) { + if (load_paths_stack->size()) { thread_load_mutex.lock(); - HashMap<String, ThreadLoadTask>::Iterator E = thread_load_tasks.find(load_paths_stack[load_paths_stack.size() - 1]); + HashMap<String, ThreadLoadTask>::Iterator E = thread_load_tasks.find(load_paths_stack->get(load_paths_stack->size() - 1)); if (E) { E->value.sub_tasks.insert(p_path); } thread_load_mutex.unlock(); } - load_paths_stack.push_back(p_path); + load_paths_stack->push_back(p_path); // Try all loaders and pick the first match for the type hint bool found = false; @@ -263,7 +263,7 @@ Ref<Resource> ResourceLoader::_load(const String &p_path, const String &p_origin } } - load_paths_stack.resize(load_paths_stack.size() - 1); + load_paths_stack->resize(load_paths_stack->size() - 1); load_nesting--; if (!res.is_null()) { @@ -296,8 +296,10 @@ void ResourceLoader::_thread_load_function(void *p_userdata) { // Thread-safe either if it's the current thread or a brand new one. CallQueue *mq_override = nullptr; if (load_nesting == 0) { + load_paths_stack = memnew(Vector<String>); + if (!load_task.dependent_path.is_empty()) { - load_paths_stack.push_back(load_task.dependent_path); + load_paths_stack->push_back(load_task.dependent_path); } if (!Thread::is_main_thread()) { mq_override = memnew(CallQueue); @@ -309,6 +311,10 @@ void ResourceLoader::_thread_load_function(void *p_userdata) { } // -- + if (!Thread::is_main_thread()) { + set_current_thread_safe_for_nodes(true); + } + Ref<Resource> res = _load(load_task.remapped_path, load_task.remapped_path != load_task.local_path ? load_task.local_path : String(), load_task.type_hint, load_task.cache_mode, &load_task.error, load_task.use_sub_threads, &load_task.progress); if (mq_override) { mq_override->flush(); @@ -356,8 +362,11 @@ void ResourceLoader::_thread_load_function(void *p_userdata) { thread_load_mutex.unlock(); - if (load_nesting == 0 && mq_override) { - memdelete(mq_override); + if (load_nesting == 0) { + if (mq_override) { + memdelete(mq_override); + } + memdelete(load_paths_stack); } } @@ -1166,7 +1175,7 @@ bool ResourceLoader::timestamp_on_load = false; thread_local int ResourceLoader::load_nesting = 0; thread_local WorkerThreadPool::TaskID ResourceLoader::caller_task_id = 0; -thread_local Vector<String> ResourceLoader::load_paths_stack; +thread_local Vector<String> *ResourceLoader::load_paths_stack; template <> thread_local uint32_t SafeBinaryMutex<ResourceLoader::BINARY_MUTEX_TAG>::count = 0; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 592befb603..2701caa3f4 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -182,7 +182,7 @@ private: static thread_local int load_nesting; static thread_local WorkerThreadPool::TaskID caller_task_id; - static thread_local Vector<String> load_paths_stack; + static thread_local Vector<String> *load_paths_stack; // A pointer to avoid broken TLS implementations from double-running the destructor. static SafeBinaryMutex<BINARY_MUTEX_TAG> thread_load_mutex; static HashMap<String, ThreadLoadTask> thread_load_tasks; static bool cleaning_tasks; diff --git a/core/object/object.cpp b/core/object/object.cpp index c76188a2cd..4d19a2c75b 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -836,14 +836,16 @@ void Object::set_script(const Variant &p_script) { return; } + Ref<Script> s = p_script; + ERR_FAIL_COND_MSG(s.is_null() && !p_script.is_null(), "Invalid parameter, it should be a reference to a valid script (or null)."); + + script = p_script; + if (script_instance) { memdelete(script_instance); script_instance = nullptr; } - script = p_script; - Ref<Script> s = script; - if (!s.is_null()) { if (s->can_instantiate()) { OBJ_DEBUG_LOCK diff --git a/core/object/undo_redo.h b/core/object/undo_redo.h index 2ee17867f2..389d8714f7 100644 --- a/core/object/undo_redo.h +++ b/core/object/undo_redo.h @@ -58,7 +58,7 @@ private: TYPE_REFERENCE } type; - bool force_keep_in_merge_ends; + bool force_keep_in_merge_ends = false; Ref<RefCounted> ref; ObjectID object; StringName name; diff --git a/core/object/worker_thread_pool.cpp b/core/object/worker_thread_pool.cpp index d285be3e70..5ec3e1a1a8 100644 --- a/core/object/worker_thread_pool.cpp +++ b/core/object/worker_thread_pool.cpp @@ -56,6 +56,8 @@ void WorkerThreadPool::_process_task(Task *p_task) { Task *prev_low_prio_task = nullptr; // In case this is recursively called. if (!use_native_low_priority_threads) { + // Tasks must start with this unset. They are free to set-and-forget otherwise. + set_current_thread_safe_for_nodes(false); pool_thread_index = thread_ids[Thread::get_caller_id()]; ThreadData &curr_thread = threads[pool_thread_index]; task_mutex.lock(); @@ -179,9 +181,6 @@ void WorkerThreadPool::_process_task(Task *p_task) { if (post) { task_available_semaphore.post(); } - - // Engine/user tasks can set-and-forget, so we must be sure it's back to normal by the end of the task. - set_current_thread_safe_for_nodes(false); } } @@ -371,7 +370,9 @@ Error WorkerThreadPool::wait_for_task_completion(TaskID p_task_id) { must_exit = true; } else { // Solve tasks while they are around. + bool safe_for_nodes_backup = is_current_thread_safe_for_nodes(); _process_task_queue(); + set_current_thread_safe_for_nodes(safe_for_nodes_backup); continue; } } else if (!use_native_low_priority_threads && task->low_priority) { @@ -415,7 +416,7 @@ Error WorkerThreadPool::wait_for_task_completion(TaskID p_task_id) { WorkerThreadPool::GroupID WorkerThreadPool::_add_group_task(const Callable &p_callable, void (*p_func)(void *, uint32_t), void *p_userdata, BaseTemplateUserdata *p_template_userdata, int p_elements, int p_tasks, bool p_high_priority, const String &p_description) { ERR_FAIL_COND_V(p_elements < 0, INVALID_TASK_ID); if (p_tasks < 0) { - p_tasks = threads.size(); + p_tasks = MAX(1u, threads.size()); } task_mutex.lock(); diff --git a/core/os/os.cpp b/core/os/os.cpp index 5704ef7a40..67423128a3 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -295,12 +295,14 @@ Error OS::shell_open(String p_uri) { } Error OS::shell_show_in_file_manager(String p_path, bool p_open_folder) { - if (!p_path.begins_with("file://")) { - p_path = String("file://") + p_path; - } - if (!p_path.ends_with("/")) { + p_path = p_path.trim_prefix("file://"); + + if (!DirAccess::dir_exists_absolute(p_path)) { p_path = p_path.get_base_dir(); } + + p_path = String("file://") + p_path; + return shell_open(p_path); } // implement these with the canvas? diff --git a/core/os/threaded_array_processor.h b/core/os/threaded_array_processor.h deleted file mode 100644 index 34b417ae57..0000000000 --- a/core/os/threaded_array_processor.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************/ -/* threaded_array_processor.h */ -/**************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/**************************************************************************/ -/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/**************************************************************************/ - -#ifndef THREADED_ARRAY_PROCESSOR_H -#define THREADED_ARRAY_PROCESSOR_H - -#include "core/os/os.h" -#include "core/os/thread.h" -#include "core/os/thread_safe.h" -#include "core/templates/safe_refcount.h" - -template <class C, class U> -struct ThreadArrayProcessData { - uint32_t elements; - SafeNumeric<uint32_t> index; - C *instance; - U userdata; - void (C::*method)(uint32_t, U); - - void process(uint32_t p_index) { - (instance->*method)(p_index, userdata); - } -}; - -template <class T> -void process_array_thread(void *ud) { - T &data = *(T *)ud; - while (true) { - uint32_t index = data.index.increment(); - if (index >= data.elements) { - break; - } - data.process(index); - } -} - -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; - data.process(0); //process first, let threads increment for next - - int thread_count = OS::get_singleton()->get_processor_count(); - Thread *threads = memnew_arr(Thread, thread_count); - - for (int i = 0; i < thread_count; i++) { - threads[i].start(process_array_thread<ThreadArrayProcessData<C, U>>, &data); - } - - for (int i = 0; i < thread_count; i++) { - threads[i].wait_to_finish(); - } - memdelete_arr(threads); -} - -#endif // THREADED_ARRAY_PROCESSOR_H diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 49c7ead423..12e6423724 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -4281,12 +4281,13 @@ String String::pad_zeros(int p_digits) const { begin++; } - if (begin >= end) { + int zeros_to_add = p_digits - (end - begin); + + if (zeros_to_add <= 0) { return s; + } else { + return s.insert(begin, String("0").repeat(zeros_to_add)); } - - int zeros_to_add = p_digits - (end - begin); - return s.insert(begin, String("0").repeat(zeros_to_add)); } String String::trim_prefix(const String &p_prefix) const { diff --git a/core/variant/callable_bind.cpp b/core/variant/callable_bind.cpp index 378d1ff618..e493e50467 100644 --- a/core/variant/callable_bind.cpp +++ b/core/variant/callable_bind.cpp @@ -144,6 +144,18 @@ void CallableCustomBind::call(const Variant **p_arguments, int p_argcount, Varia callable.callp(args, p_argcount + binds.size(), r_return_value, r_call_error); } +Error CallableCustomBind::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const { + const Variant **args = (const Variant **)alloca(sizeof(const Variant **) * (binds.size() + p_argcount)); + for (int i = 0; i < p_argcount; i++) { + args[i] = (const Variant *)p_arguments[i]; + } + for (int i = 0; i < binds.size(); i++) { + args[i + p_argcount] = (const Variant *)&binds[i]; + } + + return callable.rpcp(p_peer_id, args, p_argcount + binds.size(), r_call_error); +} + CallableCustomBind::CallableCustomBind(const Callable &p_callable, const Vector<Variant> &p_binds) { callable = p_callable; binds = p_binds; @@ -242,6 +254,16 @@ void CallableCustomUnbind::call(const Variant **p_arguments, int p_argcount, Var callable.callp(p_arguments, p_argcount - argcount, r_return_value, r_call_error); } +Error CallableCustomUnbind::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const { + if (argcount > p_argcount) { + r_call_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_call_error.argument = 0; + r_call_error.expected = argcount; + return ERR_UNCONFIGURED; + } + return callable.rpcp(p_peer_id, p_arguments, p_argcount - argcount, r_call_error); +} + CallableCustomUnbind::CallableCustomUnbind(const Callable &p_callable, int p_argcount) { callable = p_callable; argcount = p_argcount; diff --git a/core/variant/callable_bind.h b/core/variant/callable_bind.h index b51076ad0f..5798797a3d 100644 --- a/core/variant/callable_bind.h +++ b/core/variant/callable_bind.h @@ -51,6 +51,7 @@ public: virtual StringName get_method() const override; virtual ObjectID get_object() const override; virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; + virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override; virtual const Callable *get_base_comparator() const override; virtual int get_bound_arguments_count() const override; virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override; @@ -78,6 +79,7 @@ public: virtual StringName get_method() const override; virtual ObjectID get_object() const override; virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const override; + virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const override; virtual const Callable *get_base_comparator() const override; virtual int get_bound_arguments_count() const override; virtual void get_bound_arguments(Vector<Variant> &r_arguments, int &r_argcount) const override; diff --git a/core/variant/native_ptr.h b/core/variant/native_ptr.h index ea811daabf..9199b12845 100644 --- a/core/variant/native_ptr.h +++ b/core/variant/native_ptr.h @@ -53,36 +53,46 @@ struct GDExtensionPtr { operator Variant() const { return uint64_t(data); } }; -#define GDVIRTUAL_NATIVE_PTR(m_type) \ - template <> \ - struct GDExtensionConstPtr<const m_type> { \ - const m_type *data = nullptr; \ - GDExtensionConstPtr() {} \ - GDExtensionConstPtr(const m_type *p_assign) { data = p_assign; } \ - static const char *get_name() { return "const " #m_type; } \ - operator const m_type *() const { return data; } \ - operator Variant() const { return uint64_t(data); } \ - }; \ - template <> \ - struct VariantCaster<GDExtensionConstPtr<const m_type>> { \ - static _FORCE_INLINE_ GDExtensionConstPtr<const m_type> cast(const Variant &p_variant) { \ - return GDExtensionConstPtr<const m_type>((const m_type *)p_variant.operator uint64_t()); \ - } \ - }; \ - template <> \ - struct GDExtensionPtr<m_type> { \ - m_type *data = nullptr; \ - GDExtensionPtr() {} \ - GDExtensionPtr(m_type *p_assign) { data = p_assign; } \ - static const char *get_name() { return #m_type; } \ - operator m_type *() const { return data; } \ - operator Variant() const { return uint64_t(data); } \ - }; \ - template <> \ - struct VariantCaster<GDExtensionPtr<m_type>> { \ - static _FORCE_INLINE_ GDExtensionPtr<m_type> cast(const Variant &p_variant) { \ - return GDExtensionPtr<m_type>((m_type *)p_variant.operator uint64_t()); \ - } \ +#define GDVIRTUAL_NATIVE_PTR(m_type) \ + template <> \ + struct GDExtensionConstPtr<const m_type> { \ + const m_type *data = nullptr; \ + GDExtensionConstPtr() {} \ + GDExtensionConstPtr(const m_type *p_assign) { data = p_assign; } \ + static const char *get_name() { return "const " #m_type; } \ + operator const m_type *() const { return data; } \ + operator Variant() const { return uint64_t(data); } \ + }; \ + template <> \ + struct VariantCaster<GDExtensionConstPtr<const m_type>> { \ + static _FORCE_INLINE_ GDExtensionConstPtr<const m_type> cast(const Variant &p_variant) { \ + return GDExtensionConstPtr<const m_type>((const m_type *)p_variant.operator uint64_t()); \ + } \ + }; \ + template <> \ + struct VariantInternalAccessor<GDExtensionConstPtr<const m_type>> { \ + static _FORCE_INLINE_ const GDExtensionConstPtr<const m_type> &get(const Variant *v) { return *reinterpret_cast<const GDExtensionConstPtr<const m_type> *>(VariantInternal::get_int(v)); } \ + static _FORCE_INLINE_ void set(Variant *v, const GDExtensionConstPtr<const m_type> &p_value) { *VariantInternal::get_int(v) = uint64_t(p_value.data); } \ + }; \ + template <> \ + struct GDExtensionPtr<m_type> { \ + m_type *data = nullptr; \ + GDExtensionPtr() {} \ + GDExtensionPtr(m_type *p_assign) { data = p_assign; } \ + static const char *get_name() { return #m_type; } \ + operator m_type *() const { return data; } \ + operator Variant() const { return uint64_t(data); } \ + }; \ + template <> \ + struct VariantCaster<GDExtensionPtr<m_type>> { \ + static _FORCE_INLINE_ GDExtensionPtr<m_type> cast(const Variant &p_variant) { \ + return GDExtensionPtr<m_type>((m_type *)p_variant.operator uint64_t()); \ + } \ + }; \ + template <> \ + struct VariantInternalAccessor<GDExtensionPtr<m_type>> { \ + static _FORCE_INLINE_ const GDExtensionPtr<m_type> &get(const Variant *v) { return *reinterpret_cast<const GDExtensionPtr<m_type> *>(VariantInternal::get_int(v)); } \ + static _FORCE_INLINE_ void set(Variant *v, const GDExtensionPtr<m_type> &p_value) { *VariantInternal::get_int(v) = uint64_t(p_value.data); } \ }; template <class T> |