diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/config/engine.cpp | 12 | ||||
-rw-r--r-- | core/config/engine.h | 6 | ||||
-rw-r--r-- | core/core_bind.cpp | 12 | ||||
-rw-r--r-- | core/core_bind.h | 1 | ||||
-rw-r--r-- | core/extension/gdextension.cpp | 60 | ||||
-rw-r--r-- | core/extension/gdextension.h | 8 | ||||
-rw-r--r-- | core/io/resource.cpp | 5 | ||||
-rw-r--r-- | core/io/resource.h | 2 | ||||
-rw-r--r-- | core/string/ustring.cpp | 17 | ||||
-rw-r--r-- | core/string/ustring.h | 1 | ||||
-rw-r--r-- | core/variant/variant.cpp | 18 | ||||
-rw-r--r-- | core/variant/variant_call.cpp | 1 |
12 files changed, 126 insertions, 17 deletions
diff --git a/core/config/engine.cpp b/core/config/engine.cpp index 7fdea7d1aa..17d3bdb744 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -74,6 +74,14 @@ int Engine::get_max_fps() const { return _max_fps; } +void Engine::set_audio_output_latency(int p_msec) { + _audio_output_latency = p_msec > 1 ? p_msec : 1; +} + +int Engine::get_audio_output_latency() const { + return _audio_output_latency; +} + uint64_t Engine::get_frames_drawn() { return frames_drawn; } @@ -239,6 +247,10 @@ bool Engine::is_validation_layers_enabled() const { return use_validation_layers; } +bool Engine::is_generate_spirv_debug_info_enabled() const { + return generate_spirv_debug_info; +} + void Engine::set_print_error_messages(bool p_enabled) { CoreGlobals::print_error_enabled = p_enabled; } diff --git a/core/config/engine.h b/core/config/engine.h index 5ea653ba6c..ff88fbc787 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -61,12 +61,14 @@ private: double physics_jitter_fix = 0.5; double _fps = 1; int _max_fps = 0; + int _audio_output_latency = 0; double _time_scale = 1.0; uint64_t _physics_frames = 0; int max_physics_steps_per_frame = 8; double _physics_interpolation_fraction = 0.0f; bool abort_on_gpu_errors = false; bool use_validation_layers = false; + bool generate_spirv_debug_info = false; int32_t gpu_idx = -1; uint64_t _process_frames = 0; @@ -98,6 +100,9 @@ public: virtual void set_max_fps(int p_fps); virtual int get_max_fps() const; + virtual void set_audio_output_latency(int p_msec); + virtual int get_audio_output_latency() const; + virtual double get_frames_per_second() const { return _fps; } uint64_t get_frames_drawn(); @@ -156,6 +161,7 @@ public: bool is_abort_on_gpu_errors_enabled() const; bool is_validation_layers_enabled() const; + bool is_generate_spirv_debug_info_enabled() const; int32_t get_gpu_index() const; Engine(); diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 4e220d0839..05fe393a2f 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -929,6 +929,17 @@ Geometry3D *Geometry3D::get_singleton() { return singleton; } +Vector<Vector3> Geometry3D::compute_convex_mesh_points(const TypedArray<Plane> &p_planes) { + Vector<Plane> planes_vec; + int size = p_planes.size(); + planes_vec.resize(size); + for (int i = 0; i < size; ++i) { + planes_vec.set(i, p_planes[i]); + } + Variant ret = ::Geometry3D::compute_convex_mesh_points(planes_vec.ptr(), size); + return ret; +} + TypedArray<Plane> Geometry3D::build_box_planes(const Vector3 &p_extents) { Variant ret = ::Geometry3D::build_box_planes(p_extents); return ret; @@ -1029,6 +1040,7 @@ Vector<Vector3> Geometry3D::clip_polygon(const Vector<Vector3> &p_points, const } void Geometry3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("compute_convex_mesh_points", "planes"), &Geometry3D::compute_convex_mesh_points); ClassDB::bind_method(D_METHOD("build_box_planes", "extents"), &Geometry3D::build_box_planes); ClassDB::bind_method(D_METHOD("build_cylinder_planes", "radius", "height", "sides", "axis"), &Geometry3D::build_cylinder_planes, DEFVAL(Vector3::AXIS_Z)); ClassDB::bind_method(D_METHOD("build_capsule_planes", "radius", "height", "sides", "lats", "axis"), &Geometry3D::build_capsule_planes, DEFVAL(Vector3::AXIS_Z)); diff --git a/core/core_bind.h b/core/core_bind.h index 1cbbcdd251..5f51b64eb7 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -320,6 +320,7 @@ protected: public: static Geometry3D *get_singleton(); + Vector<Vector3> compute_convex_mesh_points(const TypedArray<Plane> &p_planes); TypedArray<Plane> build_box_planes(const Vector3 &p_extents); TypedArray<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z); TypedArray<Plane> build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis = Vector3::AXIS_Z); diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 67b55db3db..e39a531d0d 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -485,6 +485,13 @@ void GDExtension::close_library() { ERR_FAIL_COND(library == nullptr); OS::get_singleton()->close_dynamic_library(library); +#if defined(TOOLS_ENABLED) && defined(WINDOWS_ENABLED) + // Delete temporary copy of library if it exists. + if (!temp_lib_path.is_empty() && Engine::get_singleton()->is_editor_hint()) { + DirAccess::remove_absolute(temp_lib_path); + } +#endif + library = nullptr; } @@ -607,12 +614,13 @@ Ref<Resource> GDExtensionResourceLoader::load(const String &p_path, const String } bool compatible = true; - if (VERSION_MAJOR < compatibility_minimum[0]) { - compatible = false; - } else if (VERSION_MINOR < compatibility_minimum[1]) { - compatible = false; - } else if (VERSION_PATCH < compatibility_minimum[2]) { - compatible = false; + // Check version lexicographically. + if (VERSION_MAJOR != compatibility_minimum[0]) { + compatible = VERSION_MAJOR > compatibility_minimum[0]; + } else if (VERSION_MINOR != compatibility_minimum[1]) { + compatible = VERSION_MINOR > compatibility_minimum[1]; + } else { + compatible = VERSION_PATCH >= compatibility_minimum[2]; } if (!compatible) { if (r_error) { @@ -640,6 +648,40 @@ Ref<Resource> GDExtensionResourceLoader::load(const String &p_path, const String Ref<GDExtension> lib; lib.instantiate(); String abs_path = ProjectSettings::get_singleton()->globalize_path(library_path); + +#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED) + // If running on the editor on Windows, we copy the library and open the copy. + // This is so the original file isn't locked and can be updated by a compiler. + if (Engine::get_singleton()->is_editor_hint()) { + if (!FileAccess::exists(abs_path)) { + if (r_error) { + *r_error = ERR_FILE_NOT_FOUND; + } + ERR_PRINT("GDExtension library not found: " + library_path); + return Ref<Resource>(); + } + + // Copy the file to the same directory as the original with a prefix in the name. + // This is so relative path to dependencies are satisfied. + String copy_path = abs_path.get_base_dir().path_join("~" + abs_path.get_file()); + + Error copy_err = DirAccess::copy_absolute(abs_path, copy_path); + if (copy_err) { + if (r_error) { + *r_error = ERR_CANT_CREATE; + } + ERR_PRINT("Error copying GDExtension library: " + library_path); + return Ref<Resource>(); + } + FileAccess::set_hidden_attribute(copy_path, true); + + // Save the copied path so it can be deleted later. + lib->set_temp_library_path(copy_path); + + // Use the copy to open the library. + abs_path = copy_path; + } +#endif err = lib->open_library(abs_path, entry_symbol); if (r_error) { @@ -647,6 +689,12 @@ Ref<Resource> GDExtensionResourceLoader::load(const String &p_path, const String } if (err != OK) { +#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED) + // If the DLL fails to load, make sure that temporary DLL copies are cleaned up. + if (Engine::get_singleton()->is_editor_hint()) { + DirAccess::remove_absolute(lib->get_temp_library_path()); + } +#endif // Errors already logged in open_library() return Ref<Resource>(); } diff --git a/core/extension/gdextension.h b/core/extension/gdextension.h index b935f8706f..5a0e39302b 100644 --- a/core/extension/gdextension.h +++ b/core/extension/gdextension.h @@ -43,6 +43,9 @@ class GDExtension : public Resource { void *library = nullptr; // pointer if valid, String library_path; +#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED) + String temp_lib_path; +#endif struct Extension { ObjectGDExtension gdextension; @@ -76,6 +79,11 @@ public: Error open_library(const String &p_path, const String &p_entry_symbol); void close_library(); +#if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED) + void set_temp_library_path(const String &p_path) { temp_lib_path = p_path; } + String get_temp_library_path() const { return temp_lib_path; } +#endif + enum InitializationLevel { INITIALIZATION_LEVEL_CORE = GDEXTENSION_INITIALIZATION_CORE, INITIALIZATION_LEVEL_SERVERS = GDEXTENSION_INITIALIZATION_SERVERS, diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 07677337b4..68cdeabac7 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -239,6 +239,7 @@ void Resource::configure_for_local_scene(Node *p_for_scene, HashMap<Ref<Resource List<PropertyInfo> plist; get_property_list(&plist); + reset_local_to_scene(); local_scene = p_for_scene; for (const PropertyInfo &E : plist) { @@ -382,6 +383,10 @@ void Resource::setup_local_to_scene() { emit_signal(SNAME("setup_local_to_scene_requested")); } +void Resource::reset_local_to_scene() { + // Restores the state as if setup_local_to_scene() hadn't been called. +} + Node *(*Resource::_get_local_scene_func)() = nullptr; void (*Resource::_update_configuration_warning)() = nullptr; diff --git a/core/io/resource.h b/core/io/resource.h index af8c275a1c..f848bdba99 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -80,6 +80,8 @@ protected: void _set_path(const String &p_path); void _take_over_path(const String &p_path); + virtual void reset_local_to_scene(); + public: static Node *(*_get_local_scene_func)(); //used by editor static void (*_update_configuration_warning)(); //used by editor diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 376d0832d4..80ca51573c 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -3635,6 +3635,23 @@ String String::repeat(int p_count) const { return new_string; } +String String::reverse() const { + int len = length(); + if (len <= 1) { + return *this; + } + String new_string; + new_string.resize(len + 1); + + const char32_t *src = ptr(); + char32_t *dst = new_string.ptrw(); + for (int i = 0; i < len; i++) { + dst[i] = src[len - i - 1]; + } + dst[len] = _null; + return new_string; +} + String String::left(int p_len) const { if (p_len < 0) { p_len = length() + p_len; diff --git a/core/string/ustring.h b/core/string/ustring.h index 295625395d..f45392eee1 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -305,6 +305,7 @@ public: String replace(const char *p_key, const char *p_with) const; String replacen(const String &p_key, const String &p_with) const; String repeat(int p_count) const; + String reverse() const; String insert(int p_at_pos, const String &p_string) const; String erase(int p_pos, int p_chars = 1) const; String pad_decimals(int p_digits) const; diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 10a267e5a9..8a0289898d 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -1754,11 +1754,10 @@ String Variant::stringify(int recursion_count) const { case COLOR: return operator Color(); case DICTIONARY: { + ERR_FAIL_COND_V_MSG(recursion_count > MAX_RECURSION, "{ ... }", "Maximum dictionary recursion reached!"); + recursion_count++; + const Dictionary &d = *reinterpret_cast<const Dictionary *>(_data._mem); - if (recursion_count > MAX_RECURSION) { - ERR_PRINT("Maximum dictionary recursion reached!"); - return "{ ... }"; - } // Add leading and trailing space to Dictionary printing. This distinguishes it // from array printing on fonts that have similar-looking {} and [] characters. @@ -1768,7 +1767,6 @@ String Variant::stringify(int recursion_count) const { Vector<_VariantStrPair> pairs; - recursion_count++; for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { _VariantStrPair sp; sp.key = stringify_variant_clean(E->get(), recursion_count); @@ -1787,6 +1785,7 @@ String Variant::stringify(int recursion_count) const { return str; } + // Packed arrays cannot contain recursive structures, the recursion_count increment is not needed. case PACKED_VECTOR2_ARRAY: { return stringify_vector(operator Vector<Vector2>(), recursion_count); } @@ -1815,13 +1814,10 @@ String Variant::stringify(int recursion_count) const { return stringify_vector(operator Vector<double>(), recursion_count); } case ARRAY: { - Array arr = operator Array(); - if (recursion_count > MAX_RECURSION) { - ERR_PRINT("Maximum array recursion reached!"); - return "[...]"; - } + ERR_FAIL_COND_V_MSG(recursion_count > MAX_RECURSION, "[...]", "Maximum array recursion reached!"); + recursion_count++; - return stringify_vector(arr, recursion_count); + return stringify_vector(operator Array(), recursion_count); } case OBJECT: { if (_get_obj().obj) { diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index dad9183216..ccf9b82022 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1659,6 +1659,7 @@ static void _register_variant_builtin_methods() { bind_string_methodv(replace, static_cast<String (String::*)(const String &, const String &) const>(&String::replace), sarray("what", "forwhat"), varray()); bind_string_method(replacen, sarray("what", "forwhat"), varray()); bind_string_method(repeat, sarray("count"), varray()); + bind_string_method(reverse, sarray(), varray()); bind_string_method(insert, sarray("position", "what"), varray()); bind_string_method(erase, sarray("position", "chars"), varray(1)); bind_string_method(capitalize, sarray(), varray()); |