diff options
89 files changed, 3898 insertions, 345 deletions
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index fe046863fc..03415b4c39 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -328,6 +328,11 @@ Comment: meshoptimizer Copyright: 2016-2022, Arseny Kapoulkine License: Expat +Files: ./thirdparty/mingw-std-threads/ +Comment: mingw-std-threads +Copyright: 2016, Mega Limited +License: BSD-2-clause + Files: ./thirdparty/minimp3/ Comment: MiniMP3 Copyright: lieff @@ -19,6 +19,7 @@ generous deed immortalized in the next stable release of Godot Engine. Heroic Labs <https://heroiclabs.com> Ramatak <https://ramatak.com> + V-Sekai <https://github.com/V-Sekai> W4 Games <https://w4games.com> ## Gold sponsors @@ -40,8 +41,9 @@ generous deed immortalized in the next stable release of Godot Engine. ## Diamond members + Sealow Sylv <https://rankith.itch.io/unnamed-space-idle-prototype> - And 4 anonymous donors + And 5 anonymous donors ## Titanium members @@ -63,7 +65,7 @@ generous deed immortalized in the next stable release of Godot Engine. Sunshower <https://github.com/Phanterm> TrampolineTales <https://trampolinetales.com/> Wilfred James <https://twitter.com/0430agi> - And 7 anonymous donors + And 8 anonymous donors ## Platinum members @@ -74,6 +76,7 @@ generous deed immortalized in the next stable release of Godot Engine. Christoph Woinke Christopher Shifflett Darrin Massena + Druvsaft Edward Flick F*ckedByUnity Golden Skull Art @@ -82,6 +85,7 @@ generous deed immortalized in the next stable release of Godot Engine. Justin McGettigan Justo Delgado Baudí Marek Belski + Matthew Ekenstedt Mike King Nassor Paulino da Silva Neal Gompa (Conan Kudo) @@ -99,11 +103,12 @@ generous deed immortalized in the next stable release of Godot Engine. Vladimír Chvátil iCommitGames nate-wilkins - And 16 anonymous donors + And 18 anonymous donors ## Gold members @reilaos + Antti Vesanen Artur Ilkaev Asher Glick Ashtreighlia @@ -116,8 +121,10 @@ generous deed immortalized in the next stable release of Godot Engine. Bernd Barsuhn Blake Farnsworth Brian Ernst + Brian Levinsen Brut Chen-Pang He (jdh8) + ClarkThyLord Cosmin Munteanu Coy Humphrey Daniel James @@ -130,6 +137,7 @@ generous deed immortalized in the next stable release of Godot Engine. Ed Morley ElektroFox Enclusa Games + Ends Eric Phy Faisal Al-Kubaisi (QatariGameDev) FeralBytes @@ -137,8 +145,12 @@ generous deed immortalized in the next stable release of Godot Engine. GlassBrick Grau Guangzhou Lingchan + HTML5onMobilePLZ Hammster + Hendrik Mans + Here's my 20 cents Iggy Zuk + Illyan Jacob (HACKhalo2 Studios) Jam James Green @@ -162,6 +174,7 @@ generous deed immortalized in the next stable release of Godot Engine. MHDante Malcolm Nixon Manuel Requena + Mark Schramm Martin Agnar Dahl Martin Šenkeřík Matheus Gritz @@ -190,6 +203,7 @@ generous deed immortalized in the next stable release of Godot Engine. ThePolyglotProgrammer Tim Nedvyga Tom Langwaldt + Trevor Slocum Vincent Foulon Weasel Games WuotanStudios.com @@ -197,10 +211,13 @@ generous deed immortalized in the next stable release of Godot Engine. albinaask endaye getIntoGameDev + hiulit + korinVR nezticle ohanaya3 re:thinc tukon + zikes 杨烈胜(zedrun) Alexander Erlemann @@ -589,7 +606,7 @@ generous deed immortalized in the next stable release of Godot Engine. ケルベロス 貴宏 小松 - And 194 anonymous donors + And 241 anonymous donors ## Silver and bronze donors diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp index 1071df0979..e1d49dacc0 100644 --- a/core/math/aabb.cpp +++ b/core/math/aabb.cpp @@ -117,6 +117,11 @@ AABB AABB::intersection(const AABB &p_aabb) const { return AABB(min, max - min); } +#ifdef MINGW_ENABLED +#undef near +#undef far +#endif + bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const { #ifdef MATH_CHECKS if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) { diff --git a/core/object/object.h b/core/object/object.h index 7b53fcaa41..fdd1c0b267 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -656,7 +656,7 @@ private: friend class RefCounted; bool type_is_reference = false; - std::mutex _instance_binding_mutex; + BinaryMutex _instance_binding_mutex; struct InstanceBinding { void *binding = nullptr; void *token = nullptr; diff --git a/core/os/condition_variable.h b/core/os/condition_variable.h index 6037ff327d..6a6996019d 100644 --- a/core/os/condition_variable.h +++ b/core/os/condition_variable.h @@ -31,7 +31,14 @@ #ifndef CONDITION_VARIABLE_H #define CONDITION_VARIABLE_H +#ifdef MINGW_ENABLED +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#include "thirdparty/mingw-std-threads/mingw.condition_variable.h" +#define THREADING_NAMESPACE mingw_stdthread +#else #include <condition_variable> +#define THREADING_NAMESPACE std +#endif // An object one or multiple threads can wait on a be notified by some other. // Normally, you want to use a semaphore for such scenarios, but when the @@ -40,12 +47,12 @@ // own mutex to tie the wait-notify to some other behavior, you need to use this. class ConditionVariable { - mutable std::condition_variable condition; + mutable THREADING_NAMESPACE::condition_variable condition; public: template <class BinaryMutexT> _ALWAYS_INLINE_ void wait(const MutexLock<BinaryMutexT> &p_lock) const { - condition.wait(const_cast<std::unique_lock<std::mutex> &>(p_lock.lock)); + condition.wait(const_cast<THREADING_NAMESPACE::unique_lock<THREADING_NAMESPACE::mutex> &>(p_lock.lock)); } _ALWAYS_INLINE_ void notify_one() const { diff --git a/core/os/mutex.cpp b/core/os/mutex.cpp index 7dbb60590b..5d4e457c5f 100644 --- a/core/os/mutex.cpp +++ b/core/os/mutex.cpp @@ -40,7 +40,7 @@ void _global_unlock() { _global_mutex.unlock(); } -template class MutexImpl<std::recursive_mutex>; -template class MutexImpl<std::mutex>; -template class MutexLock<MutexImpl<std::recursive_mutex>>; -template class MutexLock<MutexImpl<std::mutex>>; +template class MutexImpl<THREADING_NAMESPACE::recursive_mutex>; +template class MutexImpl<THREADING_NAMESPACE::mutex>; +template class MutexLock<MutexImpl<THREADING_NAMESPACE::recursive_mutex>>; +template class MutexLock<MutexImpl<THREADING_NAMESPACE::mutex>>; diff --git a/core/os/mutex.h b/core/os/mutex.h index cee0f8af74..03af48ca7c 100644 --- a/core/os/mutex.h +++ b/core/os/mutex.h @@ -34,7 +34,14 @@ #include "core/error/error_macros.h" #include "core/typedefs.h" +#ifdef MINGW_ENABLED +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#include "thirdparty/mingw-std-threads/mingw.mutex.h" +#define THREADING_NAMESPACE mingw_stdthread +#else #include <mutex> +#define THREADING_NAMESPACE std +#endif template <class MutexT> class MutexLock; @@ -73,9 +80,9 @@ template <int Tag> class SafeBinaryMutex { friend class MutexLock<SafeBinaryMutex>; - using StdMutexType = std::mutex; + using StdMutexType = THREADING_NAMESPACE::mutex; - mutable std::mutex mutex; + mutable THREADING_NAMESPACE::mutex mutex; static thread_local uint32_t count; public: @@ -115,7 +122,7 @@ template <class MutexT> class MutexLock { friend class ConditionVariable; - std::unique_lock<typename MutexT::StdMutexType> lock; + THREADING_NAMESPACE::unique_lock<typename MutexT::StdMutexType> lock; public: _ALWAYS_INLINE_ explicit MutexLock(const MutexT &p_mutex) : @@ -128,7 +135,7 @@ template <int Tag> class MutexLock<SafeBinaryMutex<Tag>> { friend class ConditionVariable; - std::unique_lock<std::mutex> lock; + THREADING_NAMESPACE::unique_lock<THREADING_NAMESPACE::mutex> lock; public: _ALWAYS_INLINE_ explicit MutexLock(const SafeBinaryMutex<Tag> &p_mutex) : @@ -140,12 +147,12 @@ public: }; }; -using Mutex = MutexImpl<std::recursive_mutex>; // Recursive, for general use -using BinaryMutex = MutexImpl<std::mutex>; // Non-recursive, handle with care +using Mutex = MutexImpl<THREADING_NAMESPACE::recursive_mutex>; // Recursive, for general use +using BinaryMutex = MutexImpl<THREADING_NAMESPACE::mutex>; // Non-recursive, handle with care -extern template class MutexImpl<std::recursive_mutex>; -extern template class MutexImpl<std::mutex>; -extern template class MutexLock<MutexImpl<std::recursive_mutex>>; -extern template class MutexLock<MutexImpl<std::mutex>>; +extern template class MutexImpl<THREADING_NAMESPACE::recursive_mutex>; +extern template class MutexImpl<THREADING_NAMESPACE::mutex>; +extern template class MutexLock<MutexImpl<THREADING_NAMESPACE::recursive_mutex>>; +extern template class MutexLock<MutexImpl<THREADING_NAMESPACE::mutex>>; #endif // MUTEX_H diff --git a/core/os/os.cpp b/core/os/os.cpp index c7390f14ff..f5d55ca107 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -39,7 +39,15 @@ #include "core/version_generated.gen.h" #include <stdarg.h> + +#ifdef MINGW_ENABLED +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#include "thirdparty/mingw-std-threads/mingw.thread.h" +#define THREADING_NAMESPACE mingw_stdthread +#else #include <thread> +#define THREADING_NAMESPACE std +#endif OS *OS::singleton = nullptr; uint64_t OS::target_ticks = 0; @@ -359,7 +367,7 @@ String OS::get_unique_id() const { } int OS::get_processor_count() const { - return std::thread::hardware_concurrency(); + return THREADING_NAMESPACE::thread::hardware_concurrency(); } String OS::get_processor_name() const { diff --git a/core/os/rw_lock.h b/core/os/rw_lock.h index a232fcb1ce..e5bb6aec2b 100644 --- a/core/os/rw_lock.h +++ b/core/os/rw_lock.h @@ -33,10 +33,17 @@ #include "core/typedefs.h" +#ifdef MINGW_ENABLED +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#include "thirdparty/mingw-std-threads/mingw.shared_mutex.h" +#define THREADING_NAMESPACE mingw_stdthread +#else #include <shared_mutex> +#define THREADING_NAMESPACE std +#endif class RWLock { - mutable std::shared_timed_mutex mutex; + mutable THREADING_NAMESPACE::shared_timed_mutex mutex; public: // Lock the RWLock, block if locked by someone else. diff --git a/core/os/semaphore.h b/core/os/semaphore.h index 66dfb3ee02..8bb1529bbd 100644 --- a/core/os/semaphore.h +++ b/core/os/semaphore.h @@ -37,13 +37,21 @@ #include "core/error/error_macros.h" #endif +#ifdef MINGW_ENABLED +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#include "thirdparty/mingw-std-threads/mingw.condition_variable.h" +#include "thirdparty/mingw-std-threads/mingw.mutex.h" +#define THREADING_NAMESPACE mingw_stdthread +#else #include <condition_variable> #include <mutex> +#define THREADING_NAMESPACE std +#endif class Semaphore { private: - mutable std::mutex mutex; - mutable std::condition_variable condition; + mutable THREADING_NAMESPACE::mutex mutex; + mutable THREADING_NAMESPACE::condition_variable condition; mutable uint32_t count = 0; // Initialized as locked. #ifdef DEBUG_ENABLED mutable uint32_t awaiters = 0; @@ -57,7 +65,7 @@ public: } _ALWAYS_INLINE_ void wait() const { - std::unique_lock lock(mutex); + THREADING_NAMESPACE::unique_lock lock(mutex); #ifdef DEBUG_ENABLED ++awaiters; #endif @@ -116,7 +124,7 @@ public: "A Semaphore object is being destroyed while one or more threads are still waiting on it.\n" "Please call post() on it as necessary to prevent such a situation and so ensure correct cleanup."); // And now, the hacky countermeasure (i.e., leak the condition variable). - new (&condition) std::condition_variable(); + new (&condition) THREADING_NAMESPACE::condition_variable(); } } #endif diff --git a/core/os/thread.cpp b/core/os/thread.cpp index 03e2c5409d..2ba90ba42c 100644 --- a/core/os/thread.cpp +++ b/core/os/thread.cpp @@ -69,8 +69,7 @@ void Thread::callback(ID p_caller_id, const Settings &p_settings, Callback p_cal Thread::ID Thread::start(Thread::Callback p_callback, void *p_user, const Settings &p_settings) { ERR_FAIL_COND_V_MSG(id != UNASSIGNED_ID, UNASSIGNED_ID, "A Thread object has been re-started without wait_to_finish() having been called on it."); id = id_counter.increment(); - std::thread new_thread(&Thread::callback, id, p_settings, p_callback, p_user); - thread.swap(new_thread); + thread = THREADING_NAMESPACE::thread(&Thread::callback, id, p_settings, p_callback, p_user); return id; } @@ -82,8 +81,7 @@ void Thread::wait_to_finish() { ERR_FAIL_COND_MSG(id == UNASSIGNED_ID, "Attempt of waiting to finish on a thread that was never started."); ERR_FAIL_COND_MSG(id == get_caller_id(), "Threads can't wait to finish on themselves, another thread must wait."); thread.join(); - std::thread empty_thread; - thread.swap(empty_thread); + thread = THREADING_NAMESPACE::thread(); id = UNASSIGNED_ID; } diff --git a/core/os/thread.h b/core/os/thread.h index 3e307adfff..cc954678f9 100644 --- a/core/os/thread.h +++ b/core/os/thread.h @@ -42,7 +42,14 @@ #include "core/templates/safe_refcount.h" #include "core/typedefs.h" +#ifdef MINGW_ENABLED +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#include "thirdparty/mingw-std-threads/mingw.thread.h" +#define THREADING_NAMESPACE mingw_stdthread +#else #include <thread> +#define THREADING_NAMESPACE std +#endif class String; @@ -82,7 +89,7 @@ private: ID id = UNASSIGNED_ID; static SafeNumeric<uint64_t> id_counter; static thread_local ID caller_id; - std::thread thread; + THREADING_NAMESPACE::thread thread; static void callback(ID p_caller_id, const Settings &p_settings, Thread::Callback p_callback, void *p_userdata); diff --git a/doc/Makefile b/doc/Makefile index 53c5c7dcb0..722746f366 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -4,7 +4,7 @@ OUTPUTDIR = $(BASEDIR)/_build TOOLSDIR = $(BASEDIR)/tools JSDIR = "$(BASEDIR)/../platform/web" LANGARG ?= en -LANGCMD = -l $(LANGARG) +TOOLSOPT ?= .ONESHELL: @@ -19,7 +19,10 @@ doxygen: rst: rm -rf "$(OUTPUTDIR)/rst" mkdir -p "$(OUTPUTDIR)/rst" - python3 "$(TOOLSDIR)/make_rst.py" -o "$(OUTPUTDIR)/rst" "$(LANGCMD)" $(CLASSES) + python3 "$(TOOLSDIR)/make_rst.py" -o "$(OUTPUTDIR)/rst" -l "$(LANGARG)" $(TOOLSOPT) $(CLASSES) + +xml-check: + python3 "$(TOOLSDIR)/make_rst.py" --dry-run -l "$(LANGARG)" $(TOOLSOPT) $(CLASSES) rstjs: rm -rf "$(OUTPUTDIR)/rstjs" diff --git a/doc/translations/de.po b/doc/translations/de.po index 7c859e57b5..9d98c37510 100644 --- a/doc/translations/de.po +++ b/doc/translations/de.po @@ -80,8 +80,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2023-11-15 10:06+0000\n" -"Last-Translator: HugeGameArt <hugegameartgd@gmail.com>\n" +"PO-Revision-Date: 2023-11-20 14:00+0000\n" +"Last-Translator: Tobias Mohr <tobias_mohr_1991@gmx.de>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/godot-" "class-reference/de/>\n" "Language: de\n" @@ -89,7 +89,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.2-dev\n" +"X-Generator: Weblate 5.2\n" msgid "Description" msgstr "Beschreibung" @@ -3839,6 +3839,33 @@ msgstr "" "Siehe auch: [method typeof]." msgid "" +"Returns the internal type of the given [param variable], using the [enum " +"Variant.Type] values.\n" +"[codeblock]\n" +"var json = JSON.new()\n" +"json.parse('[\"a\", \"b\", \"c\"]')\n" +"var result = json.get_data()\n" +"if typeof(result) == TYPE_ARRAY:\n" +" print(result[0]) # Prints a\n" +"else:\n" +" print(\"Unexpected result\")\n" +"[/codeblock]\n" +"See also [method type_string]." +msgstr "" +"Gibt den internen Typ der angegebenen [param variable] zurück, unter " +"Verwendung der [enum Variant.Type]-Werte.\n" +"[codeblock]\n" +"var json = JSON.new()\n" +"json.parse('[\"a\", \"b\", \"c\"]')\n" +"var result = json.get_data()\n" +"if typeof(result) == TYPE_ARRAY:\n" +" print(result[0]) # Prints a\n" +"else:\n" +" print(\"Unexpected result\")\n" +"[/codeblock]\n" +"Siehe auch [method type_string]." + +msgid "" "Encodes a [Variant] value to a byte array, without encoding objects. " "Deserialization can be done with [method bytes_to_var].\n" "[b]Note:[/b] If you need object serialization, see [method " @@ -6513,16 +6540,15 @@ msgid "" "[code]transform.affine_inverse() * aabb[/code] can be used instead. See " "[method Transform3D.affine_inverse]." msgstr "" -"Invertiert die (multipliziert im mathematischen Sinn) die gegebene Matrix " -"[AABB] mit der gegebenen [Transform3D] Transformationsmatrix, unter der " -"Annahme dass die Transformationsbasis orthogonal zur gegebenen Matrix " -"steht(also ist Rotation/Reflektion normal, aber Skalierung nicht).\n" -"[code]aabb * transform[/code] is equivalent to [code]transform.inverse() * " -"aabb[/code]. \n" -"Siehe auch [method Transform3D.inverse] um mit der Inversen einer affinen " -"Transformation zu invertieren.\n" -"[code]transform.affine_inverse() * aabb[/code] kann auch verwendet werden. \n" -"Siehe [methodTransform3D.affine_inverse]." +"Transformiert (multipliziert) die [AABB] invers mit der gegebenen " +"[Transform3D]-Transformationsmatrix, unter der Annahme, dass die " +"Transformationsbasis orthonormal ist (d. h. Drehung/Reflexion ist in Ordnung, " +"Skalierung/Skew nicht).\n" +"[code]aabb * transform[/code] ist äquivalent zu [code]transform.inverse() * " +"aabb[/code]. Siehe [Methode Transform3D.inverse].\n" +"Für die Transformation durch die Inverse einer affinen Transformation (z.B. " +"mit Skalierung) kann stattdessen [code]transform.affine_inverse() * aabb[/" +"code] verwendet werden. Siehe [Methode Transform3D.affine_inverse]." msgid "" "Returns [code]true[/code] if the AABBs are exactly equal.\n" @@ -13956,6 +13982,147 @@ msgid "An audio stream with utilities for procedural sound generation." msgstr "Ein Audiostrom mit Hilfsprogrammen für die prozedurale Klangerzeugung." msgid "" +"[AudioStreamGenerator] is a type of audio stream that does not play back " +"sounds on its own; instead, it expects a script to generate audio data for " +"it. See also [AudioStreamGeneratorPlayback].\n" +"Here's a sample on how to use it to generate a sine wave:\n" +"[codeblocks]\n" +"[gdscript]\n" +"var playback # Will hold the AudioStreamGeneratorPlayback.\n" +"@onready var sample_hz = $AudioStreamPlayer.stream.mix_rate\n" +"var pulse_hz = 440.0 # The frequency of the sound wave.\n" +"\n" +"func _ready():\n" +" $AudioStreamPlayer.play()\n" +" playback = $AudioStreamPlayer.get_stream_playback()\n" +" fill_buffer()\n" +"\n" +"func fill_buffer():\n" +" var phase = 0.0\n" +" var increment = pulse_hz / sample_hz\n" +" var frames_available = playback.get_frames_available()\n" +"\n" +" for i in range(frames_available):\n" +" playback.push_frame(Vector2.ONE * sin(phase * TAU))\n" +" phase = fmod(phase + increment, 1.0)\n" +"[/gdscript]\n" +"[csharp]\n" +"[Export] public AudioStreamPlayer Player { get; set; }\n" +"\n" +"private AudioStreamGeneratorPlayback _playback; // Will hold the " +"AudioStreamGeneratorPlayback.\n" +"private float _sampleHz;\n" +"private float _pulseHz = 440.0f; // The frequency of the sound wave.\n" +"\n" +"public override void _Ready()\n" +"{\n" +" if (Player.Stream is AudioStreamGenerator generator) // Type as a " +"generator to access MixRate.\n" +" {\n" +" _sampleHz = generator.MixRate;\n" +" Player.Play();\n" +" _playback = (AudioStreamGeneratorPlayback)Player." +"GetStreamPlayback();\n" +" FillBuffer();\n" +" }\n" +"}\n" +"\n" +"public void FillBuffer()\n" +"{\n" +" double phase = 0.0;\n" +" float increment = _pulseHz / _sampleHz;\n" +" int framesAvailable = _playback.GetFramesAvailable();\n" +"\n" +" for (int i = 0; i < framesAvailable; i++)\n" +" {\n" +" _playback.PushFrame(Vector2.One * (float)Mathf.Sin(phase * Mathf." +"Tau));\n" +" phase = Mathf.PosMod(phase + increment, 1.0);\n" +" }\n" +"}\n" +"[/csharp]\n" +"[/codeblocks]\n" +"In the example above, the \"AudioStreamPlayer\" node must use an " +"[AudioStreamGenerator] as its stream. The [code]fill_buffer[/code] function " +"provides audio data for approximating a sine wave.\n" +"See also [AudioEffectSpectrumAnalyzer] for performing real-time audio " +"spectrum analysis.\n" +"[b]Note:[/b] Due to performance constraints, this class is best used from C# " +"or from a compiled language via GDExtension. If you still want to use this " +"class from GDScript, consider using a lower [member mix_rate] such as 11,025 " +"Hz or 22,050 Hz." +msgstr "" +"[AudioStreamGenerator] ist ein Typ von Audiostream, der nicht von sich aus " +"Töne abspielt, sondern ein Skript erwartet, das Audiodaten für ihn erzeugt. " +"Siehe auch [AudioStreamGeneratorPlayback].\n" +"Hier ist ein Beispiel, wie man damit eine Sinuswelle erzeugt:\n" +"[codeblocks]\n" +"[gdscript]\n" +"var playback # Will hold the AudioStreamGeneratorPlayback.\n" +"@onready var sample_hz = $AudioStreamPlayer.stream.mix_rate\n" +"var pulse_hz = 440.0 # The frequency of the sound wave.\n" +"\n" +"func _ready():\n" +" $AudioStreamPlayer.play()\n" +" playback = $AudioStreamPlayer.get_stream_playback()\n" +" fill_buffer()\n" +"\n" +"func fill_buffer():\n" +" var phase = 0.0\n" +" var increment = pulse_hz / sample_hz\n" +" var frames_available = playback.get_frames_available()\n" +"\n" +" for i in range(frames_available):\n" +" playback.push_frame(Vector2.ONE * sin(phase * TAU))\n" +" phase = fmod(phase + increment, 1.0)\n" +"[/gdscript]\n" +"[csharp]\n" +"[Export] public AudioStreamPlayer Player { get; set; }\n" +"\n" +"private AudioStreamGeneratorPlayback _playback; // Will hold the " +"AudioStreamGeneratorPlayback.\n" +"private float _sampleHz;\n" +"private float _pulseHz = 440.0f; // The frequency of the sound wave.\n" +"\n" +"public override void _Ready()\n" +"{\n" +" if (Player.Stream is AudioStreamGenerator generator) // Type as a " +"generator to access MixRate.\n" +" {\n" +" _sampleHz = generator.MixRate;\n" +" Player.Play();\n" +" _playback = (AudioStreamGeneratorPlayback)Player." +"GetStreamPlayback();\n" +" FillBuffer();\n" +" }\n" +"}\n" +"\n" +"public void FillBuffer()\n" +"{\n" +" double phase = 0.0;\n" +" float increment = _pulseHz / _sampleHz;\n" +" int framesAvailable = _playback.GetFramesAvailable();\n" +"\n" +" for (int i = 0; i < framesAvailable; i++)\n" +" {\n" +" _playback.PushFrame(Vector2.One * (float)Mathf.Sin(phase * Mathf." +"Tau));\n" +" phase = Mathf.PosMod(phase + increment, 1.0);\n" +" }\n" +"}\n" +"[/csharp]\n" +"[/codeblocks]\n" +"Im obigen Beispiel muss der Knoten \"AudioStreamPlayer\" einen " +"[AudioStreamGenerator] als Stream verwenden. Die Funktion [code]fill_buffer[/" +"code] liefert Audiodaten zur Annäherung an eine Sinuswelle.\n" +"Siehe auch [AudioEffectSpectrumAnalyzer] zur Durchführung einer Echtzeit-" +"Audio-Spektrum-Analyse.\n" +"[b]Hinweis:[/b] Aufgrund von Performance-Beschränkungen wird diese Klasse am " +"besten von C# oder von einer kompilierten Sprache über GDExtension verwendet. " +"Wenn Sie diese Klasse dennoch über GDScript verwenden möchten, sollten Sie " +"eine niedrigere [member mix_rate] wie 11.025 Hz oder 22.050 Hz verwenden." + +msgid "" "The length of the buffer to generate (in seconds). Lower values result in " "less latency, but require the script to generate audio data faster, resulting " "in increased CPU usage and more risk for audio cracking if the CPU can't keep " @@ -17017,6 +17184,13 @@ msgstr "" msgid "Constructs an empty [Dictionary]." msgstr "Konstruiert ein leeres [Dictionary]." +msgid "" +"Returns [code]true[/code] if the dictionary is empty (its size is [code]0[/" +"code]). See also [method size]." +msgstr "" +"Gibt [code]true[/code] zurück, wenn das Wörterbuch leer ist (seine Größe ist " +"[code]0[/code]). Siehe auch [Methode size]." + msgid "File system" msgstr "Dateisystem" @@ -17583,6 +17757,9 @@ msgstr "" "Ermöglicht es einer Anwendung, die persönlichen Profildaten des Benutzers zu " "lesen." +msgid "Allows an application to read the user dictionary." +msgstr "Ermöglicht es einer Anwendung, das Benutzerwörterbuch zu lesen." + msgid "Deprecated in API level 15." msgstr "Veraltet in API-Level 15." @@ -17926,6 +18103,81 @@ msgstr "" "Weise betreffen, wie Eingaben im [SceneTree] weitergegeben werden." msgid "" +"Returns [code]true[/code] when the user has [i]started[/i] pressing the " +"action event in the current frame or physics tick. It will only return " +"[code]true[/code] on the frame or tick that the user pressed down the " +"button.\n" +"This is useful for code that needs to run only once when an action is " +"pressed, instead of every frame while it's pressed.\n" +"If [param exact_match] is [code]false[/code], it ignores additional input " +"modifiers for [InputEventKey] and [InputEventMouseButton] events, and the " +"direction for [InputEventJoypadMotion] events.\n" +"[b]Note:[/b] Returning [code]true[/code] does not imply that the action is " +"[i]still[/i] pressed. An action can be pressed and released again rapidly, " +"and [code]true[/code] will still be returned so as not to miss input.\n" +"[b]Note:[/b] Due to keyboard ghosting, [method is_action_just_pressed] may " +"return [code]false[/code] even if one of the action's keys is pressed. See " +"[url=$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input " +"examples[/url] in the documentation for more information.\n" +"[b]Note:[/b] During input handling (e.g. [method Node._input]), use [method " +"InputEvent.is_action_pressed] instead to query the action state of the " +"current event." +msgstr "" +"Gibt [code]true[/code] zurück, wenn der Benutzer [i]begonnen hat[/i], das " +"Aktionsereignis im aktuellen Frame oder Physik-Tick zu drücken. Es wird nur " +"[code]true[/code] in dem Frame oder Tick zurückgegeben, in dem der Benutzer " +"die Aktion gedrückt hat.\n" +"Dies ist nützlich für Code, der nur einmal ausgeführt werden muss, wenn eine " +"Aktion gedrückt wird, anstatt bei jedem Frame, während sie gedrückt gelassen " +"wird.\n" +"Wenn [param exact_match] [code]false[/code] ist, werden zusätzliche " +"Eingabemodifikatoren für [InputEventKey]- und [InputEventMouseButton]-" +"Ereignisse sowie die Richtung für [InputEventJoypadMotion]-Ereignisse " +"ignoriert.\n" +"[b]Hinweis:[/b] Die Rückgabe von [code]true[/code] bedeutet nicht, dass die " +"Aktion [i]noch[/i] gedrückt ist. Eine Aktion kann schnell gedrückt und wieder " +"losgelassen werden, und [code]true[/code] wird trotzdem zurückgegeben, um " +"keine Eingabe zu verpassen.\n" +"[b]Hinweis:[/b] Aufgrund von Tastatur-Ghosting kann [method " +"is_action_just_pressed] auch dann [code]false[/code] zurückgeben, wenn eine " +"der Tasten der Aktion gedrückt ist. Siehe [url=$DOCS_URL/tutorials/inputs/" +"input_examples.html#keyboard-events]Eingabebeispiele[/url] in der " +"Dokumentation für weitere Informationen.\n" +"[b]Hinweis:[/b] Verwenden Sie bei der Eingabeverarbeitung (z.B. [Methode Node." +"_input]) stattdessen [Methode InputEvent.is_action_pressed], um den " +"Aktionsstatus des aktuellen Ereignisses abzufragen." + +msgid "" +"Returns [code]true[/code] when the user [i]stops[/i] pressing the action " +"event in the current frame or physics tick. It will only return [code]true[/" +"code] on the frame or tick that the user releases the button.\n" +"[b]Note:[/b] Returning [code]true[/code] does not imply that the action is " +"[i]still[/i] not pressed. An action can be released and pressed again " +"rapidly, and [code]true[/code] will still be returned so as not to miss " +"input.\n" +"If [param exact_match] is [code]false[/code], it ignores additional input " +"modifiers for [InputEventKey] and [InputEventMouseButton] events, and the " +"direction for [InputEventJoypadMotion] events.\n" +"[b]Note:[/b] During input handling (e.g. [method Node._input]), use [method " +"InputEvent.is_action_released] instead to query the action state of the " +"current event." +msgstr "" +"Gibt [code]true[/code] zurück, wenn der Benutzer [i]aufhört[/i], das Aktions-" +"Event im aktuellen Frame oder Physik-Tick zu drücken. Es wird nur dann " +"[code]true[/code] zurückgegeben, wenn der Benutzer die Taste loslässt.\n" +"[b]Hinweis:[/b] Die Rückgabe von [code]true[/code] bedeutet nicht, dass die " +"Aktion [i]noch[/i] nicht gedrückt ist. Eine Aktion kann schnell losgelassen " +"und wieder gedrückt werden, und [code]true[/code] wird trotzdem " +"zurückgegeben, um keine Eingabe zu verpassen.\n" +"Wenn [param exact_match] [code]false[/code] ist, werden zusätzliche " +"Eingabemodifikatoren für die Ereignisse [InputEventKey] und " +"[InputEventMouseButton] sowie die Richtung für die Ereignisse " +"[InputEventJoypadMotion] ignoriert.\n" +"[b]Hinweis:[/b] Verwenden Sie bei der Eingabeverarbeitung (z.B. [method Node." +"_input]) stattdessen [method InputEvent.is_action_released], um den " +"Aktionsstatus des aktuellen Ereignisses abzufragen." + +msgid "" "Returns [code]true[/code] if you are pressing the action event.\n" "If [param exact_match] is [code]false[/code], it ignores additional input " "modifiers for [InputEventKey] and [InputEventMouseButton] events, and the " @@ -18633,6 +18885,21 @@ msgstr "" "distance matching[/url] in Zstandard." msgid "" +"When set to [code]warn[/code] or [code]error[/code], produces a warning or an " +"error respectively when a variable or parameter has no static type, or if a " +"function has no static return type.\n" +"[b]Note:[/b] This warning is recommended together with [member EditorSettings." +"text_editor/completion/add_type_hints] to help achieve type safety." +msgstr "" +"Wenn auf [code]warn[/code] oder [code]error[/code] gesetzt, wird eine Warnung " +"bzw. ein Fehler ausgegeben, wenn eine Variable oder ein Parameter keinen " +"statischen Typ hat oder wenn eine Funktion keinen statischen Rückgabetyp " +"hat.\n" +"[b]Hinweis:[/b] Diese Warnung wird zusammen mit [member EditorSettings." +"text_editor/completion/add_type_hints] empfohlen, um Typsicherheit zu " +"erreichen." + +msgid "" "Constructs a quaternion that will rotate around the given axis by the " "specified angle. The axis must be a normalized vector." msgstr "" @@ -19448,6 +19715,13 @@ msgid "Using VisualShaders" msgstr "Verwendung von VisualShaders" msgid "" +"Has only one output port and no inputs.\n" +"Translated to [code skip-lint]bool[/code] in the shader language." +msgstr "" +"Hat nur einen Ausgangs-Port und keine Eingänge.\n" +"Wird in der Shader-Sprache in [code skip-lint]bool[/code] übersetzt." + +msgid "" "Constrains a value to lie between [code]min[/code] and [code]max[/code] " "values." msgstr "" diff --git a/doc/translations/zh_CN.po b/doc/translations/zh_CN.po index b9066b8cc6..3e9a2f777c 100644 --- a/doc/translations/zh_CN.po +++ b/doc/translations/zh_CN.po @@ -86,7 +86,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine class reference\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" -"PO-Revision-Date: 2023-11-16 07:52+0000\n" +"PO-Revision-Date: 2023-11-19 00:34+0000\n" "Last-Translator: 风青山 <idleman@yeah.net>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot-class-reference/zh_Hans/>\n" @@ -2071,7 +2071,7 @@ msgid "" msgstr "" "根据 [param weight] 定义的系数,以及 [param pre] 和 [param post] 值,在两个旋" "转值之间的最短路径进行三次插值。另见 [method lerp_angle]。\n" -"它可以根据时间值执行比 [code]cubic_interpolate()[/code] 更平滑的插值。" +"它可以根据时间值执行比 [method cubic_interpolate] 更平滑的插值。" msgid "" "Cubic interpolates between two values by the factor defined in [param weight] " @@ -3783,7 +3783,7 @@ msgstr "" "如果无法完成类型转换,此方法将返回该类型的默认值,例如 [Rect2] 转换为 " "[Vector2] 时将总是返回 [constant Vector2.ZERO]。只要 [param type] 是一个有效" "的 Variant 类型,此方法就永远不会显示错误消息。\n" -"返回的值是一个 [Variant],但是其中的数据以及 [enum Variant Type] 将会与请求的" +"返回的值是一个 [Variant],但是其中的数据以及 [enum Variant.Type] 将会与请求的" "类型相同。\n" "[codeblock]\n" "type_convert(\"Hi!\", TYPE_INT) # 返回 0\n" @@ -3901,6 +3901,25 @@ msgstr "" "都是空值。" msgid "" +"Returns a [WeakRef] instance holding a weak reference to [param obj]. Returns " +"an empty [WeakRef] instance if [param obj] is [code]null[/code]. Prints an " +"error and returns [code]null[/code] if [param obj] is neither [Object]-" +"derived nor [code]null[/code].\n" +"A weak reference to an object is not enough to keep the object alive: when " +"the only remaining references to a referent are weak references, garbage " +"collection is free to destroy the referent and reuse its memory for something " +"else. However, until the object is actually destroyed the weak reference may " +"return the object even if there are no strong references to it." +msgstr "" +"返回一个 [WeakRef] 实例,其中包含对 [param obj] 的弱引用。如果 [param obj] 为 " +"[code]null[/code],则返回空的 [WeakRef] 实例。如果 [param obj] 既不是 " +"[Object] 派生实例,也不是 [code]null[/code],则打印错误并返回 [code]null[/" +"code]。\n" +"对对象的弱引用不足以使对象保持存活:当对引用对象的剩余引用都是弱引用时,垃圾回" +"收可以自由销毁该引用对象并将其内存重新用于其他用途。但是,在对象实际被销毁之" +"前,弱引用可能会返回该对象,即使不存在对它的强引用也是如此。" + +msgid "" "Wraps the [Variant] [param value] between [param min] and [param max]. Can be " "used for creating loop-alike behavior or infinite surfaces.\n" "Variant types [int] and [float] are supported. If any of the arguments is " @@ -5613,6 +5632,13 @@ msgstr "" "提示一个 [Color] 属性在编辑时不能影响其透明度([member Color.a] 不可编辑)。" msgid "" +"Hints that the property's value is an object encoded as object ID, with its " +"type specified in the hint string. Used by the debugger." +msgstr "" +"提示该属性的值是一个被编码为对象 ID 的对象,其类型在提示字符串中指定。被用于调" +"试器。" + +msgid "" "If a property is [String], hints that the property represents a particular " "type (class). This allows to select a type from the create dialog. The " "property will store the selected type as a string.\n" @@ -5782,6 +5808,57 @@ msgstr "" "[b]注意:[/b]后缀冒号是必须的,否则无法正确识别内置类型。" msgid "" +"[i]Deprecated.[/i] This hint is not used anywhere and will be removed in the " +"future." +msgstr "[i]已废弃。[/i]该提示未被用于任何地方,将来会被移除。" + +msgid "Hints that an object is too big to be sent via the debugger." +msgstr "提示对象太大而无法通过调试器发送。" + +msgid "" +"Hints that the hint string specifies valid node types for property of type " +"[NodePath]." +msgstr "提示该提示字符串为类型 [NodePath] 的属性指定有效的节点类型。" + +msgid "" +"Hints that a [String] property is a path to a file. Editing it will show a " +"file dialog for picking the path for the file to be saved at. The dialog has " +"access to the project's directory. The hint string can be a set of filters " +"with wildcards like [code]\"*.png,*.jpg\"[/code]. See also [member FileDialog." +"filters]." +msgstr "" +"提示 [String] 属性是文件的路径。编辑它将显示一个文件对话框,用于选择文件要保存" +"的路径。该对话框可以访问项目的目录。该提示字符串可以是一组带有通配符的筛选器," +"例如 [code]\"*.png,*.jpg\"[/code]。另请参阅 [member FileDialog.filters]。" + +msgid "" +"Hints that a [String] property is a path to a file. Editing it will show a " +"file dialog for picking the path for the file to be saved at. The dialog has " +"access to the entire filesystem. The hint string can be a set of filters with " +"wildcards like [code]\"*.png,*.jpg\"[/code]. See also [member FileDialog." +"filters]." +msgstr "" +"提示 [String] 属性是文件的路径。编辑它将显示一个文件对话框,用于选择文件要保存" +"的路径。该对话框可以访问整个文件系统。该提示字符串可以是一组带有通配符的筛选" +"器,例如 [code]\"*.png,*.jpg\"[/code]。另请参阅 [member FileDialog.filters]。" + +msgid "" +"Hints that an [int] property is an object ID.\n" +"[i]Deprecated.[/i] This hint is not used anywhere and will be removed in the " +"future." +msgstr "" +"提示 [int] 属性是对象 ID。\n" +"[i]已废弃。[/i]该提示不会用于任何地方,将来会被移除。" + +msgid "Hints that an [int] property is a pointer. Used by GDExtension." +msgstr "提示 [int] 属性是一个指针。用于 GDExtension。" + +msgid "" +"Hints that a property is an [Array] with the stored type specified in the " +"hint string." +msgstr "提示属性是一个 [Array],其存储类型在提示字符串中指定。" + +msgid "" "Hints that a string property is a locale code. Editing it will show a locale " "dialog for picking language and country." msgstr "" @@ -5795,6 +5872,14 @@ msgstr "" "提示一个字典属性是字符串翻译映射。字典的键是区域设置代码,值是翻译后的字符串。" msgid "" +"Hints that a property is an instance of a [Node]-derived type, optionally " +"specified via the hint string (e.g. [code]\"Node2D\"[/code]). Editing it will " +"show a dialog for picking a node from the scene." +msgstr "" +"提示属性是 [Node] 派生类型的实例,可以选择通过提示字符串指定(例如 " +"[code]\"Node2D\"[/code])。编辑它将显示一个用于从场景中选取节点的对话框。" + +msgid "" "Hints that a quaternion property should disable the temporary euler editor." msgstr "提示四元数属性应当禁用临时欧拉值编辑器。" @@ -5838,6 +5923,11 @@ msgid "" msgstr "" "用于在子组(一个组下)中将编辑器中的属性编组在一起。请参阅 [EditorInspector]。" +msgid "" +"The property is a bitfield, i.e. it contains multiple flags represented as " +"bits." +msgstr "该属性是一个位字段,即它包含多个被表示为位的标志。" + msgid "The property does not save its state in [PackedScene]." msgstr "该属性不在 [PackedScene] 中保存其状态。" @@ -5849,6 +5939,31 @@ msgid "" "scene file." msgstr "该属性是一个脚本变量,应该被序列化并保存在场景文件中。" +msgid "" +"The property value of type [Object] will be stored even if its value is " +"[code]null[/code]." +msgstr "即使 [Object] 类型的属性值为 [code]null[/code],也会被存储。" + +msgid "If this property is modified, all inspector fields will be refreshed." +msgstr "如果该属性被修改,则所有检查器字段都将被刷新。" + +msgid "" +"Signifies a default value from a placeholder script instance.\n" +"[i]Deprecated.[/i] This hint is not used anywhere and will be removed in the " +"future." +msgstr "" +"表示占位符脚本实例的默认值。\n" +"[i]已废弃。[/i]该提示不会用于任何地方,将来会被移除。" + +msgid "" +"The property is an enum, i.e. it only takes named integer constants from its " +"associated enumeration." +msgstr "该属性是一个枚举,即它仅从其关联的枚举中获取被命名的整数常量。" + +msgid "" +"If property has [code]nil[/code] as default value, its type will be [Variant]." +msgstr "如果属性将 [code]nil[/code] 作为默认值,则其类型将为 [Variant]。" + msgid "The property is an array." msgstr "该属性为数组。" @@ -5874,6 +5989,48 @@ msgid "" "(the Compatibility rendering method is excluded)." msgstr "只有在支持现代渲染器(不包含 GLES3)的情况下该属性才会在编辑器中显示。" +msgid "" +"The [NodePath] property will always be relative to the scene's root. Mostly " +"useful for local resources." +msgstr "[NodePath] 属性将始终相对于场景根。对于本地资源来说最有用。" + +msgid "" +"Use when a resource is created on the fly, i.e. the getter will always return " +"a different instance. [ResourceSaver] needs this information to properly save " +"such resources." +msgstr "" +"在动态创建资源时使用,即 Getter 将始终返回一个不同的实例。[ResourceSaver] 需要" +"该信息来正确保存这种资源。" + +msgid "" +"Inserting an animation key frame of this property will automatically " +"increment the value, allowing to easily keyframe multiple values in a row." +msgstr "" +"插入该属性的动画关键帧将自动增加该值,从而可以轻松地为一行中的多个值设置关键" +"帧。" + +msgid "" +"When loading, the resource for this property can be set at the end of " +"loading.\n" +"[i]Deprecated.[/i] This hint is not used anywhere and will be removed in the " +"future." +msgstr "" +"加载时,可以在加载结束时设置该属性的资源。\n" +"[i]已废弃。[/i]该提示不会用于任何地方,将来会被移除。" + +msgid "" +"When this property is a [Resource] and base object is a [Node], a resource " +"instance will be automatically created whenever the node is created in the " +"editor." +msgstr "" +"当该属性为 [Resource] 且基础对象为 [Node] 时,则每当该节点是在编辑器中创建的," +"都会自动创建一个资源实例。" + +msgid "" +"The property is considered a basic setting and will appear even when advanced " +"mode is disabled. Used for project settings." +msgstr "该属性被视为基本设置,即使禁用高级模式时也会显现。用于项目设置。" + msgid "The property is read-only in the [EditorInspector]." msgstr "该属性在 [EditorInspector] 中只读。" @@ -14422,11 +14579,9 @@ msgid "" "[b]Note:[/b] This can be expensive; it is not recommended to call [method " "get_output_latency] every frame." msgstr "" -"返回音频驱动程序的有效输出延迟。该方法基于 [ 成员 ProjectSettings.audio/" -"driver/output_latency],但精确的返回值将依赖操作系统和音频驱动程序而有所不" -"同。\n" -"[b] 注意:[/b] 该方法可能存在大量性能开销;不建议逐帧调用 [ 方法 " -"get_output_latency]。" +"返回音频驱动的实际输出延迟。基于 [member ProjectSettings.audio/driver/" +"output_latency],但实际的返回值取决于操作系统和音频驱动。\n" +"[b]注意:[/b]可能开销较大;不建议每帧都调用 [method get_output_latency]。" msgid "Returns the speaker configuration." msgstr "返回扬声器的配置。" @@ -14912,9 +15067,12 @@ msgid "" "This class is part of the audio stream system, which also supports WAV files " "through the [AudioStreamWAV] class." msgstr "" -"AudioStreamOggVorbis 类是专用于处理 Ogg Vorbis 文件格式的 [ 音频流 ] 类。它提" -"供加载和播放 Ogg Vorbis 文件以及管理循环和其他播放属性的功能。该类是音频流系统" -"的一部分,该系统还通过 [AudioStreamWAV] 类支持 WAV 系统。" +"AudioStreamOggVorbis 类是专用于处理 Ogg Vorbis 文件格式的 [AudioStream] 类。它" +"提供加载和播放 Ogg Vorbis 文件以及管理循环和其他播放属性的功能。该类是音频流系" +"统的一部分,该系统还通过 [AudioStreamWAV] 类支持 WAV 系统。" + +msgid "Runtime file loading and saving" +msgstr "运行时文件加载与保存" msgid "" "Creates a new AudioStreamOggVorbis instance from the given buffer. The buffer " @@ -14935,8 +15093,8 @@ msgid "" "loop_offset] once it is done playing. Useful for ambient sounds and " "background music." msgstr "" -"如果为 [code]true[/code],则音频播放完成后将从 [ 成员 loop_offset] 指定的位置" -"再次播放。该方法对环境声音和背景音乐很有用。" +"如果为 [code]true[/code],则音频播放完成后将从 [member loop_offset] 指定的位置" +"再次播放。可用于环境声音和背景音乐。" msgid "Contains the raw Ogg data for this stream." msgstr "包含用于这个流的原始 Ogg 数据。" @@ -29492,6 +29650,11 @@ msgid "Particles are drawn in the order emitted." msgstr "粒子按发射顺序绘制。" msgid "" +"Particles are drawn in order of remaining lifetime. In other words, the " +"particle with the highest lifetime is drawn at the front." +msgstr "粒子按照剩余寿命的顺序绘制。换句话说,寿命最长的粒子被绘制在前面。" + +msgid "" "Use with [method set_param_min], [method set_param_max], and [method " "set_param_curve] to set initial velocity properties." msgstr "" @@ -55012,6 +55175,11 @@ msgstr "" "因此它永远不会发出。\n" "[b]注意:[/b]由于粒子是在 GPU 上计算的,因此在该信号发出之前可能会有延迟。" +msgid "" +"Particles are drawn in reverse order of remaining lifetime. In other words, " +"the particle with the lowest lifetime is drawn at the front." +msgstr "粒子按照剩余寿命的相反顺序绘制。换句话说,寿命最短的粒子被绘制在前面。" + msgid "Particle starts at the specified position." msgstr "粒子在指定位置开始。" @@ -59194,6 +59362,28 @@ msgstr "水平翻转图像。" msgid "Flips the image vertically." msgstr "垂直翻转图像。" +msgid "" +"Generates mipmaps for the image. Mipmaps are precalculated lower-resolution " +"copies of the image that are automatically used if the image needs to be " +"scaled down when rendered. They help improve image quality and performance " +"when rendering. This method returns an error if the image is compressed, in a " +"custom format, or if the image's width/height is [code]0[/code]. Enabling " +"[param renormalize] when generating mipmaps for normal map textures will make " +"sure all resulting vector values are normalized.\n" +"It is possible to check if the image has mipmaps by calling [method " +"has_mipmaps] or [method get_mipmap_count]. Calling [method generate_mipmaps] " +"on an image that already has mipmaps will replace existing mipmaps in the " +"image." +msgstr "" +"为图像生成多级渐远纹理(Mipmap)。多级渐远纹理是预先计算好的图像的低分辨率副" +"本,如果图像在渲染时需要按比例缩小,则会自动使用这些副本。它们有助于在渲染时提" +"高图像质量和性能。如果图像被压缩,或采用自定义格式,或图像的宽度或高度为 " +"[code]0[/code],则该方法返回错误。在为法线纹理生成多级渐远纹理时启用 [param " +"renormalize] 能够确保得到的所有向量值都是归一化的。\n" +"调用 [method has_mipmaps] 或 [method get_mipmap_count] 能够检查图像是否使用多" +"级渐远纹理。在已拥有多级渐远纹理的图像上调用 [method generate_mipmaps] 将替换" +"该图像中已有的多级渐远纹理。" + msgid "Returns a copy of the image's raw data." msgstr "返回图像原始数据的副本。" @@ -59286,12 +59476,45 @@ msgstr "" "[code]user://[/code] 目录的图像,并且可能不适用于导出的项目。\n" "另请参阅 [ImageTexture] 说明,以获取使用示例。" +msgid "" +"Loads an image from the binary contents of a BMP file.\n" +"[b]Note:[/b] Godot's BMP module doesn't support 16-bit per pixel images. Only " +"1-bit, 4-bit, 8-bit, 24-bit, and 32-bit per pixel images are supported.\n" +"[b]Note:[/b] This method is only available in engine builds with the BMP " +"module enabled. By default, the BMP module is enabled, but it can be disabled " +"at build-time using the [code]module_bmp_enabled=no[/code] SCons option." +msgstr "" +"从 BMP 文件的二进制内容加载图像。\n" +"[b]注意:[/b]Godot 的 BMP 模块不支持每像素 16 位的图像。仅支持每像素 1 位、4 " +"位、8 位、24 位和 32 位的图像。\n" +"[b]注意:[/b]该方法仅在启用了 BMP 模块的引擎版本中可用。默认情况下,BMP 模块是" +"启用的,但可以在构建时使用 [code]module_bmp_enabled=no[/code] SCons 选项禁用" +"它。" + msgid "Creates a new [Image] and loads data from the specified file." msgstr "创建一个新的 [Image] 并从指定文件加载数据。" msgid "Loads an image from the binary contents of a JPEG file." msgstr "从 JPEG 文件的二进制内容加载图像。" +msgid "" +"Loads an image from the binary contents of a [url=https://github.com/" +"KhronosGroup/KTX-Software]KTX[/url] file. Unlike most image formats, KTX can " +"store VRAM-compressed data and embed mipmaps.\n" +"[b]Note:[/b] Godot's libktx implementation only supports 2D images. Cubemaps, " +"texture arrays, and de-padding are not supported.\n" +"[b]Note:[/b] This method is only available in engine builds with the KTX " +"module enabled. By default, the KTX module is enabled, but it can be disabled " +"at build-time using the [code]module_ktx_enabled=no[/code] SCons option." +msgstr "" +"从 [url=https://github.com/KhronosGroup/KTX-Software]KTX[/url] 文件的二进制内" +"容加载图像。与大多数图像格式不同,KTX 可以存储 VRAM 压缩数据并嵌入 mipmap。\n" +"[b]注意:[/b]Godot 的 libktx 实现仅支持 2D 图像。不支持立方体贴图、纹理数组、" +"和去填充。\n" +"[b]注意:[/b]该方法仅在启用了 KTX 模块的引擎版本中可用。默认情况下,KTX 模块是" +"启用的,但可以在构建时使用 [code]module_ktx_enabled=no[/code] SCons 选项禁用" +"它。" + msgid "Loads an image from the binary contents of a PNG file." msgstr "从 PNG 文件的二进制内容加载图像。" @@ -59322,6 +59545,17 @@ msgstr "" "启用的,但可以在构建时使用 [code]module_svg_enabled=no[/code] SCons 选项禁用" "它。" +msgid "" +"Loads an image from the binary contents of a TGA file.\n" +"[b]Note:[/b] This method is only available in engine builds with the TGA " +"module enabled. By default, the TGA module is enabled, but it can be disabled " +"at build-time using the [code]module_tga_enabled=no[/code] SCons option." +msgstr "" +"从 TGA 文件的二进制内容加载图像。\n" +"[b]注意:[/b]该方法仅在启用了 TGA 模块的引擎版本中可用。默认情况下,TGA 模块是" +"启用的,但可以在构建时使用 [code]module_tga_enabled=no[/code] SCons 选项禁用" +"它。" + msgid "Loads an image from the binary contents of a WebP file." msgstr "从 WebP 文件的二进制内容加载图像。" @@ -59334,6 +59568,14 @@ msgstr "" "可以在不增加多边形数量的情况下向 3D 表面添加大量细节。" msgid "" +"Multiplies color values with alpha values. Resulting color values for a pixel " +"are [code](color * alpha)/256[/code]. See also [member CanvasItemMaterial." +"blend_mode]." +msgstr "" +"将颜色值与 Alpha 值相乘。像素的最终颜色值为 [code](color * alpha)/256[/code]。" +"另见 [member CanvasItemMaterial.blend_mode]。" + +msgid "" "Resizes the image to the given [param width] and [param height]. New pixels " "are calculated using the [param interpolation] mode defined via [enum " "Interpolation] constants." @@ -59446,6 +59688,34 @@ msgid "Saves the image as a PNG file to a byte array." msgstr "将该图像作为 PNG 文件保存到字节数组中。" msgid "" +"Saves the image as a WebP (Web Picture) file to the file at [param path]. By " +"default it will save lossless. If [param lossy] is true, the image will be " +"saved lossy, using the [param quality] setting between 0.0 and 1.0 " +"(inclusive). Lossless WebP offers more efficient compression than PNG.\n" +"[b]Note:[/b] The WebP format is limited to a size of 16383×16383 pixels, " +"while PNG can save larger images." +msgstr "" +"将该图像作为 WebP(Web 图片)文件保存到 [param path] 中的文件中。默认情况下," +"它将无损保存。如果 [param lossy] 为真,则该图像将使用介于 0.0 和 1.0(包含)之" +"间的 [param quality] 设置进行有损保存。无损 WebP 提供比 PNG 更有效的压缩。\n" +"[b]注意:[/b]WebP 格式的大小限制为 16383×16383 像素,而 PNG 可以保存更大的图" +"像。" + +msgid "" +"Saves the image as a WebP (Web Picture) file to a byte array. By default it " +"will save lossless. If [param lossy] is true, the image will be saved lossy, " +"using the [param quality] setting between 0.0 and 1.0 (inclusive). Lossless " +"WebP offers more efficient compression than PNG.\n" +"[b]Note:[/b] The WebP format is limited to a size of 16383×16383 pixels, " +"while PNG can save larger images." +msgstr "" +"将该图像作为 WebP(Web 图片)文件保存到字节数组中。默认情况下,它将无损保存。" +"如果 [param lossy] 为真,则该图像将使用介于 0.0 和 1.0(包含)之间的 [param " +"quality] 设置进行有损保存。无损 WebP 提供比 PNG 更有效的压缩。\n" +"[b]注意:[/b]WebP 格式的大小限制为 16383×16383 像素,而 PNG 可以保存更大的图" +"像。" + +msgid "" "Overwrites data of an existing [Image]. Non-static equivalent of [method " "create_from_data]." msgstr "覆盖现有 [Image] 的数据。[method create_from_data] 的非静态等价物。" @@ -59537,6 +59807,11 @@ msgstr "" "[/codeblocks]\n" "这与 [method set_pixel] 相同,只是使用一个 [Vector2i] 参数而不是两个整数参数。" +msgid "" +"Shrinks the image by a factor of 2 on each axis (this divides the pixel count " +"by 4)." +msgstr "在每个轴上将图像缩小 2 倍(这会将像素数除以 4)。" + msgid "Converts the raw data from the sRGB colorspace to a linear scale." msgstr "将原始数据从 sRGB 色彩空间转换为线性比例。" @@ -60674,6 +60949,70 @@ msgstr "" "要的值(在 0 到 1 的范围内)。" msgid "" +"Returns [code]true[/code] when the user has [i]started[/i] pressing the " +"action event in the current frame or physics tick. It will only return " +"[code]true[/code] on the frame or tick that the user pressed down the " +"button.\n" +"This is useful for code that needs to run only once when an action is " +"pressed, instead of every frame while it's pressed.\n" +"If [param exact_match] is [code]false[/code], it ignores additional input " +"modifiers for [InputEventKey] and [InputEventMouseButton] events, and the " +"direction for [InputEventJoypadMotion] events.\n" +"[b]Note:[/b] Returning [code]true[/code] does not imply that the action is " +"[i]still[/i] pressed. An action can be pressed and released again rapidly, " +"and [code]true[/code] will still be returned so as not to miss input.\n" +"[b]Note:[/b] Due to keyboard ghosting, [method is_action_just_pressed] may " +"return [code]false[/code] even if one of the action's keys is pressed. See " +"[url=$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]Input " +"examples[/url] in the documentation for more information.\n" +"[b]Note:[/b] During input handling (e.g. [method Node._input]), use [method " +"InputEvent.is_action_pressed] instead to query the action state of the " +"current event." +msgstr "" +"当用户在当前帧或物理周期中[i]开始[/i]按下动作事件时返回 [code]true[/code]。只" +"在用户按下按钮的那一帧或周期中为 [code]true[/code]。\n" +"如果代码只需要在动作按下时执行一次,而不是只要处于按下状态就每帧都需要执行,那" +"么这个方法就很有用。\n" +"如果 [param exact_match] 为 [code]false[/code],则会忽略 [InputEventKey] 和 " +"[InputEventMouseButton] 事件的额外输入修饰键,以及 [InputEventJoypadMotion] 事" +"件的方向。\n" +"[b]注意:[/b]返回 [code]true[/code] 并不意味着该动作[i]仍然[/i]处于按下状态。" +"动作在按下后是可以很快再释放的,为了不丢失输入,这种情况下仍然会返回 " +"[code]true[/code]。\n" +"[b]注意:[/b]由于键盘重影,即便该动作的某个键处于按下状态,[method " +"is_action_just_pressed] 仍可能会返回 [code]false[/code]。详情见文档中的" +"[url=$DOCS_URL/tutorials/inputs/input_examples.html#keyboard-events]《输入示" +"例》[/url]。\n" +"[b]注意:[/b]在输入处理期间(例如 [method Node._input]),请使用 [method " +"InputEvent.is_action_pressed] 来查询当前事件的动作状态。" + +msgid "" +"Returns [code]true[/code] when the user [i]stops[/i] pressing the action " +"event in the current frame or physics tick. It will only return [code]true[/" +"code] on the frame or tick that the user releases the button.\n" +"[b]Note:[/b] Returning [code]true[/code] does not imply that the action is " +"[i]still[/i] not pressed. An action can be released and pressed again " +"rapidly, and [code]true[/code] will still be returned so as not to miss " +"input.\n" +"If [param exact_match] is [code]false[/code], it ignores additional input " +"modifiers for [InputEventKey] and [InputEventMouseButton] events, and the " +"direction for [InputEventJoypadMotion] events.\n" +"[b]Note:[/b] During input handling (e.g. [method Node._input]), use [method " +"InputEvent.is_action_released] instead to query the action state of the " +"current event." +msgstr "" +"当用户在当前帧或物理周期中[i]停止[/i]按下动作事件时返回 [code]true[/code]。只" +"在用户松开按钮的那一帧或周期中为 [code]true[/code]。\n" +"[b]注意:[/b]返回 [code]true[/code] 并不意味着该动作[i]仍然[/i]处于松开状态。" +"动作在松开后是可以很快再按下的,为了不丢失输入,这种情况下仍然会返回 " +"[code]true[/code]。\n" +"如果 [param exact_match] 为 [code]false[/code],则会忽略 [InputEventKey] 和 " +"[InputEventMouseButton] 事件的额外输入修饰键,以及 [InputEventJoypadMotion] 事" +"件的方向。\n" +"[b]注意:[/b]在输入处理期间(例如 [method Node._input]),请使用 [method " +"InputEvent.is_action_released] 来查询当前事件的动作状态。" + +msgid "" "Returns [code]true[/code] if you are pressing the action event.\n" "If [param exact_match] is [code]false[/code], it ignores additional input " "modifiers for [InputEventKey] and [InputEventMouseButton] events, and the " @@ -65678,7 +66017,7 @@ msgid "" "The style of the beginning of the polyline, if [member closed] is " "[code]false[/code]. Use [enum LineCapMode] constants." msgstr "" -"[member close] 为 [code]false[/code] 时折线开头的样式。使用 [enum " +"[member closed] 为 [code]false[/code] 时的折线开头样式。使用 [enum " "LineCapMode] 常量。" msgid "" @@ -65706,7 +66045,7 @@ msgid "" "The style of the end of the polyline, if [member closed] is [code]false[/" "code]. Use [enum LineCapMode] constants." msgstr "" -"折线末端的样式,如果 [member close] 为 [code]false[/code]。使用 [enum " +"[member closed] 为 [code]false[/code] 时的折线末端样式。使用 [enum " "LineCapMode] 常量。" msgid "" @@ -74045,6 +74384,14 @@ msgstr "" "[InstancePlaceholder]。" msgid "" +"Returns the [SceneTree] that contains this node. Returns [code]null[/code] " +"and prints an error if this node is not inside the scene tree. See also " +"[method is_inside_tree]." +msgstr "" +"返回包含该节点的 [SceneTree]。如果该节点不在场景树内,则返回 [code]null[/" +"code] 并打印错误。另见 [method is_inside_tree]。" + +msgid "" "Returns the tree as a [String]. Used mainly for debugging purposes. This " "version displays the path relative to the current node, and is good for copy/" "pasting into the [method get_node] function. It also can be used in game UI/" @@ -92093,6 +92440,17 @@ msgstr "" "仅在重新启动应用程序时才会应用此设置的更改。" msgid "" +"Forces a [i]constant[/i] delay between frames in the main loop (in " +"milliseconds). In most situations, [member application/run/max_fps] should be " +"preferred as an FPS limiter as it's more precise.\n" +"This setting can be overridden using the [code]--frame-delay <ms;>[/code] " +"command line argument." +msgstr "" +"强制主循环中的帧之间有[i]恒定的[/i]延迟(以毫秒为单位)。在大多数情况下,应首" +"选 [member application/run/max_fps] 作为 FPS 限制器,因为它更精确。\n" +"可以使用 [code]--frame-delay <ms;>[/code] 命令行参数覆盖该设置。" + +msgid "" "If [code]true[/code], enables low-processor usage mode. This setting only " "works on desktop platforms. The screen is not redrawn if nothing changes " "visually. This is meant for writing applications and editors, but is pretty " @@ -100397,6 +100755,44 @@ msgstr "该矩形的宽度和高度。" msgid "Base class for reference-counted objects." msgstr "引用计数对象的基类。" +msgid "" +"Base class for any object that keeps a reference count. [Resource] and many " +"other helper objects inherit this class.\n" +"Unlike other [Object] types, [RefCounted]s keep an internal reference counter " +"so that they are automatically released when no longer in use, and only then. " +"[RefCounted]s therefore do not need to be freed manually with [method Object." +"free].\n" +"[RefCounted] instances caught in a cyclic reference will [b]not[/b] be freed " +"automatically. For example, if a node holds a reference to instance [code]A[/" +"code], which directly or indirectly holds a reference back to [code]A[/code], " +"[code]A[/code]'s reference count will be 2. Destruction of the node will " +"leave [code]A[/code] dangling with a reference count of 1, and there will be " +"a memory leak. To prevent this, one of the references in the cycle can be " +"made weak with [method @GlobalScope.weakref].\n" +"In the vast majority of use cases, instantiating and using [RefCounted]-" +"derived types is all you need to do. The methods provided in this class are " +"only for advanced users, and can cause issues if misused.\n" +"[b]Note:[/b] In C#, reference-counted objects will not be freed instantly " +"after they are no longer in use. Instead, garbage collection will run " +"periodically and will free reference-counted objects that are no longer in " +"use. This means that unused ones will linger on for a while before being " +"removed." +msgstr "" +"所有保持引用计数的对象的基类。[Resource] 和许多其他辅助对象继承该类。\n" +"与其他 [Object] 类型不同,[RefCounted] 保留一个内部引用计数器,以便它们在不再" +"使用时自动释放,并且仅在那时才会如此。因此,[RefCounted] 不需要使用 [method " +"Object.free] 手动释放。\n" +"陷入循环引用的 [RefCounted] 实例将[b]不会[/b]自动释放。例如,如果节点持有对实" +"例 [code]A[/code] 的引用,而该实例直接或间接持有对 [code]A[/code] 的引用,则 " +"[code]A[/code] 的引用计数将为 2。该节点的销毁将使 [code]A[/code] 悬空,引用计" +"数为 1,并且会出现内存泄漏。为了防止这种情况,可以使用 [method @GlobalScope." +"weakref] 将循环中的引用之一设置为弱引用。\n" +"在绝大多数用例中,只需实例化和使用 [RefCounted] 派生类型即可。该类中提供的方法" +"仅适用于高级用户,如果使用不当可能会导致问题。\n" +"[b]注意:[/b]在 C# 中,引用计数的对象在不再使用后不会立即被释放。相反,垃圾收" +"集将定期运行,并释放不再使用的引用计数对象。这意味着未使用的引用计数对象会在被" +"移除之前停留一段时间。" + msgid "Returns the current reference count." msgstr "返回当前的引用计数。" @@ -109569,6 +109965,17 @@ msgstr "3D 粒子。" msgid "Draw particles in the order that they appear in the particles array." msgstr "按照粒子数组中出现的顺序绘制粒子。" +msgid "" +"Sort particles based on their lifetime. In other words, the particle with the " +"highest lifetime is drawn at the front." +msgstr "根据粒子的寿命对其进行排序。换句话说,寿命最长的粒子被绘制在前面。" + +msgid "" +"Sort particles based on the inverse of their lifetime. In other words, the " +"particle with the lowest lifetime is drawn at the front." +msgstr "" +"根据粒子寿命的倒数对粒子进行排序。换句话说,寿命最短的粒子被绘制在前面。" + msgid "Sort particles based on their distance to the camera." msgstr "根据粒子与相机的距离对其进行排序。" @@ -113387,8 +113794,9 @@ msgstr "" "[b]注意:[/b][code]push_*/pop[/code] 函数不会影响 BBCode。\n" "[b]注意:[/b]与 [Label] 不同,[RichTextLabel] 没有使文本水平居中的[i]属性[/" "i]。请启用 [member bbcode_enabled] 并将文本包围在 [code skip-lint][center][/" -"code] 标签中,类似:[code][center]示例[/center][/code]。目前也没有垂直对齐文本" -"的内置方法,但这可以通过使用锚点/容器和 [member fit_content] 属性来模拟。" +"code] 标签中,类似:[code skip-lint][center]示例[/center][/code]。目前也没有垂" +"直对齐文本的内置方法,但这可以通过使用锚点/容器和 [member fit_content] 属性来" +"模拟。" msgid "GUI Rich Text/BBcode Demo" msgstr "GUI 富文本/BBcode 演示" @@ -117741,6 +118149,24 @@ msgstr "" msgid "Returns the pose transform of the specified bone." msgstr "返回指定骨骼的姿势变换。" +msgid "" +"Returns the pose position of the bone at [param bone_idx]. The returned " +"[Vector3] is in the local coordinate space of the [Skeleton3D] node." +msgstr "" +"返回骨骼在 [param bone_idx]处的姿势位置。返回的 [Vector3] 位于 [Skeleton3D] 节" +"点的局部坐标空间中。" + +msgid "" +"Returns the pose rotation of the bone at [param bone_idx]. The returned " +"[Quaternion] is local to the bone with respect to the rotation of any parent " +"bones." +msgstr "" +"返回 [param bone_idx] 处骨骼的姿势旋转。返回的 [Quaternion] 是局部于该骨骼的," +"且相对于任何父骨骼的旋转。" + +msgid "Returns the pose scale of the bone at [param bone_idx]." +msgstr "返回 [param bone_idx] 处骨骼的姿态缩放。" + msgid "Returns the rest transform for a bone [param bone_idx]." msgstr "返回骨骼 [param bone_idx] 的放松变换。" @@ -117838,6 +118264,25 @@ msgstr "" "-1,则该骨骼没有父级。\n" "[b]注意:[/b][param parent_idx] 必须小于 [param bone_idx]。" +msgid "" +"Sets the pose position of the bone at [param bone_idx] to [param position]. " +"[param position] is a [Vector3] describing a position local to the " +"[Skeleton3D] node." +msgstr "" +"将 [param bone_idx] 处的骨骼姿势位置设置为 [param position]。[param position] " +"是一个 [Vector3],描述局部于 [Skeleton3D] 节点的位置。" + +msgid "" +"Sets the pose rotation of the bone at [param bone_idx] to [param rotation]. " +"[param rotation] is a [Quaternion] describing a rotation in the bone's local " +"coordinate space with respect to the rotation of any parent bones." +msgstr "" +"将 [param bone_idx] 处骨骼的姿势旋转设置为 [param rotation]。[param rotation] " +"是一个 [Quaternion],描述该骨骼局部坐标空间中相对于任何父骨骼的旋转的旋转。" + +msgid "Sets the pose scale of the bone at [param bone_idx] to [param scale]." +msgstr "将 [param bone_idx] 处骨骼的姿势缩放设置为 [param scale]。" + msgid "Sets the rest transform for bone [param bone_idx]." msgstr "设置骨骼 [param bone_idx] 的放松变换。" @@ -126340,6 +126785,9 @@ msgstr "返回字体的加粗力度。" msgid "Returns bitmap font fixed size." msgstr "返回位图字体的固定大小。" +msgid "Returns bitmap font scaling mode." +msgstr "返回位图字体的缩放模式。" + msgid "Returns [code]true[/code] if font texture mipmap generation is enabled." msgstr "如果启用了字体纹理 mipmap 生成,则返回 [code]true[/code]。" @@ -132150,7 +132598,7 @@ msgid "" "equivalent to [code]t.x[/code], [code]t[1][/code] is equivalent to [code]t.y[/" "code], and [code]t[2][/code] is equivalent to [code]t.origin[/code]." msgstr "" -"使用其索引访问变换的分量。[code]t[0][/code] 相当于 [code]t.x[/code]," +"使用变换分量的索引访问变换的分量。[code]t[0][/code] 相当于 [code]t.x[/code]," "[code]t[1][/code] 相当于 [code]t.y[/code],[code]t[2][/code] 相当于 [code]t." "origin[/code]。" @@ -134187,7 +134635,7 @@ msgstr "" "始重新播放每个动画都请新建一个 Tween。请记住,Tween 是会立即开始的,所以请只在" "需要开始动画时创建 Tween。\n" "[b]注意:[/b]该补间在当前帧中的所有节点之后进行处理,即节点的 [method Node." -"_process] 方法(或 [method Node._physicals_process],具体取决于传递给 [method " +"_process] 方法(或 [method Node._physics_process],具体取决于传递给 [method " "set_process_mode] 的值)会在补间之前被调用。" msgid "" @@ -145497,7 +145945,7 @@ msgid "" "automatic scale factor determined by [member content_scale_size]." msgstr "" "决定 2D 元素最终缩放系数的策略。会影响 [member content_scale_factor] 的使用," -"与 [member display/window/stretch/mode] 决定的自动缩放系数共同生效。" +"与 [member content_scale_size] 决定的自动缩放系数共同生效。" msgid "The screen the window is currently on." msgstr "该窗口当前所在的屏幕。" diff --git a/editor/dependency_editor.h b/editor/dependency_editor.h index 0979606716..d43b12f1d2 100644 --- a/editor/dependency_editor.h +++ b/editor/dependency_editor.h @@ -68,6 +68,10 @@ public: DependencyEditor(); }; +#ifdef MINGW_ENABLED +#undef FILE_OPEN +#endif + class DependencyEditorOwners : public AcceptDialog { GDCLASS(DependencyEditorOwners, AcceptDialog); diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 3b7cce60bf..822b379091 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -233,6 +233,7 @@ void EditorResourcePicker::_update_menu_items() { } edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Save")), TTR("Save"), OBJ_MENU_SAVE); + edit_menu->add_icon_item(get_editor_theme_icon(SNAME("Save")), TTR("Save As..."), OBJ_MENU_SAVE_AS); } if (edited_resource->get_path().is_resource_file()) { @@ -400,6 +401,13 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { EditorNode::get_singleton()->save_resource(edited_resource); } break; + case OBJ_MENU_SAVE_AS: { + if (edited_resource.is_null()) { + return; + } + EditorNode::get_singleton()->save_resource_as(edited_resource); + } break; + case OBJ_MENU_COPY: { EditorSettings::get_singleton()->set_resource_clipboard(edited_resource); } break; diff --git a/editor/editor_resource_picker.h b/editor/editor_resource_picker.h index 856ef974d3..0046354861 100644 --- a/editor/editor_resource_picker.h +++ b/editor/editor_resource_picker.h @@ -72,6 +72,7 @@ class EditorResourcePicker : public HBoxContainer { OBJ_MENU_MAKE_UNIQUE, OBJ_MENU_MAKE_UNIQUE_RECURSIVE, OBJ_MENU_SAVE, + OBJ_MENU_SAVE_AS, OBJ_MENU_COPY, OBJ_MENU_PASTE, OBJ_MENU_SHOW_IN_FILE_SYSTEM, diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index 8eac5ec323..c555653732 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -367,14 +367,6 @@ void ResourceImporterTexture::_save_ctex(const Ref<Image> &p_image, const String f->store_32(0); f->store_32(0); - /* - print_line("streamable " + itos(p_streamable)); - print_line("mipmaps " + itos(p_mipmaps)); - print_line("detect_3d " + itos(p_detect_3d)); - print_line("roughness " + itos(p_detect_roughness)); - print_line("normal " + itos(p_detect_normal)); -*/ - if ((p_compress_mode == COMPRESS_LOSSLESS || p_compress_mode == COMPRESS_LOSSY) && p_image->get_format() > Image::FORMAT_RGBA8) { p_compress_mode = COMPRESS_VRAM_UNCOMPRESSED; //these can't go as lossy } diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index f6c2eb727b..4a814ea1bc 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -204,6 +204,10 @@ class EditorScriptCodeCompletionCache; class FindInFilesDialog; class FindInFilesPanel; +#ifdef MINGW_ENABLED +#undef FILE_OPEN +#endif + class ScriptEditor : public PanelContainer { GDCLASS(ScriptEditor, PanelContainer); diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h index 039afd61fe..073b0ee192 100644 --- a/editor/plugins/shader_editor_plugin.h +++ b/editor/plugins/shader_editor_plugin.h @@ -42,6 +42,10 @@ class TextShaderEditor; class VisualShaderEditor; class WindowWrapper; +#ifdef MINGW_ENABLED +#undef FILE_OPEN +#endif + class ShaderEditorPlugin : public EditorPlugin { GDCLASS(ShaderEditorPlugin, EditorPlugin); diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 07a73b4e51..c4ee654b25 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -260,6 +260,10 @@ class VisualShaderEditor : public VBoxContainer { COLLAPSE_ALL }; +#ifdef MINGW_ENABLED +#undef DELETE +#endif + enum NodeMenuOptions { ADD, SEPARATOR, // ignore diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 40c482eb90..ed01187947 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -727,9 +727,12 @@ void ProjectDialog::show_dialog() { project_path->set_text(d->get_current_dir()); fdialog->set_current_dir(d->get_current_dir()); } - String proj = TTR("New Game Project"); - project_name->set_text(proj); - _text_changed(proj); + + if (project_name->get_text().is_empty()) { + String proj = TTR("New Game Project"); + project_name->set_text(proj); + _text_changed(proj); + } project_path->set_editable(true); browse->set_disabled(false); diff --git a/editor/translations/editor/ar.po b/editor/translations/editor/ar.po index bbb11988e1..4d63f5ed0b 100644 --- a/editor/translations/editor/ar.po +++ b/editor/translations/editor/ar.po @@ -4083,6 +4083,9 @@ msgstr "اجعلْه فريدًا" msgid "Make Unique (Recursive)" msgstr "اجعلْه فريدا (متكرر)" +msgid "Save As..." +msgstr "حفظ بنوع..." + msgid "Show in FileSystem" msgstr "أظهر في نظام الملفات" @@ -5969,9 +5972,6 @@ msgstr "تحميل مورد موجود مسبقا من الذاكرة وتعدي msgid "Save the currently edited resource." msgstr "حفظ المورد الذي يتم تعديله حاليا." -msgid "Save As..." -msgstr "حفظ بنوع..." - msgid "Extra resource options." msgstr "أختيارات اضافية للمورد." diff --git a/editor/translations/editor/bg.po b/editor/translations/editor/bg.po index 1597a4f768..1ec4b77c84 100644 --- a/editor/translations/editor/bg.po +++ b/editor/translations/editor/bg.po @@ -1922,6 +1922,9 @@ msgstr "Размер:" msgid "New Value:" msgstr "Нова стойност:" +msgid "Save As..." +msgstr "Запазване като..." + msgid "Show in FileSystem" msgstr "Показване във файловата система" @@ -2544,9 +2547,6 @@ msgstr "Поставяне на свойствата" msgid "Save the currently edited resource." msgstr "Запазване на текущо редактирания ресурс." -msgid "Save As..." -msgstr "Запазване като..." - msgid "Extra resource options." msgstr "Допълнителни настройки на ресурса." diff --git a/editor/translations/editor/ca.po b/editor/translations/editor/ca.po index 18d23f865a..80b3779866 100644 --- a/editor/translations/editor/ca.po +++ b/editor/translations/editor/ca.po @@ -2722,6 +2722,9 @@ msgstr "Carrega Rapida" msgid "Make Unique" msgstr "Fes-lo Únic" +msgid "Save As..." +msgstr "Anomena i Desa..." + msgid "Show in FileSystem" msgstr "Mostrar en el Sistema de Fitxers" @@ -3426,9 +3429,6 @@ msgstr "Carrega un recurs des del disc i edita'l." msgid "Save the currently edited resource." msgstr "Desa el recurs editat ara." -msgid "Save As..." -msgstr "Anomena i Desa..." - msgid "Copy Resource" msgstr "Copia el Recurs" diff --git a/editor/translations/editor/cs.po b/editor/translations/editor/cs.po index e173708ee0..7a82bceae1 100644 --- a/editor/translations/editor/cs.po +++ b/editor/translations/editor/cs.po @@ -2802,6 +2802,9 @@ msgstr "Rychlé načtení" msgid "Make Unique" msgstr "Vytvořit unikátní" +msgid "Save As..." +msgstr "Uložit jako..." + msgid "Show in FileSystem" msgstr "Zobrazit v souborovém systému" @@ -3719,9 +3722,6 @@ msgstr "Nahrát existující zdroj z disku a editovat ho." msgid "Save the currently edited resource." msgstr "Uložit právě editovaný zdroj." -msgid "Save As..." -msgstr "Uložit jako..." - msgid "Extra resource options." msgstr "Další možnosti zdrojů." diff --git a/editor/translations/editor/de.po b/editor/translations/editor/de.po index da9315ee15..b3d2b793d8 100644 --- a/editor/translations/editor/de.po +++ b/editor/translations/editor/de.po @@ -113,7 +113,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor interface\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2023-11-11 00:20+0000\n" +"PO-Revision-Date: 2023-11-20 14:00+0000\n" "Last-Translator: Cerno_b <cerno.b@gmail.com>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/godot/" "de/>\n" @@ -122,7 +122,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.2-dev\n" +"X-Generator: Weblate 5.2\n" msgid "Main Thread" msgstr "Hauptthread" @@ -2005,6 +2005,9 @@ msgstr "Entwickler" msgid "Authors" msgstr "Autoren" +msgid "Patrons" +msgstr "Förderer" + msgid "Platinum Sponsors" msgstr "Platin-Sponsoren" @@ -2014,6 +2017,18 @@ msgstr "Gold-Sponsoren" msgid "Silver Sponsors" msgstr "Silber-Sponsoren" +msgid "Diamond Members" +msgstr "Diamant-Mitglieder" + +msgid "Titanium Members" +msgstr "Titan-Mitglieder" + +msgid "Platinum Members" +msgstr "Platin-Mitglieder" + +msgid "Gold Members" +msgstr "Gold-Mitglieder" + msgid "Donors" msgstr "Unterstützer" @@ -4156,6 +4171,9 @@ msgstr "Einzigartig machen" msgid "Make Unique (Recursive)" msgstr "Einzigartig machen (rekursiv)" +msgid "Save As..." +msgstr "Speichern als …" + msgid "Show in FileSystem" msgstr "Im Dateisystem anzeigen" @@ -4301,7 +4319,7 @@ msgid "Joystick 4 Down" msgstr "Joystick 4 runter" msgid "or" -msgstr "oder" +msgstr "or" msgid "Unicode" msgstr "Unicode" @@ -6094,9 +6112,6 @@ msgstr "Lade eine bestehende Ressource von der Festplatte und bearbeite sie." msgid "Save the currently edited resource." msgstr "Speichere die so eben bearbeitete Ressource." -msgid "Save As..." -msgstr "Speichern als …" - msgid "Extra resource options." msgstr "Zusatz-Ressourcenoptionen." @@ -6249,7 +6264,7 @@ msgid "" msgstr "" "Optional. diese Beschreibung sollte relativ kurz gehalten werden (bis zu 5 " "Zeilen).\n" -"Sie wird angezeigt wenn der Mauscursor in der Liste der Plugins über dem " +"Sie wird angezeigt, wenn der Mauszeiger in der Liste der Plugins über dem " "Plugin schwebt." msgid "Author:" @@ -6550,14 +6565,14 @@ msgid "" "This animation library can't be saved because it does not belong to the " "edited scene. Make it unique first." msgstr "" -"Diese Animationsbibliothek kann nicht gespeichert werden da sie nicht zur " +"Diese Animationsbibliothek kann nicht gespeichert werden, da sie nicht zur " "bearbeiteten Szene gehört. Sie muss erst einzigartig gemacht werden." msgid "" "This animation library can't be saved because it was imported from another " "file. Make it unique first." msgstr "" -"Diese Animationsbibliothek kann nicht gespeichert werden da sie aus einer " +"Diese Animationsbibliothek kann nicht gespeichert werden, da sie aus einer " "anderen Datei importiert wurde. Sie muss erst einzigartig gemacht werden." msgid "Save Library" @@ -6570,14 +6585,14 @@ msgid "" "This animation can't be saved because it does not belong to the edited scene. " "Make it unique first." msgstr "" -"Diese Animation kann nicht gespeichert werden da sie nicht zur bearbeiteten " +"Diese Animation kann nicht gespeichert werden, da sie nicht zur bearbeiteten " "Szene gehört. Sie muss erst einzigartig gemacht werden." msgid "" "This animation can't be saved because it was imported from another file. Make " "it unique first." msgstr "" -"Diese Animation kann nicht gespeichert werden da sie aus einer anderen Datei " +"Diese Animation kann nicht gespeichert werden, da sie aus einer anderen Datei " "importiert wurde. Sie muss erst einzigartig gemacht werden." msgid "Save Animation" @@ -11088,7 +11103,7 @@ msgid "Scattering:" msgstr "Streuung:" msgid "Tiles" -msgstr "Kacheln" +msgstr "Tiles" msgid "" "This TileMap's TileSet has no source configured. Go to the TileSet bottom tab " @@ -11469,7 +11484,7 @@ msgid "" "to reference an invalid source instead. This may result in unexpected data " "loss. Change this ID carefully." msgstr "" -"Achtung: Die Änderung einer Quellen-ID wird dazu führen, dass alle TileMaps, " +"Warnung: Die Änderung einer Quellen-ID wird dazu führen, dass alle TileMaps, " "die diese Quelle benutzen, stattdessen eine Referenz auf eine ungültige " "Quelle haben. Dies könnte zu unerwartetem Datenverlust führen. Ändern Sie " "diese ID mit Bedacht." @@ -15119,9 +15134,17 @@ msgstr "Konnte Expansion-Package-Datei nicht schreiben!" msgid "Building Android Project (gradle)" msgstr "Baue Android-Projekt (gradle)" +msgid "Building of Android project failed, check output for the error:" +msgstr "" +"Das Erstellen des Android-Projekts ist fehlgeschlagen, prüfen Sie die Ausgabe " +"auf den Fehler:" + msgid "Moving output" msgstr "Verschiebe Ausgabe" +msgid "Unable to copy and rename export file:" +msgstr "Exportdatei kann nicht kopiert und umbenannt werden:" + msgid "Package not found: \"%s\"." msgstr "Paket nicht gefunden: „%s“." diff --git a/editor/translations/editor/el.po b/editor/translations/editor/el.po index 880fbd205c..3b3a15e751 100644 --- a/editor/translations/editor/el.po +++ b/editor/translations/editor/el.po @@ -2422,6 +2422,9 @@ msgstr "" msgid "Make Unique" msgstr "Κάνε μοναδικό" +msgid "Save As..." +msgstr "Αποθήκευση ως..." + msgid "Show in FileSystem" msgstr "Εμφάνιση στο Σύστημα Αρχείων" @@ -3114,9 +3117,6 @@ msgstr "Φόρτωσε υπάρχων πόρο στη μνήμη και επεξ msgid "Save the currently edited resource." msgstr "Αποθήκευσε το τρέχων επεξεργαζόμενο πόρο." -msgid "Save As..." -msgstr "Αποθήκευση ως..." - msgid "Copy Resource" msgstr "Αντιγραφή πόρου" diff --git a/editor/translations/editor/eo.po b/editor/translations/editor/eo.po index a55b9bc46f..91b351995e 100644 --- a/editor/translations/editor/eo.po +++ b/editor/translations/editor/eo.po @@ -2118,6 +2118,9 @@ msgstr "" msgid "Make Unique" msgstr "Farigi unikan" +msgid "Save As..." +msgstr "Konservi kiel..." + msgid "Show in FileSystem" msgstr "Montri en dosiersistemo" @@ -2692,9 +2695,6 @@ msgstr "Ŝargi ekzistantan risurcon el disko kaj redakti ĝin." msgid "Save the currently edited resource." msgstr "Konservi la aktuale redaktantan risurcon." -msgid "Save As..." -msgstr "Konservi kiel..." - msgid "Copy Resource" msgstr "Kopii risurcon" diff --git a/editor/translations/editor/es.po b/editor/translations/editor/es.po index e89dfa2e71..c4d7da3887 100644 --- a/editor/translations/editor/es.po +++ b/editor/translations/editor/es.po @@ -4151,6 +4151,9 @@ msgstr "Hacer Único" msgid "Make Unique (Recursive)" msgstr "Hacer Único (Recursivo)" +msgid "Save As..." +msgstr "Guardar como..." + msgid "Show in FileSystem" msgstr "Mostrar en Sistema de Archivos" @@ -6060,9 +6063,6 @@ msgstr "Cargar un recurso existente desde disco y editarlo." msgid "Save the currently edited resource." msgstr "Guardar el recurso editado actualmente." -msgid "Save As..." -msgstr "Guardar como..." - msgid "Extra resource options." msgstr "Opciones de recursos extra." diff --git a/editor/translations/editor/es_AR.po b/editor/translations/editor/es_AR.po index 2c3e8cfe56..856636c088 100644 --- a/editor/translations/editor/es_AR.po +++ b/editor/translations/editor/es_AR.po @@ -2366,6 +2366,9 @@ msgstr "Carga Rápida" msgid "Make Unique" msgstr "Convertir en Unico" +msgid "Save As..." +msgstr "Guardar Como..." + msgid "Show in FileSystem" msgstr "Mostrar en Sistema de Archivos" @@ -3224,9 +3227,6 @@ msgstr "Cargar un recurso existente desde disco y editarlo." msgid "Save the currently edited resource." msgstr "Guardar el recurso editado actualmente." -msgid "Save As..." -msgstr "Guardar Como..." - msgid "Extra resource options." msgstr "Opciones de recursos extra." diff --git a/editor/translations/editor/et.po b/editor/translations/editor/et.po index fe7e2b1fc9..0b223b906d 100644 --- a/editor/translations/editor/et.po +++ b/editor/translations/editor/et.po @@ -2829,6 +2829,9 @@ msgstr "Tee Unikaalseks" msgid "Make Unique (Recursive)" msgstr "Tee Unikaalseks (Rekursiivselt)" +msgid "Save As..." +msgstr "Salvesta kui..." + msgid "Show in FileSystem" msgstr "Kuva failisüsteemis" @@ -4429,9 +4432,6 @@ msgstr "Lae olemasolev resurss kettalt ning redigeeri seda." msgid "Save the currently edited resource." msgstr "Salvesta käesolevalt muudetud ressurss." -msgid "Save As..." -msgstr "Salvesta kui..." - msgid "Extra resource options." msgstr "Ekstra resursi valikud." diff --git a/editor/translations/editor/fa.po b/editor/translations/editor/fa.po index c1529dbe55..8d3a609f6e 100644 --- a/editor/translations/editor/fa.po +++ b/editor/translations/editor/fa.po @@ -48,7 +48,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor interface\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2023-11-16 07:52+0000\n" +"PO-Revision-Date: 2023-11-18 06:21+0000\n" "Last-Translator: theBSH <bloodshot1387@hotmail.com>\n" "Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/" "godot/fa/>\n" @@ -1429,6 +1429,9 @@ msgstr "کپی نام" msgid "Edit..." msgstr "ویرایش..." +msgid "Go to Method" +msgstr "برو به متد" + msgid "Change Type of \"%s\"" msgstr "تغییر نوع \"%s\"" @@ -1915,6 +1918,9 @@ msgstr "توسعه دهندگان" msgid "Authors" msgstr "مؤلفان" +msgid "Patrons" +msgstr "حامی" + msgid "Platinum Sponsors" msgstr "حامیان پلاتینیومی" @@ -1924,6 +1930,18 @@ msgstr "حامیان طلایی" msgid "Silver Sponsors" msgstr "حامیان نقره ای" +msgid "Diamond Members" +msgstr "اعضای الماسی" + +msgid "Titanium Members" +msgstr "اعضای تیتانیومی" + +msgid "Platinum Members" +msgstr "اعضای پلاتینیومی" + +msgid "Gold Members" +msgstr "اعضای طلایی" + msgid "Donors" msgstr "اهدا کنندگان" @@ -1959,8 +1977,22 @@ msgstr "خطا در گشودن پروندهٔ دارایی برای «%s» (در msgid "%s (already exists)" msgstr "\"%s\" (در حال حاضر موجود است)" +msgid "%d file conflicts with your project and won't be installed" +msgid_plural "%d files conflict with your project and won't be installed" +msgstr[0] "فایل %d با پروژه شما در مغایرت است و نصب نمی شود" +msgstr[1] "فایل های %d با پروژه شما در مغایرت است و نصب نمی شود" + +msgid "This asset doesn't have a root directory, so it can't be ignored." +msgstr "این Asset یک مسیر Root ندارد پس نمیتوان آن را نادیده گرفت." + +msgid "Ignore the root directory when extracting files." +msgstr "هنگام استخراج فایل ها مسیر Root را نادیده بگیر." + +msgid "Select Install Folder" +msgstr "پوشه نصب را انتخاب کنید" + msgid "Uncompressing Assets" -msgstr "استخراج داراییها" +msgstr "استخراج Asset ها" msgid "The following files failed extraction from asset \"%s\":" msgstr "استخراج پروندههای زیر از دارایی «%s» شکست خورد:" @@ -1969,11 +2001,42 @@ msgid "(and %s more files)" msgstr "(و %s دیگر فایل ها)" msgid "Asset \"%s\" installed successfully!" -msgstr "دارایی «%s» با موفقیت نصب شد!" +msgstr "Asset ه \"%s\" با موفقیت نصب شد!" msgid "Success!" msgstr "موفقیت!" +msgid "Asset:" +msgstr "Asset:" + +msgid "Open the list of the asset contents and select which files to install." +msgstr "باز کردنه لیست محتوا Asset ها و انتخاب فایل ها را برای نصب." + +msgid "Change Install Folder" +msgstr "تغییر پوشه نصب" + +msgid "" +"Change the folder where the contents of the asset are going to be installed." +msgstr "تغییر پوشه ای که محتوای Asset در آن نصب خواهد شد." + +msgid "Ignore asset root" +msgstr "نادیده گرفتن Root ه Asset" + +msgid "No files conflict with your project" +msgstr "هیچ فایلی با پروژه شما در مغایرت نیست" + +msgid "Show contents of the asset and conflicting files." +msgstr "نشان دادن محتوای Asset و فایل های در مغایرت." + +msgid "Contents of the asset:" +msgstr "محتوای Asset:" + +msgid "Installation preview:" +msgstr "پیشنمایش نصب:" + +msgid "Configure Asset Before Installing" +msgstr "تنظیم کردن Asset قبل از نصب کردن" + msgid "Install" msgstr "نصب کردن" @@ -2025,6 +2088,12 @@ msgstr "گذرگاه فرعی" msgid "Bus Options" msgstr "گزینه های اتوبوس" +msgid "Duplicate Bus" +msgstr "تکثیر کردن Bus" + +msgid "Delete Bus" +msgstr "حذف Bus" + msgid "Reset Volume" msgstr "بازنشانی حجم" @@ -2032,34 +2101,37 @@ msgid "Delete Effect" msgstr "حذف جلوه" msgid "Add Audio Bus" -msgstr "افزودن گذرگاه صدا" +msgstr "افزودن Bus صدا" msgid "Master bus can't be deleted!" -msgstr "گذرگاه اصلی قابل حذف نیست!" +msgstr "Bus اصلی قابل حذف نیست!" msgid "Delete Audio Bus" -msgstr "حذف گذرگاه صدا" +msgstr "حذف Bus صدا" msgid "Duplicate Audio Bus" -msgstr "تکثیر صدای خطی" +msgstr "تکثیر Bus صدا" msgid "Reset Bus Volume" -msgstr "بازنشانی مقدار خطی" +msgstr "بازنشانی مقدار Bus" msgid "Move Audio Bus" -msgstr "انتقال صدای خطی" +msgstr "انتقال Bus صدا" msgid "Save Audio Bus Layout As..." -msgstr "ذخیره طرح اتوبوس صوتی به عنوان ..." +msgstr "ذخیره چیدمان Bus صوتی به عنوان ..." msgid "Location for New Layout..." -msgstr "مکان برای طرح جدید ..." +msgstr "مکان برای چیدمان جدید ..." msgid "Open Audio Bus Layout" -msgstr "چیدمان اتوبوس صوتی را باز کنید" +msgstr "بار کردن چیدمان Bus صوتی" msgid "There is no '%s' file." -msgstr "پرونده '٪ s' وجود ندارد." +msgstr "فایل '%s' وجود ندارد." + +msgid "Layout:" +msgstr "چیدمان:" msgid "Invalid file, not an audio bus layout." msgstr "پرونده نامعتبر است ، نه طرح اتوبوس صوتی." @@ -2094,6 +2166,9 @@ msgstr "طرح پیش فرض اتوبوس را بارگیری کنید." msgid "Create a new Bus Layout." msgstr "طرح جدید اتوبوس ایجاد کنید." +msgid "Audio Bus Layout" +msgstr "چیدمان Bus صوتی" + msgid "Invalid name." msgstr "نام نامعتبر." @@ -2106,36 +2181,51 @@ msgstr "کاراکترهای معتبر:" msgid "Must not collide with an existing engine class name." msgstr "نباید با یک نام کلاس موتور موجود برخورد کند." +msgid "Must not collide with an existing global script class name." +msgstr "نباید با نام یک کلاس سراسری موجود برخوردی کند." + msgid "Must not collide with an existing built-in type name." msgstr "نباید با یک نام نوع درون-ساز موجود برخورد کند." msgid "Must not collide with an existing global constant name." msgstr "نباید با نام یک ثابت سراسری موجود برخوردی کند." +msgid "Keyword cannot be used as an Autoload name." +msgstr "کلمه کلیدی نمی تواند به عنوان یک نام خودبارگیر بکار برده شود." + msgid "Autoload '%s' already exists!" msgstr "بارگذاری خودکار '%s' هم اکنون موجود است!" msgid "Rename Autoload" msgstr "بارگذاری خودکار را تغییر نام بده" +msgid "Toggle Autoload Globals" +msgstr "تغییر خودبارگیری متغیر های عمومی" + msgid "Move Autoload" -msgstr "بارگیری خودکار را انجام دهید" +msgstr "انتقال بارگیری خودکار" msgid "Remove Autoload" -msgstr "بارگیری خودکار را حذف کنید" +msgstr "حذف بارگیری خودکار" msgid "Enable" -msgstr "روشن کردن" +msgstr "فعال کردن" msgid "Rearrange Autoloads" msgstr "تنظیم مجدد بارهای خودکار" +msgid "Can't add Autoload:" +msgstr "اضافه کردن بارگیری خودکار امکان پذیر نیست:" + msgid "%s is an invalid path. File does not exist." msgstr "%s یک مسیر نامعتبر است. فایل موجود نمیباشد." msgid "%s is an invalid path. Not in resource path (res://)." msgstr "%s یک مسیر نامعتبر است. در مسیر منبع نیست (//:res)." +msgid "Add Autoload" +msgstr "افزودن بارگیری خودکار" + msgid "Path:" msgstr "مسیر:" @@ -2163,8 +2253,35 @@ msgstr "جهتیابی" msgid "XR" msgstr "اکسآر" +msgid "RenderingDevice" +msgstr "دستگاه Render" + +msgid "OpenGL" +msgstr "OpenGL" + msgid "Vulkan" -msgstr "وولکان" +msgstr "Vulkan" + +msgid "Text Server: Fallback" +msgstr "سرویس دهنده متن: Fallback" + +msgid "Text Server: Advanced" +msgstr "سرویس دهنده متن: پیشرفته" + +msgid "TTF, OTF, Type 1, WOFF1 Fonts" +msgstr "فونت های TTF, OTF, Type 1, WOFF1" + +msgid "WOFF2 Fonts" +msgstr "فونت های WOFF2" + +msgid "SIL Graphite Fonts" +msgstr "فونت های گرافیکی SIL" + +msgid "Multi-channel Signed Distance Field Font Rendering" +msgstr "Render فونت میدان فاصله امضا شده چند کاناله" + +msgid "3D Nodes as well as RenderingServer access to 3D features." +msgstr "دسترسی گرههای ۳بعدی و همین طور سرویس دهنده Render به قابلیت های ۳بعدی." msgid "2D Physics nodes and PhysicsServer2D." msgstr "گرههای دوبعدی فیزیک و PhysicsServer2D." @@ -3124,6 +3241,9 @@ msgstr "دیکشنری (اندازه %d)" msgid "Quick Load" msgstr "بارگذاری سریع" +msgid "Save As..." +msgstr "ذخیره در..." + msgid "Show in FileSystem" msgstr "نمایش در فایلسیستم" @@ -3808,9 +3928,6 @@ msgstr "یک منبع جدید در حافظه بساز و آن را ویرای msgid "Load an existing resource from disk and edit it." msgstr "بارگذاری یک منبع موجود از دیسک و ویرایش آن." -msgid "Save As..." -msgstr "ذخیره در..." - msgid "Copy Resource" msgstr "کپی منبع" @@ -4389,6 +4506,9 @@ msgstr "اندازه سلول: %s" msgid "Video RAM size: %s MB (%s)" msgstr "اندازه ویدئو رم: %s مگابایت ( %s)" +msgid "Configure" +msgstr "تنظیم کردن" + msgid "Create Outline" msgstr "ساخت طرح کلی" diff --git a/editor/translations/editor/fi.po b/editor/translations/editor/fi.po index 747f1e096a..4b31ba3690 100644 --- a/editor/translations/editor/fi.po +++ b/editor/translations/editor/fi.po @@ -3743,6 +3743,9 @@ msgstr "Tee yksilölliseksi" msgid "Make Unique (Recursive)" msgstr "Tee yksilölliseksi (Rekursiivisesti)" +msgid "Save As..." +msgstr "Tallenna nimellä..." + msgid "Show in FileSystem" msgstr "Näytä tiedostojärjestelmässä" @@ -5149,9 +5152,6 @@ msgstr "Lataa olemassaoleva resurssi levyltä ja muokkaa sitä." msgid "Save the currently edited resource." msgstr "Tallenna tällä hetkellä muokattu resurssi." -msgid "Save As..." -msgstr "Tallenna nimellä..." - msgid "Extra resource options." msgstr "Ylimääräiset resurssivalinnat." diff --git a/editor/translations/editor/fr.po b/editor/translations/editor/fr.po index 45df12b19d..72fd83c550 100644 --- a/editor/translations/editor/fr.po +++ b/editor/translations/editor/fr.po @@ -160,8 +160,8 @@ msgstr "" "Project-Id-Version: Godot Engine editor interface\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2023-11-16 07:52+0000\n" -"Last-Translator: Clément <clement.vaugoyeau@gmail.com>\n" +"PO-Revision-Date: 2023-11-18 06:21+0000\n" +"Last-Translator: Roskai <angel.du.2558@gmail.com>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/godot/" "fr/>\n" "Language: fr\n" @@ -713,6 +713,15 @@ msgstr "Changer l’appel d'animation" msgid "Animation Multi Change Transition" msgstr "Changements multiple d'animations de Transition" +msgid "Animation Multi Change Position3D" +msgstr "Changements multiple d'animations de Position3D" + +msgid "Animation Multi Change Rotation3D" +msgstr "Changements multiple d'animations de Rotation3D" + +msgid "Animation Multi Change Scale3D" +msgstr "Changements multiple d'animations de Scale3D" + msgid "Animation Multi Change Keyframe Value" msgstr "Changer la valeur de plusieurs images clés d’animation" @@ -2047,6 +2056,9 @@ msgstr "Développeurs" msgid "Authors" msgstr "Auteurs" +msgid "Patrons" +msgstr "Modèles" + msgid "Platinum Sponsors" msgstr "Sponsors Platine" @@ -2056,6 +2068,18 @@ msgstr "Sponsors Or" msgid "Silver Sponsors" msgstr "Sponsors Argent" +msgid "Diamond Members" +msgstr "Membres Diamant" + +msgid "Titanium Members" +msgstr "Membres Titane" + +msgid "Platinum Members" +msgstr "Membres Platine" + +msgid "Gold Members" +msgstr "Membres Or" + msgid "Donors" msgstr "Donateurs" @@ -4106,6 +4130,12 @@ msgstr "" msgid "Assign..." msgstr "Assigner..." +msgid "Copy as Text" +msgstr "Copier en tant que texte" + +msgid "Show Node in Tree" +msgstr "Afficher le nœud dans l'arbre" + msgid "Invalid RID" msgstr "RID invalide" @@ -4195,6 +4225,9 @@ msgstr "Rendre unique" msgid "Make Unique (Recursive)" msgstr "Rendre unique (récursivement)" +msgid "Save As..." +msgstr "Enregistrer sous…" + msgid "Show in FileSystem" msgstr "Montrer dans le système de fichiers" @@ -6129,9 +6162,6 @@ msgstr "Charger une ressource existante depuis la disque et la modifier." msgid "Save the currently edited resource." msgstr "Enregistrer la ressource en cours d'édition." -msgid "Save As..." -msgstr "Enregistrer sous…" - msgid "Extra resource options." msgstr "Options de ressource additionnelles." @@ -14530,9 +14560,16 @@ msgstr "Impossible d'écrire le fichier du paquet d'expansion !" msgid "Building Android Project (gradle)" msgstr "Construire le Project Android (gradle)" +msgid "Building of Android project failed, check output for the error:" +msgstr "" +"La construction du projet Android a échoué, vérifier la sortie pour l'erreur :" + msgid "Moving output" msgstr "Déplacement du résultat" +msgid "Unable to copy and rename export file:" +msgstr "Impossible de copier et de renommer le fichier d'export :" + msgid "Package not found: \"%s\"." msgstr "Paquet non trouvé : \"%s\"." @@ -15387,12 +15424,50 @@ msgstr "" "Les volumes de brouillard sont seulement visible quand le moteur de rendu " "Forward+ est utilisé." +msgid "" +"Fog Volumes need volumetric fog to be enabled in the scene's Environment in " +"order to be visible." +msgstr "" +"Pour être visibles, les volumes de brouillard doivent être activés dans " +"l'environnement de la scène." + msgid "Nothing is visible because meshes have not been assigned to draw passes." msgstr "" "Rien n'est visible car les maillages n'ont pas été assignés au tirage des " "passes." msgid "" +"Using Trail meshes with a skin causes Skin to override Trail poses. Suggest " +"removing the Skin." +msgstr "" +"L'utilisation de Trail meshes avec un skin fait que le Skin prévaut sur les " +"Trail poses. Il est suggéré de supprimer le skin." + +msgid "Trails active, but neither Trail meshes or a Skin were found." +msgstr "Trails actifs, mais aucune maille de Trail ou Skin n'a été trouvée." + +msgid "" +"Only one Trail mesh is supported. If you want to use more than a single mesh, " +"a Skin is needed (see documentation)." +msgstr "" +"Une seule mesh Trail est prise en charge. Si vous souhaitez utiliser plus " +"d'une maille, un Skin est nécessaire (voir la documentation)." + +msgid "" +"Trails enabled, but one or more mesh materials are either missing or not set " +"for trails rendering." +msgstr "" +"Trails activés, mais un ou plusieurs matériaux de mesh sont soit manquants, " +"soit non définis pour le rendu des trails." + +msgid "" +"Particle sub-emitters are only available when using the Forward+ or Mobile " +"rendering backends." +msgstr "" +"Les sous-émetteurs de particules ne sont disponibles que lors de " +"l'utilisation des backends de rendu Forward+ ou Mobile." + +msgid "" "The Bake Mask has no bits enabled, which means baking will not produce any " "collision for this GPUParticlesCollisionSDF3D.\n" "To resolve this, enable at least one bit in the Bake Mask property." @@ -15402,6 +15477,9 @@ msgstr "" "Pour résoudre ce problème, activer au moins un bit dans la propriété du " "masque de précalcul." +msgid "A light's scale does not affect the visual size of the light." +msgstr "L'échelle d'un feu n'affecte pas la taille visuelle du feu." + msgid "Projector texture only works with shadows active." msgstr "La texture du projecteur fonctionne uniquement avec les ombres actives." @@ -15457,6 +15535,18 @@ msgstr "" "de fin pour être utile." msgid "" +"Occlusion culling is disabled in the Project Settings, which means occlusion " +"culling won't be performed in the root viewport.\n" +"To resolve this, open the Project Settings and enable Rendering > Occlusion " +"Culling > Use Occlusion Culling." +msgstr "" +"L'élagage de l'occlusion est désactivé dans les paramètres du projet, ce qui " +"signifie que l'élagage de l'occlusion ne sera pas effectué dans la fenêtre " +"racine.\n" +"Pour résoudre ce problème, ouvrez les paramètres du projet et activez les " +"options Rendu > Élagage de l'occlusion > Utiliser l'élagage de l'occlusion." + +msgid "" "The Bake Mask has no bits enabled, which means baking will not produce any " "occluder meshes for this OccluderInstance3D.\n" "To resolve this, enable at least one bit in the Bake Mask property." @@ -15467,6 +15557,21 @@ msgstr "" "masque de précalcul." msgid "" +"No occluder mesh is defined in the Occluder property, so no occlusion culling " +"will be performed using this OccluderInstance3D.\n" +"To resolve this, set the Occluder property to one of the primitive occluder " +"types or bake the scene meshes by selecting the OccluderInstance3D and " +"pressing the Bake Occluders button at the top of the 3D editor viewport." +msgstr "" +"Aucun maillage d'occlusion n'est défini dans la propriété Occluder, de sorte " +"qu'aucun filtrage d'occlusion ne sera effectué à l'aide de cette " +"OccluderInstance3D.\n" +"Pour résoudre ce problème, définissez la propriété Occluder sur l'un des " +"types d'occluder primitifs ou faites cuire les maillages de la scène en " +"sélectionnant l'OccluderInstance3D et en appuyant sur le bouton Calculer les " +"occluders en haut de la fenêtre de l'éditeur 3D." + +msgid "" "This node cannot interact with other objects unless a Shape3D is assigned." msgstr "" "Ce nœud ne peut pas interagir avec d'autres objets, sauf si une Shape3D est " diff --git a/editor/translations/editor/gl.po b/editor/translations/editor/gl.po index f369f416ae..2b8c68acf3 100644 --- a/editor/translations/editor/gl.po +++ b/editor/translations/editor/gl.po @@ -2739,6 +2739,9 @@ msgstr "" msgid "Make Unique" msgstr "Facer Único" +msgid "Save As..." +msgstr "Gardar Como..." + msgid "Show in FileSystem" msgstr "Amosar no Sistema de Arquivos" @@ -3244,9 +3247,6 @@ msgstr "Fallou a carga do Recurso." msgid "Raw" msgstr "Sen Procesar (Raw)" -msgid "Save As..." -msgstr "Gardar Como..." - msgid "Copy Resource" msgstr "Copiar Recurso" diff --git a/editor/translations/editor/he.po b/editor/translations/editor/he.po index 1bd9377e06..b6ce679883 100644 --- a/editor/translations/editor/he.po +++ b/editor/translations/editor/he.po @@ -2185,6 +2185,9 @@ msgstr "מחרוזת ניתנת לתרגום (גודל %d)" msgid "Make Unique" msgstr "הפוך לייחודי" +msgid "Save As..." +msgstr "שמירה בשם…" + msgid "Show in FileSystem" msgstr "הצגה בחלון הקבצים" @@ -2652,9 +2655,6 @@ msgstr "טעינת משאב קיים מהכונן ועריכתו." msgid "Save the currently edited resource." msgstr "שמירת המשאב שנערך כרגע." -msgid "Save As..." -msgstr "שמירה בשם…" - msgid "Copy Resource" msgstr "העתקת משאב" diff --git a/editor/translations/editor/hu.po b/editor/translations/editor/hu.po index e3ba688a0b..87c89bb544 100644 --- a/editor/translations/editor/hu.po +++ b/editor/translations/editor/hu.po @@ -2191,6 +2191,9 @@ msgstr "Kulcs/érték pár hozzáadása" msgid "Make Unique" msgstr "Egyedivé tétel" +msgid "Save As..." +msgstr "Mentés Másként..." + msgid "Show in FileSystem" msgstr "Megjelenítés a fájlrendszerben" @@ -2703,9 +2706,6 @@ msgstr "Meglévő erőforrás betöltése a lemezről, majd annak szerkesztése. msgid "Save the currently edited resource." msgstr "A jelenleg szerkesztett erőforrás elmentése." -msgid "Save As..." -msgstr "Mentés Másként..." - msgid "Copy Resource" msgstr "Erőforrás Másolása" diff --git a/editor/translations/editor/id.po b/editor/translations/editor/id.po index 46e4317551..934926bb1c 100644 --- a/editor/translations/editor/id.po +++ b/editor/translations/editor/id.po @@ -12,7 +12,7 @@ # Reza Hidayat Bayu Prabowo <rh.bayu.prabowo@gmail.com>, 2018, 2019. # Romi Kusuma Bakti <romikusumab@gmail.com>, 2017, 2018, 2021. # Sofyan Sugianto <sofyanartem@gmail.com>, 2017-2018, 2019, 2020, 2021. -# Tito <ijavadroid@gmail.com>, 2018. +# Tito <ijavadroid@gmail.com>, 2018, 2023. # Tom My <tom.asadinawan@gmail.com>, 2017. # yursan9 <rizal.sagi@gmail.com>, 2016. # Evan Hyacinth <muhammad.ivan669@gmail.com>, 2018, 2019. @@ -55,13 +55,14 @@ # Bayu Satiyo <itsyuukunz@gmail.com>, 2023. # Avirur Rahman <avirahmandev@gmail.com>, 2023. # Nazan <121859424+nazhard@users.noreply.github.com>, 2023. +# ekaknl22 <2200018407@webmail.uad.ac.id>, 2023. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor interface\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2023-11-15 10:05+0000\n" -"Last-Translator: Nazan <121859424+nazhard@users.noreply.github.com>\n" +"PO-Revision-Date: 2023-11-21 15:04+0000\n" +"Last-Translator: Tito <ijavadroid@gmail.com>\n" "Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/" "godot/id/>\n" "Language: id\n" @@ -69,7 +70,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.2-dev\n" +"X-Generator: Weblate 5.2\n" msgid "Main Thread" msgstr "Utas Utama" @@ -323,7 +324,7 @@ msgid "Dedent" msgstr "Dedentasi" msgid "Backspace" -msgstr "Kembali" +msgstr "Backspace" msgid "Backspace Word" msgstr "Hapus Word" @@ -592,9 +593,15 @@ msgstr "Batalkan Pilihan Semua Kunci" msgid "Animation Change Transition" msgstr "Ubah Transisi Animasi" +msgid "Animation Change Position3D" +msgstr "Ubah Transisi Animasi3D" + msgid "Animation Change Rotation3D" msgstr "Ubah Transisi Animasi 3D" +msgid "Animation Change Scale3D" +msgstr "Ubah Animasi Skala3D" + msgid "Animation Change Keyframe Value" msgstr "Ubah Nilai Keyframe Animasi" @@ -604,6 +611,15 @@ msgstr "Ubah Panggilan Animasi" msgid "Animation Multi Change Transition" msgstr "Ubah Beberapa Transisi Animasi" +msgid "Animation Multi Change Position3D" +msgstr "Ubah Beberapa Posisi3D Animasi" + +msgid "Animation Multi Change Rotation3D" +msgstr "Ubah Beberapa Rotasi Animasi3D" + +msgid "Animation Multi Change Scale3D" +msgstr "Ubah Beberapa Skala3D Animasi" + msgid "Animation Multi Change Keyframe Value" msgstr "Ubah Beberapa Nilai Keyframe Animasi" @@ -818,6 +834,9 @@ msgstr "" msgid "Remove Anim Track" msgstr "Hapus Trek Anim" +msgid "Hold Shift when clicking the key icon to skip this dialog." +msgstr "Tahan Shift saat mengklik ikon kunci untuk melewati dialog ini." + msgid "Create new track for %s and insert key?" msgstr "Buat track baru untuk %s dan sisipkan kunci?" @@ -919,7 +938,7 @@ msgid "Scale" msgstr "Skala" msgid "BlendShape" -msgstr "BlendShape" +msgstr "BentukCampuran" msgid "Methods" msgstr "Metode" @@ -949,6 +968,9 @@ msgstr "Opsi ini tidak bisa untuk mengedit Bezier, karena hanya satu track." msgid "Animation Add RESET Keys" msgstr "Animasi Tambahkan Kunci RESET" +msgid "Bake Animation as Linear Keys" +msgstr "Bake Animasi sebagai Kunci Linier" + msgid "" "This animation belongs to an imported scene, so changes to imported tracks " "will not be saved.\n" @@ -968,8 +990,24 @@ msgstr "" "khusus, aktifkan \"Simpan Ke File\" dan\n" "\"Simpan Trek Khusus\"." +msgid "" +"Some AnimationPlayerEditor's options are disabled since this is the dummy " +"AnimationPlayer for preview.\n" +"\n" +"The dummy player is forced active, non-deterministic and doesn't have the " +"root motion track. Furthermore, the original node is inactive temporary." +msgstr "" +"Beberapa opsi AnimationPlayerEditor dinonaktifkan karena ini adalah " +"AnimationPlayer tiruan untuk pratinjau.\n" +"\n" +"Pemain tiruan dipaksa aktif, non-deterministik dan tidak memiliki jalur gerak " +"root. Selain itu, node asli tidak aktif sementara." + +msgid "AnimationPlayer is inactive. The playback will not be processed." +msgstr "AnimationPlayer mati. Putar ulang tidak akan diproses." + msgid "Select an AnimationPlayer node to create and edit animations." -msgstr "Lokasi untuk node AnimationPlayer yang mengandung animasi belum diatur." +msgstr "Pilih node AnimationPlayer untuk membuat dan mengedit animasi." msgid "Imported Scene" msgstr "Adegan yang Diimpor" @@ -977,6 +1015,18 @@ msgstr "Adegan yang Diimpor" msgid "Warning: Editing imported animation" msgstr "Peringatan: Menyunting animasi yang diimpor" +msgid "Dummy Player" +msgstr "Pemain Tiruan" + +msgid "Warning: Editing dummy AnimationPlayer" +msgstr "Peringatan: Sedang menyunting tiruan AnimationPlayer" + +msgid "Inactive Player" +msgstr "Player Nonaktif" + +msgid "Warning: AnimationPlayer is inactive" +msgstr "Peringatan: AnimationPlayer tidak aktif" + msgid "Toggle between the bezier curve editor and track editor." msgstr "Beralih antara editor kurva bezier dan editor trek." @@ -984,13 +1034,13 @@ msgid "Only show tracks from nodes selected in tree." msgstr "Hanya tampilkan track dari node terpilih dalam tree." msgid "Group tracks by node or display them as plain list." -msgstr "Susun Track-track dengan node atau tampilkan sebagai daftar biasa." +msgstr "Susun track berdasarkan node atau tampilkan sebagai daftar biasa." msgid "Snap:" -msgstr "Senap:" +msgstr "Tangkapan:" msgid "Animation step value." -msgstr "Nilai Langkah Animasi." +msgstr "Nilai langkah animasi." msgid "Seconds" msgstr "Detik" @@ -1002,7 +1052,7 @@ msgid "Edit" msgstr "Sunting" msgid "Animation properties." -msgstr "Properti Animasi." +msgstr "Properti animasi." msgid "Copy Tracks" msgstr "Salin Trek-trek" @@ -1035,7 +1085,7 @@ msgid "Apply Reset" msgstr "Terapkan Reset" msgid "Bake Animation" -msgstr "Bake Animasi" +msgstr "Ubah Animasi" msgid "Optimize Animation (no undo)" msgstr "Optimalkan Animasi (tanpa undo)" @@ -1068,7 +1118,7 @@ msgid "Optimize" msgstr "Optimalkan" msgid "Remove invalid keys" -msgstr "Hapus Tombol-tombol yang tidak sah" +msgstr "Hapus Tombol-tombol yang tidak valid" msgid "Remove unresolved and empty tracks" msgstr "Hapus tracks yang kosong dan belum diselesaikan" @@ -1741,7 +1791,7 @@ msgstr "Cari Resource Pengganti:" msgid "Open Scene" msgid_plural "Open Scenes" -msgstr[0] "Buka Skene" +msgstr[0] "Buka Skena" msgid "Open" msgstr "Buka" @@ -2327,7 +2377,7 @@ msgid "Asset Library" msgstr "Pustaka Aset" msgid "Scene Tree Editing" -msgstr "Menyunting Pohon Skena" +msgstr "Menyunting Daftar Skena" msgid "Node Dock" msgstr "Dok Node" @@ -2342,7 +2392,7 @@ msgid "History Dock" msgstr "Dok Sejarah" msgid "Allows to view and edit 3D scenes." -msgstr "Memungkinkan untuk melihat dan mengedit scene 3D." +msgstr "Memungkinkan untuk melihat dan mengedit adegan 3D." msgid "Allows to edit scripts using the integrated script editor." msgstr "" @@ -2352,7 +2402,7 @@ msgid "Provides built-in access to the Asset Library." msgstr "Menyediakan akses bawaan ke Perpustakaan Aset." msgid "Allows editing the node hierarchy in the Scene dock." -msgstr "Memungkinkan pengeditan hierarki node di dock Scene." +msgstr "Memungkinkan pengeditan hierarki node di dock adegan." msgid "" "Allows to work with signals and groups of the node selected in the Scene dock." @@ -2997,7 +3047,7 @@ msgid "Error while loading file '%s'." msgstr "Kesalahan saat memuat file '%s'." msgid "Saving Scene" -msgstr "Menyimpan Skena" +msgstr "Menyimpan Adegan" msgid "Analyzing" msgstr "Menganalisis" @@ -3012,8 +3062,9 @@ msgid "" "This scene can't be saved because there is a cyclic instance inclusion.\n" "Please resolve it and then attempt to save again." msgstr "" -"Scene ini tidak bisa disimpan karena ada inklusi penginstansian yang siklik.\n" -"Mohon betulkan dan coba simpan lagi." +"Adegan ini tidak bisa disimpan karena ada inklusi penginstansian yang " +"siklik.\n" +"Mohon perbaiki dan coba simpan lagi." msgid "" "Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " @@ -3023,16 +3074,16 @@ msgstr "" "tidak terpenuhi." msgid "Save scene before running..." -msgstr "Simpan skena sebelum menjalankan..." +msgstr "Simpan adegan sebelum menjalankan..." msgid "Could not save one or more scenes!" -msgstr "Tidak dapat menyimpan satu atau lebih skena!" +msgstr "Tidak dapat menyimpan satu atau beberapa adegan!" msgid "Save All Scenes" -msgstr "Simpan Semua Skena" +msgstr "Simpan Semua Adegan" msgid "Can't overwrite scene that is still open!" -msgstr "Tidak bisa menimpa skena yang masih terbuka!" +msgstr "Tidak bisa menimpa adegan yang masih terbuka!" msgid "Can't load MeshLibrary for merging!" msgstr "Tidak dapat memuat MeshLibrary untuk menggabungkan!" @@ -3070,17 +3121,16 @@ msgid "" "Please read the documentation relevant to importing scenes to better " "understand this workflow." msgstr "" -"Resource ini milik skena yang telah diimpor, jadi tidak dapat disunting.\n" -"Harap baca dokumentasi yang relevan dalam mengimpor skena untuk lebih " +"Resource ini milik adegan yang telah diimpor, jadi tidak dapat disunting.\n" +"Harap baca dokumentasi yang relevan dalam mengimpor adegan untuk lebih " "memahami alur kerjanya." msgid "" "This resource belongs to a scene that was instantiated or inherited.\n" "Changes to it must be made inside the original scene." msgstr "" -"Sumber daya ini termasuk dalam scene yang telah di-instansiasi atau " -"diwarisi.\n" -"Perubahan harus dilakukan di dalam scene asli." +"Resource ini termasuk dalam adegan yang telah di-instansiasi atau diwarisi.\n" +"Perubahan harus dilakukan di dalam adegan asli." msgid "" "This resource was imported, so it's not editable. Change its settings in the " @@ -3098,7 +3148,7 @@ msgstr "" "Adegan ini diimpor, jadi perubahan pada adegan ini tidak akan disimpan.\n" "Menginstansiasi atau mewarisinya akan memungkinkan Anda untuk membuat " "perubahan padanya.\n" -"Silakan baca dokumentasi yang relevan dengan mengimpor scene untuk lebih " +"Silakan baca dokumentasi yang relevan dengan mengimpor adegan untuk lebih " "memahami alur kerja ini." msgid "Changes may be lost!" @@ -3108,13 +3158,13 @@ msgid "This object is read-only." msgstr "Objek ini hanya dapat dibaca." msgid "Open Base Scene" -msgstr "Buka Skena Dasar" +msgstr "Buka Adegan Dasar" msgid "Quick Open..." msgstr "Buka Cepat..." msgid "Quick Open Scene..." -msgstr "Buka Cepat Skenario..." +msgstr "Buka Cepat Adegan..." msgid "Quick Open Script..." msgstr "Buka Cepat Skrip..." @@ -3126,21 +3176,21 @@ msgid "" "The current scene has no root node, but %d modified external resource(s) were " "saved anyway." msgstr "" -"Scene saat ini tidak memiliki node root, tetapi %d sumber daya eksternal yang " +"Adegan saat ini tidak memiliki node root, tetapi %d resource eksternal yang " "diubah tetap disimpan." msgid "" "A root node is required to save the scene. You can add a root node using the " "Scene tree dock." msgstr "" -"Node root diperlukan untuk menyimpan scene. Anda dapat menambahkan node root " -"menggunakan dok pohon Scene." +"Node root diperlukan untuk menyimpan adegan. Anda dapat menambahkan node root " +"menggunakan dok pohon Adegan." msgid "Save Scene As..." -msgstr "Simpan Skena Sebagai..." +msgstr "Simpan Adegan Sebagai..." msgid "Current scene not saved. Open anyway?" -msgstr "Skena saat ini belum disimpan. Buka saja?" +msgstr "Adegan saat ini belum disimpan. Buka saja?" msgid "Can't undo while mouse buttons are pressed." msgstr "Tidak bisa membatalkan ketika tombol mouse ditekan." @@ -3170,20 +3220,20 @@ msgid "Remote Redo: %s" msgstr "Undo Remote: %s" msgid "Scene Redo: %s" -msgstr "Adegan Redo: %s" +msgstr "Redo Adegan: %s" msgid "Can't reload a scene that was never saved." -msgstr "Tidak bisa memuat ulang skena yang belum pernah disimpan." +msgstr "Tidak bisa memuat ulang adegan yang belum pernah disimpan." msgid "Reload Saved Scene" -msgstr "Muat ulang scene yang sudah disimpan" +msgstr "Muat ulang adegan yang sudah disimpan" msgid "" "The current scene has unsaved changes.\n" "Reload the saved scene anyway? This action cannot be undone." msgstr "" -"Skena saat ini mempunyai perubahan yang belum tersimpan.\n" -"Tetap muat ulang skena yang tersimpan? Aksi ini tidak dapat dibatalkan." +"Adegan saat ini mempunyai perubahan yang belum tersimpan.\n" +"Tetap muat ulang adegan yang tersimpan? Tindakan ini tidak dapat dibatalkan." msgid "Save & Reload" msgstr "Simpan & Mulai Ulang" @@ -3201,10 +3251,10 @@ msgid "Save changes to the following scene(s) before reloading?" msgstr "Menyimpan perubahan pada adegan berikut sebelum memuat ulang?" msgid "Save changes to the following scene(s) before quitting?" -msgstr "Simpan perubahan skena saat ini sebelum keluar?" +msgstr "Simpan perubahan adegan saat ini sebelum keluar?" msgid "Save changes to the following scene(s) before opening Project Manager?" -msgstr "Simpan perubahan skena saat ini sebelum membuka Manajer Proyek?" +msgstr "Simpan perubahan adegan saat ini sebelum membuka Manajer Proyek?" msgid "" "This option is deprecated. Situations where refresh must be forced are now " @@ -3214,10 +3264,10 @@ msgstr "" "sebagai bug. Tolong laporkan." msgid "Pick a Main Scene" -msgstr "Pilih Skena Utama" +msgstr "Pilih Adegan Utama" msgid "This operation can't be done without a scene." -msgstr "Operasi ini tidak dapat diselesaikan tanpa skena." +msgstr "Operasi ini tidak dapat diselesaikan tanpa adegan." msgid "Export Mesh Library" msgstr "Ekspor Pustaka Mesh" @@ -3257,24 +3307,24 @@ msgid "" "Scene '%s' was automatically imported, so it can't be modified.\n" "To make changes to it, a new inherited scene can be created." msgstr "" -"Skena '%s' terimpor otomatis, jadi tidak dapat dimodifikasi.\n" -"Untuk melakukan perubahan, skena warisan baru dapat dibuat." +"Adegan '%s' terimpor otomatis, jadi tidak dapat dimodifikasi.\n" +"Untuk melakukan perubahan, adegan warisan baru dapat dibuat." msgid "" "Error loading scene, it must be inside the project path. Use 'Import' to open " "the scene, then save it inside the project path." msgstr "" -"Gagal memuat skena, harus dalam lokasi proyek. Gunakan 'Impor\" untuk membuka " -"skena tersebut, kemudian simpan di dalam lokasi proyek." +"Gagal memuat adegan, harus dalam lokasi proyek. Gunakan 'Impor\" untuk " +"membuka adegan tersebut, kemudian simpan di dalam lokasi proyek." msgid "Scene '%s' has broken dependencies:" -msgstr "Skena '%s' memiliki dependensi yang rusak:" +msgstr "Adegan '%s' memiliki dependensi yang rusak:" msgid "Clear Recent Scenes" -msgstr "Bersihkan Scenes baru-baru ini" +msgstr "Bersihkan Adegan baru-baru ini" msgid "There is no defined scene to run." -msgstr "Tidak ada skena yang didefinisikan untuk dijalankan." +msgstr "Tidak ada adegan yang didefinisikan untuk dijalankan." msgid "%s - Godot Engine" msgstr "%s - Godot Engine" @@ -3284,7 +3334,7 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"Tidak ada skena utama yang pernah didefinisikan, pilih satu?\n" +"Tidak ada adegan utama yang pernah didefinisikan, pilih satu?\n" "Anda dapat mengubahnya nanti di \"Pengaturan Proyek\" di bawah kategori " "'aplikasi'." @@ -3293,7 +3343,7 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"Skena '%s' tidak ada, pilih yang valid?\n" +"Adegan '%s' tidak ada, pilih yang valid?\n" "Anda dapat mengubahnya nanti di \"Pengaturan Proyek\" di bawah kategori " "'aplikasi'." @@ -3302,7 +3352,7 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"Skena yang dipilih '%s' bukanlah berkas skena, pilih yang valid?\n" +"Adegan yang dipilih '%s' bukanlah berkas adegan, pilih yang valid?\n" "Anda dapat menggantinya nanti di \"Pengaturan Proyek\" di bawah kategori " "'aplikasi'." @@ -3315,6 +3365,16 @@ msgstr "Hapus Penampilan" msgid "Default" msgstr "Bawaan" +msgid "This scene was never saved." +msgstr "Tidak bisa memuat ulang adegan yang belum pernah disimpan." + +msgid "" +"Scene \"%s\" has unsaved changes.\n" +"Last saved: %s." +msgstr "" +"Adegan \"%s\" memiliki perubahan yang belum disimpan.\n" +"Terakhir disimpan: %s." + msgid "Save & Close" msgstr "Simpan & Tutup" @@ -3352,7 +3412,7 @@ msgid "Scene" msgstr "Adegan" msgid "Operations with scene files." -msgstr "Operasi dengan berkas skena." +msgstr "Operasi dengan berkas adegan." msgid "Copy Text" msgstr "Salin Teks" @@ -3370,22 +3430,22 @@ msgid "Command Palette" msgstr "Palet Perintah" msgid "New Scene" -msgstr "Skena Baru" +msgstr "Adegan Baru" msgid "New Inherited Scene..." -msgstr "Skena Warisan Baru..." +msgstr "Adegan Turunan Baru..." msgid "Open Scene..." -msgstr "Buka Skena..." +msgstr "Buka Adegan..." msgid "Reopen Closed Scene" -msgstr "Buka Kembali Skena yang Ditutup" +msgstr "Buka Kembali Adegan yang Ditutup" msgid "Open Recent" msgstr "Buka baru-baru ini" msgid "Save Scene" -msgstr "Simpan Skena" +msgstr "Simpan Adegan" msgid "Export As..." msgstr "Ekspor Sebagai..." @@ -3394,7 +3454,7 @@ msgid "MeshLibrary..." msgstr "PerpustakaanMesh..." msgid "Close Scene" -msgstr "Tutup Skena" +msgstr "Tutup Adegan" msgid "Quit" msgstr "Keluar" @@ -3746,7 +3806,7 @@ msgid "" msgstr "" "Tidak dapat membuat ViewportTexture pada resource yang disimpan sebagai " "berkas.\n" -"Resource harus dimiliki oleh sebuah skena." +"Resource harus dimiliki oleh sebuah adegan." msgid "" "Can't create a ViewportTexture on this resource because it's not set as local " @@ -3755,7 +3815,7 @@ msgid "" "containing it up to a node)." msgstr "" "Tidak dapat membuat ViewportTexture pada resource ini karena tidak dibuat " -"lokal ke skena.\n" +"lokal ke adegan.\n" "Silakan aktifkan properti 'lokal ke skena' di atasnya (dan semua resource " "yang memuatnya sampai node)." @@ -3823,6 +3883,9 @@ msgstr "Jadikan Unik" msgid "Make Unique (Recursive)" msgstr "Jadikan Unik (Rekursif)" +msgid "Save As..." +msgstr "Simpan Sebagai..." + msgid "Show in FileSystem" msgstr "Tampilkan dalam FileSystem" @@ -5646,9 +5709,6 @@ msgstr "Muat resource yang ada dari diska dan mengubahnya." msgid "Save the currently edited resource." msgstr "Simpan resource yang sedang disunting saat ini." -msgid "Save As..." -msgstr "Simpan Sebagai..." - msgid "Extra resource options." msgstr "Opsi resource tambahan." @@ -6276,7 +6336,7 @@ msgid "Force White Modulate" msgstr "Paksa Modulasi Putih" msgid "Include Gizmos (3D)" -msgstr "Masukkan Gizmo (3D)" +msgstr "Sertakan Gizmo (3D)" msgid "Pin AnimationPlayer" msgstr "Sematkan AnimationPlayer" @@ -6909,7 +6969,7 @@ msgid "Show Group And Lock Icons" msgstr "Tampilkan Ikon Kunci Dan Grup" msgid "Show Transformation Gizmos" -msgstr "Tampilkan Gizmos Transformasi" +msgstr "Tampilkan Transformasi Gismos" msgid "Center Selection" msgstr "Seleksi Tengah" @@ -12142,6 +12202,9 @@ msgstr "Konstanta tidak dapat dimodifikasi." msgid "Invalid argument name." msgstr "Nama argumen tidak valid." +msgid "Invalid undef." +msgstr "Tidak valid." + msgid "Invalid macro argument list." msgstr "Daftar Argumen Macro Tidak Valid." @@ -12150,3 +12213,6 @@ msgstr "Argumen makro tidak sah." msgid "Invalid macro argument count." msgstr "Daftar Argumen Macro Tidak Valid" + +msgid "Unmatched conditional statement." +msgstr "Pernyataan kondisi tidak cocok." diff --git a/editor/translations/editor/it.po b/editor/translations/editor/it.po index b8d27005b3..1ee9bd8616 100644 --- a/editor/translations/editor/it.po +++ b/editor/translations/editor/it.po @@ -3906,6 +3906,9 @@ msgstr "Rendi Unico" msgid "Make Unique (Recursive)" msgstr "Rendi unica (ricorsivo)" +msgid "Save As..." +msgstr "Salva Come..." + msgid "Show in FileSystem" msgstr "Mostra nel filesystem" @@ -5775,9 +5778,6 @@ msgstr "Carica una risorsa esistente dal disco e modificala." msgid "Save the currently edited resource." msgstr "Salva la risorsa attualmente in modifica." -msgid "Save As..." -msgstr "Salva Come..." - msgid "Extra resource options." msgstr "Ulteriori opzioni di risorsa." diff --git a/editor/translations/editor/ja.po b/editor/translations/editor/ja.po index 3f8e21a12e..8a09b765a7 100644 --- a/editor/translations/editor/ja.po +++ b/editor/translations/editor/ja.po @@ -68,7 +68,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor interface\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2023-11-12 18:58+0000\n" +"PO-Revision-Date: 2023-11-18 06:21+0000\n" "Last-Translator: ueshita <nalto32@gmail.com>\n" "Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/" "godot/ja/>\n" @@ -77,7 +77,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.2-dev\n" +"X-Generator: Weblate 5.2\n" msgid "Main Thread" msgstr "メインスレッド" @@ -1940,6 +1940,9 @@ msgstr "開発者" msgid "Authors" msgstr "作者" +msgid "Patrons" +msgstr "パトロン" + msgid "Platinum Sponsors" msgstr "プラチナスポンサー" @@ -1949,6 +1952,18 @@ msgstr "ゴールドスポンサー" msgid "Silver Sponsors" msgstr "シルバースポンサー" +msgid "Diamond Members" +msgstr "ダイヤモンドメンバー" + +msgid "Titanium Members" +msgstr "チタニウムメンバー" + +msgid "Platinum Members" +msgstr "プレミアムメンバー" + +msgid "Gold Members" +msgstr "ゴールドメンバー" + msgid "Donors" msgstr "ドナー" @@ -4042,6 +4057,9 @@ msgstr "ユニーク化" msgid "Make Unique (Recursive)" msgstr "ユニーク化 (再帰的)" +msgid "Save As..." +msgstr "名前を付けて保存..." + msgid "Show in FileSystem" msgstr "ファイルシステム上で表示" @@ -4516,6 +4534,9 @@ msgstr "プリセット '%s' を削除しますか?" msgid "Resources to exclude:" msgstr "除外するリソース:" +msgid "Resources to override export behavior:" +msgstr "エクスポート処理を上書きするリソース:" + msgid "Resources to export:" msgstr "エクスポートするリソース:" @@ -4825,6 +4846,9 @@ msgstr "フォルダーを複製:" msgid "New Inherited Scene" msgstr "新しい継承シーン" +msgid "Set as Main Scene" +msgstr "メインシーンとして設定" + msgid "Open Scenes" msgstr "シーンを開く" @@ -4972,6 +4996,9 @@ msgstr "次に選択したフォルダ/ファイルに移動します。" msgid "Re-Scan Filesystem" msgstr "ファイルシステムを再スキャン" +msgid "Change Split Mode" +msgstr "分割モードの変更" + msgid "Filter Files" msgstr "ファイルをフィルタ" @@ -5946,9 +5973,6 @@ msgstr "既存のリソースをディスクから読み込み編集する。" msgid "Save the currently edited resource." msgstr "現在編集中のリソースを保存する。" -msgid "Save As..." -msgstr "名前を付けて保存..." - msgid "Extra resource options." msgstr "追加のリソースオプション。" @@ -6561,6 +6585,9 @@ msgstr "[グローバル](作成)" msgid "Duplicated Animation Name:" msgstr "複製されたアニメーション名:" +msgid "Onion skinning requires a RESET animation." +msgstr "オニオン スキニングには RESET アニメーションが必要です。" + msgid "Play selected animation backwards from current pos. (A)" msgstr "選択したアニメーションを現在の位置から逆再生する。(A)" @@ -7693,6 +7720,18 @@ msgstr "" "このオプションを有効にすると、回避形状、大きさおよびベロシティが、ゲーム実行中" "にも表示されるようになります。" +msgid "Debug CanvasItem Redraws" +msgstr "CanvasItem の再描画をデバッグする" + +msgid "" +"When this option is enabled, redraw requests of 2D objects will become " +"visible (as a short flash) in the running project.\n" +"This is useful to troubleshoot low processor mode." +msgstr "" +"このオプションを有効にすると、2D オブジェクトの再描画リクエストが実行中のプロ" +"ジェクトに (短いフラッシュとして) 表示されるようになります。 これは低プロセッ" +"サ モードのトラブルシューティングに役立ちます。" + msgid "Synchronize Scene Changes" msgstr "シーン変更を同期" @@ -9818,6 +9857,12 @@ msgstr "LightOccluder2Dを作成" msgid "LightOccluder2D Preview" msgstr "LightOccluder2D プレビュー" +msgid "Can't convert a sprite from a foreign scene." +msgstr "外部シーンからのスプライトを変換できません。" + +msgid "Can't convert an empty sprite to mesh." +msgstr "空のスプライトをメッシュに変換できません。" + msgid "Can't convert a sprite using animation frames to mesh." msgstr "アニメーションフレームを使用してスプライトをメッシュに変換できません。" @@ -13484,9 +13529,19 @@ msgstr "" "\"editable_instance\" を無効にすると、ノードのすべてのプロパティがデフォルトに" "戻ります。" +msgid "" +"Enabling \"Load as Placeholder\" will disable \"Editable Children\" and cause " +"all properties of the node to be reverted to their default." +msgstr "" +"「プレースホルダーとしてロード」を有効にすると、「編集可能な子」が無効になり、" +"ノードのすべてのプロパティがデフォルトに戻ります。" + msgid "Make Local" msgstr "ローカルにする" +msgid "Can't toggle unique name for nodes in subscene!" +msgstr "サブシーン内のノードの固有名を切り替えることができません!" + msgid "Enable Scene Unique Name(s)" msgstr "シーン固有名を有効にする" @@ -13572,6 +13627,9 @@ msgstr "継承をクリア" msgid "Editable Children" msgstr "編集可能な子" +msgid "Load as Placeholder" +msgstr "プレースホルダーとしてロード" + msgid "Auto Expand to Selected" msgstr "選択対象へ自動拡張" @@ -13862,7 +13920,7 @@ msgid "Please specify a valid shader uniform identifier name." msgstr "有効なシェーダーuniform識別子名を指定してください。" msgid "Global shader parameter '%s' already exists'" -msgstr "グローバルシェーダーパラメーター '%s' は存在しています" +msgstr "グローバルシェーダーパラメーター '%s' は既に存在しています" msgid "Name '%s' is a reserved shader language keyword." msgstr "名前 '%s' は予約されたシェーダー言語キーワードです。" @@ -13898,6 +13956,9 @@ msgstr "トーラスの外半径を変更" msgid "Invalid type argument to convert(), use TYPE_* constants." msgstr "convert() の引数の型が無効です。TYPE_* 定数を使用してください。" +msgid "Cannot resize array." +msgstr "配列のサイズを変更できません。" + msgid "Step argument is zero!" msgstr "ステップ引数はゼロです!" @@ -13922,6 +13983,9 @@ msgstr "無効なインスタンス辞書形式です(@path で無効なスク msgid "Invalid instance dictionary (invalid subclasses)" msgstr "無効なインスタンス辞書です(無効なサブクラス)" +msgid "Cannot instantiate GDScript class." +msgstr "GDScriptクラスをインスタンス化できません。" + msgid "Value of type '%s' can't provide a length." msgstr "'%s'型のオブジェクトは長さを提供できません。" diff --git a/editor/translations/editor/ka.po b/editor/translations/editor/ka.po index 7669bd9820..a9f193b9d1 100644 --- a/editor/translations/editor/ka.po +++ b/editor/translations/editor/ka.po @@ -1650,6 +1650,9 @@ msgstr "თარგმნადი სტრიქონი (ზომა %d)" msgid "Inspect" msgstr "შეამოწმეთ" +msgid "Save As..." +msgstr "შეინახვა &როგორც..." + msgid "Convert to %s" msgstr "%s-ში გადაყვანა" @@ -2122,9 +2125,6 @@ msgstr "თვისებების კოპირება" msgid "Paste Properties" msgstr "თვისებების ჩასმა" -msgid "Save As..." -msgstr "შეინახვა &როგორც..." - msgid "Go to previous edited object in history." msgstr "ისტორიაში წინა ჩასწორებულ ობიექტზე გადასვლა." diff --git a/editor/translations/editor/ko.po b/editor/translations/editor/ko.po index 8fafeffea6..8d69f31ad5 100644 --- a/editor/translations/editor/ko.po +++ b/editor/translations/editor/ko.po @@ -3801,6 +3801,9 @@ msgstr "유일하게 만들기" msgid "Make Unique (Recursive)" msgstr "유일하게 만들기 (재귀적으로)" +msgid "Save As..." +msgstr "다른 이름으로 저장..." + msgid "Show in FileSystem" msgstr "파일시스템에서 보기" @@ -5587,9 +5590,6 @@ msgstr "디스크에서 기존 리소스를 불러오고 편집합니다." msgid "Save the currently edited resource." msgstr "현재 편집하는 리소스를 저장합니다." -msgid "Save As..." -msgstr "다른 이름으로 저장..." - msgid "Extra resource options." msgstr "다른 리소스 옵션입니다." diff --git a/editor/translations/editor/lv.po b/editor/translations/editor/lv.po index ec6a76748b..3d1e21086f 100644 --- a/editor/translations/editor/lv.po +++ b/editor/translations/editor/lv.po @@ -2382,6 +2382,9 @@ msgstr "Jauna atslēga:" msgid "New Value:" msgstr "Jauna vērtība:" +msgid "Save As..." +msgstr "Saglabāt kā..." + msgid "Show in FileSystem" msgstr "Parādīt failu sistēmā" @@ -2788,9 +2791,6 @@ msgstr "Kopēt iestatījumus" msgid "Paste Properties" msgstr "Ielīmēt iestatījumus" -msgid "Save As..." -msgstr "Saglabāt kā..." - msgid "Open documentation for this object." msgstr "Atvērt dokumentāciju šim objektam." diff --git a/editor/translations/editor/ms.po b/editor/translations/editor/ms.po index 4c93d18ee7..4a4edb5e3e 100644 --- a/editor/translations/editor/ms.po +++ b/editor/translations/editor/ms.po @@ -2392,6 +2392,9 @@ msgstr "Muatan Cepat" msgid "Make Unique" msgstr "Buat Unik" +msgid "Save As..." +msgstr "Simpan Sebagai..." + msgid "Show in FileSystem" msgstr "Tunjukkan dalam FileSystem" @@ -3055,9 +3058,6 @@ msgstr "Muatkan sumber sedia ada dari cakera dan suntingnya." msgid "Save the currently edited resource." msgstr "Simpan sumber yang sedang disunting." -msgid "Save As..." -msgstr "Simpan Sebagai..." - msgid "Extra resource options." msgstr "Pilihan sumber tambahan." diff --git a/editor/translations/editor/nb.po b/editor/translations/editor/nb.po index e2acd64e6c..9b8f4e8b94 100644 --- a/editor/translations/editor/nb.po +++ b/editor/translations/editor/nb.po @@ -1907,6 +1907,9 @@ msgstr "Legg Til Nøkkel/Verdi Par" msgid "Make Unique" msgstr "Gjør Unik" +msgid "Save As..." +msgstr "Lagre Som..." + msgid "New %s" msgstr "Ny %s" @@ -2348,9 +2351,6 @@ msgstr "Last inn en eksisterende ressurs fra disk og rediger den." msgid "Save the currently edited resource." msgstr "Lagre den nylige redigerte ressursen." -msgid "Save As..." -msgstr "Lagre Som..." - msgid "Copy Resource" msgstr "Kopier Ressurs" diff --git a/editor/translations/editor/nl.po b/editor/translations/editor/nl.po index 1a709ce615..fc1d7e33ba 100644 --- a/editor/translations/editor/nl.po +++ b/editor/translations/editor/nl.po @@ -69,13 +69,14 @@ # Raymon Zutekouw <me@raymon.dev>, 2023. # Nicolai Van der Storm <nicolai@nvds.be>, 2023. # Gaetan Deglorie <gaetan@rhinox.training>, 2023. +# Bert Heymans <bert.heymans@gmail.com>, 2023. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor interface\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2023-11-08 00:04+0000\n" -"Last-Translator: Raymon <me@raymon.dev>\n" +"PO-Revision-Date: 2023-11-18 06:21+0000\n" +"Last-Translator: Bert Heymans <bert.heymans@gmail.com>\n" "Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/" "nl/>\n" "Language: nl\n" @@ -83,7 +84,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.2-dev\n" +"X-Generator: Weblate 5.2\n" msgid "Unset" msgstr "Niet ingesteld" @@ -956,7 +957,7 @@ msgstr "" "Weet je zeker dat je alle verbindingen met signaal \"%s\" wilt verwijderen?" msgid "Signals" -msgstr "Signalen" +msgstr "Signaal:" msgid "Filter Signals" msgstr "Filter Signalen" @@ -2645,6 +2646,9 @@ msgstr "Snel Laden" msgid "Make Unique" msgstr "Maak Uniek" +msgid "Save As..." +msgstr "Opslaan Als..." + msgid "Show in FileSystem" msgstr "Weergeven in Bestandssysteem" @@ -3425,9 +3429,6 @@ msgstr "Laad een bestaande bron van de schijf en bewerk het." msgid "Save the currently edited resource." msgstr "De zojuist bewerkte bron opslaan." -msgid "Save As..." -msgstr "Opslaan Als..." - msgid "Copy Resource" msgstr "Bron kopiëren" diff --git a/editor/translations/editor/pl.po b/editor/translations/editor/pl.po index 37c7df4755..7983f088f8 100644 --- a/editor/translations/editor/pl.po +++ b/editor/translations/editor/pl.po @@ -88,7 +88,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor interface\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2023-11-12 01:21+0000\n" +"PO-Revision-Date: 2023-11-21 15:04+0000\n" "Last-Translator: Tomek <kobewi4e@gmail.com>\n" "Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/godot/" "pl/>\n" @@ -98,7 +98,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 5.2-dev\n" +"X-Generator: Weblate 5.2\n" msgid "Main Thread" msgstr "Główny wątek" @@ -1969,6 +1969,9 @@ msgstr "Deweloperzy" msgid "Authors" msgstr "Autorzy" +msgid "Patrons" +msgstr "Sponsorzy" + msgid "Platinum Sponsors" msgstr "Platynowi sponsorzy" @@ -1978,6 +1981,18 @@ msgstr "Złoci sponsorzy" msgid "Silver Sponsors" msgstr "Srebrni sponsorzy" +msgid "Diamond Members" +msgstr "Diamentowi członkowie" + +msgid "Titanium Members" +msgstr "Tytanowi członkowie" + +msgid "Platinum Members" +msgstr "Platynowi członkowie" + +msgid "Gold Members" +msgstr "Złoci członkowie" + msgid "Donors" msgstr "Darczyńcy" @@ -3763,7 +3778,7 @@ msgid "Mobile" msgstr "Mobilny" msgid "Compatibility" -msgstr "Kompatybilność" +msgstr "Kompatybilny" msgid "Changing the renderer requires restarting the editor." msgstr "Zmiana renderera wymaga restartu edytora." @@ -4078,6 +4093,9 @@ msgstr "Zrób unikalny" msgid "Make Unique (Recursive)" msgstr "Zrób unikalny (rekurencyjnie)" +msgid "Save As..." +msgstr "Zapisz jako..." + msgid "Show in FileSystem" msgstr "Pokaż w systemie plików" @@ -4989,7 +5007,7 @@ msgid "Blue" msgstr "Niebieski" msgid "Purple" -msgstr "Purpurowy" +msgstr "Fioletowy" msgid "Pink" msgstr "Różowy" @@ -5998,9 +6016,6 @@ msgstr "Wczytaj istniejący zasób i edytuj go." msgid "Save the currently edited resource." msgstr "Zapisz aktualnie edytowany zasób." -msgid "Save As..." -msgstr "Zapisz jako..." - msgid "Extra resource options." msgstr "Dodatkowe opcje zasobów." @@ -14921,9 +14936,15 @@ msgstr "Nie udało się zapisać pliku pakietu rozszerzenia!" msgid "Building Android Project (gradle)" msgstr "Budowanie projektu Androida (gradle)" +msgid "Building of Android project failed, check output for the error:" +msgstr "Budowanie projektu Androida nie powiodło się, sprawdź błędy w konsoli." + msgid "Moving output" msgstr "Przesuwam wyjście" +msgid "Unable to copy and rename export file:" +msgstr "Nie udało się skopiować i zmienić nazwy pliku eksportu:" + msgid "Package not found: \"%s\"." msgstr "Nie znaleziono pakietu: \"%s\"." @@ -16491,7 +16512,7 @@ msgid "" "refactoring in a future 4.x version involving compatibility-breaking API " "changes." msgstr "" -"Miej na uwadze, że GraphEdit i GraphNode przejdą obszerne refaktorowanie w " +"Miej na uwadze, że GraphEdit i GraphNode przejdą obszerną refaktoryzację w " "przyszłej wersji 4.x, obejmujące zmiany API łamiące kompatybilność." msgid "Toggle the visual grid." diff --git a/editor/translations/editor/pt.po b/editor/translations/editor/pt.po index 6be39a5994..c3f8f89656 100644 --- a/editor/translations/editor/pt.po +++ b/editor/translations/editor/pt.po @@ -3851,6 +3851,9 @@ msgstr "Fazer único" msgid "Make Unique (Recursive)" msgstr "Tornar Único (Recursivo)" +msgid "Save As..." +msgstr "Guardar Como..." + msgid "Show in FileSystem" msgstr "Mostrar no Sistema de Ficheiros" @@ -5679,9 +5682,6 @@ msgstr "Carregue um recurso existente a partir do disco e edite-o." msgid "Save the currently edited resource." msgstr "Guarde o recurso editado." -msgid "Save As..." -msgstr "Guardar Como..." - msgid "Extra resource options." msgstr "Opções de recurso extra." diff --git a/editor/translations/editor/pt_BR.po b/editor/translations/editor/pt_BR.po index 326ee2a71f..b7e474aee8 100644 --- a/editor/translations/editor/pt_BR.po +++ b/editor/translations/editor/pt_BR.po @@ -175,13 +175,14 @@ # "wendeli alves (wilcoxjvkb)" <wilcoxjvkb@gmail.com>, 2023. # Fernando Crozetta <fernando@czetta.com>, 2023. # Sergio Antonio <sergio.antonio.pn@proton.me>, 2023. +# Martonio Junior <jose.mart.junior@gmail.com>, 2023. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor interface\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: 2016-05-30\n" -"PO-Revision-Date: 2023-11-06 00:35+0000\n" -"Last-Translator: Elizandro Baldin <ejbaldin@gmail.com>\n" +"PO-Revision-Date: 2023-11-21 15:04+0000\n" +"Last-Translator: Martonio Junior <jose.mart.junior@gmail.com>\n" "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/godot-" "engine/godot/pt_BR/>\n" "Language: pt_BR\n" @@ -189,7 +190,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.2-dev\n" +"X-Generator: Weblate 5.2\n" msgid "Main Thread" msgstr "Thread principal" @@ -2067,6 +2068,9 @@ msgstr "Patrocinadores Ouro" msgid "Silver Sponsors" msgstr "Patrocinadores Prata" +msgid "Diamond Members" +msgstr "Patrocinadores Diamante" + msgid "Donors" msgstr "Doadores" @@ -4051,6 +4055,9 @@ msgstr "Tornar Único" msgid "Make Unique (Recursive)" msgstr "Tornar Único (Recursivo)" +msgid "Save As..." +msgstr "Salvar Como..." + msgid "Show in FileSystem" msgstr "Mostrar em Arquivos" @@ -5882,9 +5889,6 @@ msgstr "Carrega um recurso existente do disco e o edita." msgid "Save the currently edited resource." msgstr "Salva o recurso editado atualmente." -msgid "Save As..." -msgstr "Salvar Como..." - msgid "Extra resource options." msgstr "Opções de recursos extras." diff --git a/editor/translations/editor/ro.po b/editor/translations/editor/ro.po index c52adbc255..cbde238be5 100644 --- a/editor/translations/editor/ro.po +++ b/editor/translations/editor/ro.po @@ -1991,6 +1991,9 @@ msgstr "Cheie Nouă:" msgid "New Value:" msgstr "Valoare Nouă:" +msgid "Save As..." +msgstr "Salvează Ca..." + msgid "Show in FileSystem" msgstr "Afișare în FileSystem" @@ -2452,9 +2455,6 @@ msgstr "Încarcă o resursă existentă de pe disc si editeaz-o." msgid "Save the currently edited resource." msgstr "Salvează resursa editată curentă." -msgid "Save As..." -msgstr "Salvează Ca..." - msgid "Copy Resource" msgstr "Copiați Resursa" diff --git a/editor/translations/editor/ru.po b/editor/translations/editor/ru.po index 8cbb33c832..f2931b5182 100644 --- a/editor/translations/editor/ru.po +++ b/editor/translations/editor/ru.po @@ -170,7 +170,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor interface\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2023-11-11 19:11+0000\n" +"PO-Revision-Date: 2023-11-18 06:21+0000\n" "Last-Translator: Ilia Brykin <brykin.ilia@gmail.com>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" @@ -180,7 +180,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 5.2-dev\n" +"X-Generator: Weblate 5.2\n" msgid "Main Thread" msgstr "Главный поток" @@ -2055,6 +2055,9 @@ msgstr "Разработчики" msgid "Authors" msgstr "Авторы" +msgid "Patrons" +msgstr "Покровители" + msgid "Platinum Sponsors" msgstr "Платиновые спонсоры" @@ -2064,6 +2067,18 @@ msgstr "Золотые спонсоры" msgid "Silver Sponsors" msgstr "Серебряные спонсоры" +msgid "Diamond Members" +msgstr "Члены Алмазного уровня" + +msgid "Titanium Members" +msgstr "Члены Титанового уровня" + +msgid "Platinum Members" +msgstr "Члены Платинового уровня" + +msgid "Gold Members" +msgstr "Члены золотого уровня" + msgid "Donors" msgstr "Доноры" @@ -4170,6 +4185,9 @@ msgstr "Сделать уникальным" msgid "Make Unique (Recursive)" msgstr "Сделать уникальным (рекурсивно)" +msgid "Save As..." +msgstr "Сохранить как..." + msgid "Show in FileSystem" msgstr "Показать в файловой системе" @@ -6089,9 +6107,6 @@ msgstr "Загрузить существующий ресурс с диска msgid "Save the currently edited resource." msgstr "Сохранить текущий редактируемый ресурс." -msgid "Save As..." -msgstr "Сохранить как..." - msgid "Extra resource options." msgstr "Дополнительные параметры ресурса." @@ -15021,9 +15036,15 @@ msgstr "Не удалось записать расширение файла п msgid "Building Android Project (gradle)" msgstr "Сборка проекта Android (gradle)" +msgid "Building of Android project failed, check output for the error:" +msgstr "Сборка проекта Android не удалась, проверьте вывод для ошибки:" + msgid "Moving output" msgstr "Перемещение выходных данных" +msgid "Unable to copy and rename export file:" +msgstr "Не удается скопировать и переименовать файл экспорта:" + msgid "Package not found: \"%s\"." msgstr "Пакет не найден: \"%s\"." diff --git a/editor/translations/editor/sk.po b/editor/translations/editor/sk.po index 9dbfc541f1..d354bf30df 100644 --- a/editor/translations/editor/sk.po +++ b/editor/translations/editor/sk.po @@ -3230,6 +3230,9 @@ msgstr "Rýchle načítanie" msgid "Make Unique" msgstr "Spraviť Jedinečným" +msgid "Save As..." +msgstr "Uložiť Ako..." + msgid "Show in FileSystem" msgstr "Ukázať v FileSystéme" @@ -4279,9 +4282,6 @@ msgstr "Načítať existujúci prostriedok z disku a upraviť ho." msgid "Save the currently edited resource." msgstr "Uložiť aktuálne upravený prostriedok." -msgid "Save As..." -msgstr "Uložiť Ako..." - msgid "Copy Resource" msgstr "Skopírovať Prostriedok" diff --git a/editor/translations/editor/sv.po b/editor/translations/editor/sv.po index 0198e3cc27..83a7925f3e 100644 --- a/editor/translations/editor/sv.po +++ b/editor/translations/editor/sv.po @@ -3524,6 +3524,9 @@ msgstr "Lokaliserbar sträng (storlek %d)" msgid "Make Unique" msgstr "Gör Unik" +msgid "Save As..." +msgstr "Spara Som..." + msgid "Show in FileSystem" msgstr "Visa i filsystemet" @@ -4465,9 +4468,6 @@ msgstr "Ladda en befintlig resurs från disken och redigera den." msgid "Save the currently edited resource." msgstr "Spara den nuvarande redigerade resursen." -msgid "Save As..." -msgstr "Spara Som..." - msgid "Copy Resource" msgstr "Kopiera Resurs" diff --git a/editor/translations/editor/th.po b/editor/translations/editor/th.po index 002c09fff8..00e0d50576 100644 --- a/editor/translations/editor/th.po +++ b/editor/translations/editor/th.po @@ -2435,6 +2435,9 @@ msgstr "ทรัพยากรที่เลือก (%s) มีประเ msgid "Make Unique" msgstr "ไม่ใช้ร่วมกับวัตถุอื่น" +msgid "Save As..." +msgstr "บันทึกเป็น..." + msgid "Show in FileSystem" msgstr "แสดงในรูปแบบไฟล์" @@ -3093,9 +3096,6 @@ msgstr "โหลดรีซอร์สที่มีอยู่แล้ว msgid "Save the currently edited resource." msgstr "บันทึกรีซอร์สที่กำลังปรับแต่ง" -msgid "Save As..." -msgstr "บันทึกเป็น..." - msgid "Copy Resource" msgstr "คัดลอกรีซอร์ส" diff --git a/editor/translations/editor/tr.po b/editor/translations/editor/tr.po index bf9c8246a1..792179d72c 100644 --- a/editor/translations/editor/tr.po +++ b/editor/translations/editor/tr.po @@ -111,7 +111,7 @@ msgstr "" "Project-Id-Version: Godot Engine editor interface\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2023-11-16 16:21+0000\n" +"PO-Revision-Date: 2023-11-17 02:03+0000\n" "Last-Translator: Yılmaz Durmaz <yilmaz_durmaz@hotmail.com>\n" "Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/" "godot/tr/>\n" @@ -1988,6 +1988,9 @@ msgstr "Geliştiriciler" msgid "Authors" msgstr "Yazarlar" +msgid "Patrons" +msgstr "Velinimetler" + msgid "Platinum Sponsors" msgstr "Platin Sponsorlar" @@ -1997,6 +2000,18 @@ msgstr "Altın Sponsorlar" msgid "Silver Sponsors" msgstr "Gümüş Bağışçılar" +msgid "Diamond Members" +msgstr "Elmas Üyeler" + +msgid "Titanium Members" +msgstr "Titanyum Üyeler" + +msgid "Platinum Members" +msgstr "Platin Üyeler" + +msgid "Gold Members" +msgstr "Altın Üyeler" + msgid "Donors" msgstr "Bağışçılar" @@ -4111,6 +4126,9 @@ msgstr "Benzersiz Yap" msgid "Make Unique (Recursive)" msgstr "Benzersiz Yap (Özyinelemeli)" +msgid "Save As..." +msgstr "Farklı Kaydet..." + msgid "Show in FileSystem" msgstr "DosyaSistemi'nde Göster" @@ -6041,9 +6059,6 @@ msgstr "Var olan bir kaynağı diskten yükle ve düzenle." msgid "Save the currently edited resource." msgstr "Şu anda düzenlenen kaynağı kaydet." -msgid "Save As..." -msgstr "Farklı Kaydet..." - msgid "Extra resource options." msgstr "Kaynak ek seçenekleri." @@ -14990,9 +15005,17 @@ msgstr "Genişletme paketi dosyası yazılamadı!" msgid "Building Android Project (gradle)" msgstr "Android Projesi Oluşturuluyor (gradle)" +msgid "Building of Android project failed, check output for the error:" +msgstr "" +"Android projesinin oluşturulması başarısız oldu, hata için çıktıları kontrol " +"edin:" + msgid "Moving output" msgstr "Çıktı taşınıyor" +msgid "Unable to copy and rename export file:" +msgstr "Dışa aktarma dosyası kopyalanamıyor ve yeniden adlandırılamıyor:" + msgid "Package not found: \"%s\"." msgstr "Paket bulunamadı: \"%s\"." diff --git a/editor/translations/editor/uk.po b/editor/translations/editor/uk.po index f904164474..39e34daae4 100644 --- a/editor/translations/editor/uk.po +++ b/editor/translations/editor/uk.po @@ -3582,6 +3582,9 @@ msgstr "Зробити унікальним" msgid "Make Unique (Recursive)" msgstr "Зробити унікальним (Рекурсивним)" +msgid "Save As..." +msgstr "Зберегти як..." + msgid "Show in FileSystem" msgstr "Показати у файловій системі" @@ -5308,9 +5311,6 @@ msgstr "Завантажити наявний ресурс із диска та msgid "Save the currently edited resource." msgstr "Зберегти поточний редагований ресурс." -msgid "Save As..." -msgstr "Зберегти як..." - msgid "Extra resource options." msgstr "Додаткові параметри ресурсу." diff --git a/editor/translations/editor/vi.po b/editor/translations/editor/vi.po index 6830e91ca3..35e12f2db2 100644 --- a/editor/translations/editor/vi.po +++ b/editor/translations/editor/vi.po @@ -2198,6 +2198,9 @@ msgstr "Nạp nhanh" msgid "Make Unique" msgstr "Duy nhất" +msgid "Save As..." +msgstr "Lưu thành ..." + msgid "Show in FileSystem" msgstr "Hiện trong Hệ thống tệp tin" @@ -2880,9 +2883,6 @@ msgstr "Tải tài nguyên có sẵn trong đĩa rồi chỉnh sửa." msgid "Save the currently edited resource." msgstr "Lưu tài nguyên đã chỉnh sửa hiện tại." -msgid "Save As..." -msgstr "Lưu thành ..." - msgid "Copy Resource" msgstr "Sao chép Tài nguyên" diff --git a/editor/translations/editor/zh_CN.po b/editor/translations/editor/zh_CN.po index 47496f948f..ebbdc53fa0 100644 --- a/editor/translations/editor/zh_CN.po +++ b/editor/translations/editor/zh_CN.po @@ -101,7 +101,7 @@ msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2023-11-11 03:41+0000\n" +"PO-Revision-Date: 2023-11-18 06:21+0000\n" "Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hans/>\n" @@ -110,7 +110,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.2-dev\n" +"X-Generator: Weblate 5.2\n" msgid "Main Thread" msgstr "主线程" @@ -1950,6 +1950,9 @@ msgstr "开发人员" msgid "Authors" msgstr "作者" +msgid "Patrons" +msgstr "赞助人" + msgid "Platinum Sponsors" msgstr "白金赞助" @@ -1959,6 +1962,18 @@ msgstr "黄金赞助" msgid "Silver Sponsors" msgstr "白银赞助" +msgid "Diamond Members" +msgstr "钻石会员" + +msgid "Titanium Members" +msgstr "钛金会员" + +msgid "Platinum Members" +msgstr "白金会员" + +msgid "Gold Members" +msgstr "黄金会员" + msgid "Donors" msgstr "捐助者" @@ -3983,6 +3998,9 @@ msgstr "唯一化" msgid "Make Unique (Recursive)" msgstr "唯一化(递归)" +msgid "Save As..." +msgstr "另存为..." + msgid "Show in FileSystem" msgstr "在文件系统中显示" @@ -5822,9 +5840,6 @@ msgstr "从磁盘中加载资源并编辑。" msgid "Save the currently edited resource." msgstr "保存当前编辑的资源。" -msgid "Save As..." -msgstr "另存为..." - msgid "Extra resource options." msgstr "更多资源选项。" @@ -14401,9 +14416,15 @@ msgstr "无法写入扩展包文件!" msgid "Building Android Project (gradle)" msgstr "构建 Android 项目 (Gradle)" +msgid "Building of Android project failed, check output for the error:" +msgstr "Android 项目构建失败,请检查输出中显示的错误:" + msgid "Moving output" msgstr "移动输出" +msgid "Unable to copy and rename export file:" +msgstr "无法复制并更名导出文件:" + msgid "Package not found: \"%s\"." msgstr "包不存在:“%s”。" diff --git a/editor/translations/editor/zh_TW.po b/editor/translations/editor/zh_TW.po index 0a56829306..c427be8902 100644 --- a/editor/translations/editor/zh_TW.po +++ b/editor/translations/editor/zh_TW.po @@ -3914,6 +3914,9 @@ msgstr "唯一化" msgid "Make Unique (Recursive)" msgstr "獨立化(遞迴)" +msgid "Save As..." +msgstr "另存為..." + msgid "Show in FileSystem" msgstr "在檔案系統中顯示" @@ -5714,9 +5717,6 @@ msgstr "從磁碟中載入現有的資源並編輯。" msgid "Save the currently edited resource." msgstr "儲存目前編輯的資源。" -msgid "Save As..." -msgstr "另存為..." - msgid "Extra resource options." msgstr "更多資源選項。" diff --git a/editor/translations/properties/de.po b/editor/translations/properties/de.po index 98ffb8212f..29c79c92f6 100644 --- a/editor/translations/properties/de.po +++ b/editor/translations/properties/de.po @@ -108,7 +108,7 @@ msgstr "" "Project-Id-Version: Godot Engine properties\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2023-11-11 00:20+0000\n" +"PO-Revision-Date: 2023-11-20 14:00+0000\n" "Last-Translator: Cerno_b <cerno.b@gmail.com>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/godot-" "properties/de/>\n" @@ -117,7 +117,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.2-dev\n" +"X-Generator: Weblate 5.2\n" msgid "Application" msgstr "Anwendung" @@ -5205,7 +5205,7 @@ msgid "Filter Clip Enabled" msgstr "Filter-Clip aktiviert" msgid "Tile Set" -msgstr "Tileset" +msgstr "Tile Set" msgid "Rendering Quadrant Size" msgstr "Renderquadrantengröße" @@ -8658,7 +8658,7 @@ msgid "Alternative Level" msgstr "Alternativer Level" msgid "Tile Shape" -msgstr "Tile-Shape" +msgstr "Tile-Form" msgid "Tile Layout" msgstr "Tile-Layout" @@ -9420,7 +9420,7 @@ msgid "Color Okhsl Hue" msgstr "Farbe Okhsl Farbton" msgid "BG" -msgstr "HG" +msgstr "BG" msgid "Preset FG" msgstr "Vorgabe VG" diff --git a/editor/translations/properties/pl.po b/editor/translations/properties/pl.po index ea55bd82b2..b2acad70ab 100644 --- a/editor/translations/properties/pl.po +++ b/editor/translations/properties/pl.po @@ -87,8 +87,8 @@ msgstr "" "Project-Id-Version: Godot Engine properties\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2023-11-12 10:25+0000\n" -"Last-Translator: Marcin Zieliński <czolgista83@gmail.com>\n" +"PO-Revision-Date: 2023-11-21 15:04+0000\n" +"Last-Translator: Tomek <kobewi4e@gmail.com>\n" "Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/godot-" "properties/pl/>\n" "Language: pl\n" @@ -97,7 +97,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 5.2-dev\n" +"X-Generator: Weblate 5.2\n" msgid "Application" msgstr "Aplikacja" @@ -421,7 +421,7 @@ msgid "Input Devices" msgstr "Urządzenia wejściowe" msgid "Compatibility" -msgstr "Kompatybilność" +msgstr "Kompatybilny" msgid "Device" msgstr "Urządzenie" diff --git a/editor/translations/properties/pt_BR.po b/editor/translations/properties/pt_BR.po index 84ef5ca496..8791950b78 100644 --- a/editor/translations/properties/pt_BR.po +++ b/editor/translations/properties/pt_BR.po @@ -161,13 +161,14 @@ # Romildo Franco <rtfranco@gmail.com>, 2023. # Felipe Bertola <eduardodelphinodepaula@gmail.com>, 2023. # Vittor Paulo Vieira da Costa <vittorpaulovc@gmail.com>, 2023. +# Matheus Macedo <mmanganelidemacedo@gmail.com>, 2023. msgid "" msgstr "" "Project-Id-Version: Godot Engine properties\n" "Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n" "POT-Creation-Date: 2016-05-30\n" -"PO-Revision-Date: 2023-11-03 04:56+0000\n" -"Last-Translator: Vittor Paulo Vieira da Costa <vittorpaulovc@gmail.com>\n" +"PO-Revision-Date: 2023-11-18 06:21+0000\n" +"Last-Translator: Matheus Macedo <mmanganelidemacedo@gmail.com>\n" "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/godot-" "engine/godot-properties/pt_BR/>\n" "Language: pt_BR\n" @@ -175,7 +176,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.2-dev\n" +"X-Generator: Weblate 5.2\n" msgid "Application" msgstr "Aplicação" @@ -309,6 +310,9 @@ msgstr "Intensidade da Panorâmica 3D" msgid "iOS" msgstr "iOS" +msgid "Mix With Others" +msgstr "Misturar com Outros" + msgid "Editor" msgstr "Editor" diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 4accdb4d21..b098a0d3d5 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1394,7 +1394,7 @@ String GDScript::debug_get_script_name(const Ref<Script> &p_script) { thread_local GDScript::UpdatableFuncPtr GDScript::func_ptrs_to_update_thread_local; GDScript::UpdatableFuncPtr *GDScript::func_ptrs_to_update_main_thread = &func_ptrs_to_update_thread_local; -GDScript::UpdatableFuncPtrElement *GDScript::_add_func_ptr_to_update(GDScriptFunction **p_func_ptr_ptr) { +List<GDScript::UpdatableFuncPtrElement>::Element *GDScript::_add_func_ptr_to_update(GDScriptFunction **p_func_ptr_ptr) { MutexLock lock(func_ptrs_to_update_mutex); List<UpdatableFuncPtrElement>::Element *result = func_ptrs_to_update_elems.push_back(UpdatableFuncPtrElement()); @@ -1405,7 +1405,7 @@ GDScript::UpdatableFuncPtrElement *GDScript::_add_func_ptr_to_update(GDScriptFun result->get().mutex = &func_ptrs_to_update_thread_local.mutex; if (likely(func_ptrs_to_update_thread_local.initialized)) { - return &result->get(); + return result; } func_ptrs_to_update_thread_local.initialized = true; @@ -1413,18 +1413,20 @@ GDScript::UpdatableFuncPtrElement *GDScript::_add_func_ptr_to_update(GDScriptFun func_ptrs_to_update.push_back(&func_ptrs_to_update_thread_local); - return &result->get(); + return result; } -void GDScript::_remove_func_ptr_to_update(const UpdatableFuncPtrElement *p_func_ptr_element) { +void GDScript::_remove_func_ptr_to_update(List<UpdatableFuncPtrElement>::Element *p_func_ptr_element) { // None of these checks should ever fail, unless there's a bug. // They can be removed once we are sure they never catch anything. // Left here now due to extra safety needs late in the release cycle. ERR_FAIL_NULL(p_func_ptr_element); - MutexLock lock(*p_func_ptr_element->mutex); - ERR_FAIL_NULL(p_func_ptr_element->element); - ERR_FAIL_NULL(p_func_ptr_element->mutex); - p_func_ptr_element->element->erase(); + MutexLock lock(func_ptrs_to_update_thread_local.mutex); + ERR_FAIL_NULL(p_func_ptr_element->get().element); + ERR_FAIL_NULL(p_func_ptr_element->get().mutex); + MutexLock lock2(*p_func_ptr_element->get().mutex); + p_func_ptr_element->get().element->erase(); + p_func_ptr_element->erase(); } void GDScript::_fixup_thread_function_bookkeeping() { diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 9b99f5ca0b..8d62334d69 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -134,8 +134,8 @@ class GDScript : public Script { List<UpdatableFuncPtrElement> func_ptrs_to_update_elems; Mutex func_ptrs_to_update_mutex; - UpdatableFuncPtrElement *_add_func_ptr_to_update(GDScriptFunction **p_func_ptr_ptr); - static void _remove_func_ptr_to_update(const UpdatableFuncPtrElement *p_func_ptr_element); + List<UpdatableFuncPtrElement>::Element *_add_func_ptr_to_update(GDScriptFunction **p_func_ptr_ptr); + static void _remove_func_ptr_to_update(List<UpdatableFuncPtrElement>::Element *p_func_ptr_element); static void _fixup_thread_function_bookkeeping(); diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 724715d9e5..7c342cc41a 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -2745,8 +2745,6 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(p_call); GDScriptParser::Node::Type callee_type = call->get_callee_type(); - GDScriptCompletionIdentifier connect_base; - if (callee_type == GDScriptParser::Node::SUBSCRIPT) { const GDScriptParser::SubscriptNode *subscript = static_cast<const GDScriptParser::SubscriptNode *>(call->callee); diff --git a/modules/gdscript/gdscript_lambda_callable.h b/modules/gdscript/gdscript_lambda_callable.h index d961f18852..405d7c1823 100644 --- a/modules/gdscript/gdscript_lambda_callable.h +++ b/modules/gdscript/gdscript_lambda_callable.h @@ -45,7 +45,7 @@ class GDScriptLambdaCallable : public CallableCustom { GDScriptFunction *function = nullptr; Ref<GDScript> script; uint32_t h; - GDScript::UpdatableFuncPtrElement *updatable_func_ptr_element = nullptr; + List<GDScript::UpdatableFuncPtrElement>::Element *updatable_func_ptr_element = nullptr; Vector<Variant> captures; @@ -72,7 +72,7 @@ class GDScriptLambdaSelfCallable : public CallableCustom { Ref<RefCounted> reference; // For objects that are RefCounted, keep a reference. Object *object = nullptr; // For non RefCounted objects, use a direct pointer. uint32_t h; - GDScript::UpdatableFuncPtrElement *updatable_func_ptr_element = nullptr; + List<GDScript::UpdatableFuncPtrElement>::Element *updatable_func_ptr_element = nullptr; Vector<Variant> captures; diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index 6dd8a98652..a64aaf6820 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -37,6 +37,12 @@ #include "core/templates/vector.h" #include "core/variant/variant.h" +#ifdef MINGW_ENABLED +#undef CONST +#undef IN +#undef VOID +#endif + class GDScriptTokenizer { public: enum CursorPlace { diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp index 2fad475e92..9587604e56 100644 --- a/modules/gltf/editor/editor_scene_importer_blend.cpp +++ b/modules/gltf/editor/editor_scene_importer_blend.cpp @@ -45,6 +45,11 @@ #include "main/main.h" #include "scene/gui/line_edit.h" +#ifdef MINGW_ENABLED +#define near +#define far +#endif + #ifdef WINDOWS_ENABLED #include <shlwapi.h> #endif diff --git a/platform/android/java_godot_view_wrapper.h b/platform/android/java_godot_view_wrapper.h index e5b04e4866..5f554aa2d6 100644 --- a/platform/android/java_godot_view_wrapper.h +++ b/platform/android/java_godot_view_wrapper.h @@ -38,7 +38,7 @@ #include <android/log.h> #include <jni.h> -// Class that makes functions in java/src/org/godotengine/godot/GodotView.java callable from C++ +// Class that makes functions in java/src/org/godotengine/godot/GodotRenderView.java callable from C++ class GodotJavaViewWrapper { private: jclass _cls; diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h index 7c6327c9e1..920df958c2 100644 --- a/platform/android/java_godot_wrapper.h +++ b/platform/android/java_godot_wrapper.h @@ -39,7 +39,7 @@ #include <android/log.h> #include <jni.h> -// Class that makes functions in java/src/org/godotengine/godot/Godot.java callable from C++ +// Class that makes functions in java/src/org/godotengine/godot/Godot.kt callable from C++ class GodotJavaWrapper { private: jobject godot_instance; diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp index 94984a74b6..c0e052865f 100644 --- a/platform/ios/export/export_plugin.cpp +++ b/platform/ios/export/export_plugin.cpp @@ -2071,6 +2071,22 @@ bool EditorExportPlatformIOS::is_package_name_valid(const String &p_package, Str } #ifdef MACOS_ENABLED +bool EditorExportPlatformIOS::_check_xcode_install() { + static bool xcode_found = false; + if (!xcode_found) { + String xcode_path; + List<String> args; + args.push_back("-p"); + int ec = 0; + Error err = OS::get_singleton()->execute("xcode-select", args, &xcode_path, &ec, true); + if (err != OK || ec != 0) { + return false; + } + xcode_found = DirAccess::dir_exists_absolute(xcode_path.strip_edges()); + } + return xcode_found; +} + void EditorExportPlatformIOS::_check_for_changes_poll_thread(void *ud) { EditorExportPlatformIOS *ea = static_cast<EditorExportPlatformIOS *>(ud); @@ -2138,7 +2154,7 @@ void EditorExportPlatformIOS::_check_for_changes_poll_thread(void *ud) { } // Enum simulators - if (FileAccess::exists("/usr/bin/xcrun") || FileAccess::exists("/bin/xcrun")) { + if (_check_xcode_install() && (FileAccess::exists("/usr/bin/xcrun") || FileAccess::exists("/bin/xcrun"))) { String devices; List<String> args; args.push_back("simctl"); diff --git a/platform/ios/export/export_plugin.h b/platform/ios/export/export_plugin.h index 27a4d73fcd..951017ddae 100644 --- a/platform/ios/export/export_plugin.h +++ b/platform/ios/export/export_plugin.h @@ -81,6 +81,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform { Thread check_for_changes_thread; SafeFlag quit_request; + static bool _check_xcode_install(); static void _check_for_changes_poll_thread(void *ud); #endif diff --git a/platform/windows/gl_manager_windows_native.cpp b/platform/windows/gl_manager_windows_native.cpp index b350786d11..8af32395b7 100644 --- a/platform/windows/gl_manager_windows_native.cpp +++ b/platform/windows/gl_manager_windows_native.cpp @@ -104,8 +104,8 @@ static bool nvapi_err_check(const char *msg, int status) { } // On windows we have to disable threaded optimization when using NVIDIA graphics cards -// to avoid stuttering, see https://github.com/microsoft/vscode-cpptools/issues/6592 -// also see https://github.com/Ryujinx/Ryujinx/blob/master/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs +// to avoid stuttering, see https://stackoverflow.com/questions/36959508/nvidia-graphics-driver-causing-noticeable-frame-stuttering/37632948 +// also see https://github.com/Ryujinx/Ryujinx/blob/master/src/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs void GLManagerNative_Windows::_nvapi_disable_threaded_optimization() { HMODULE nvapi = 0; #ifdef _WIN64 @@ -149,6 +149,10 @@ void GLManagerNative_Windows::_nvapi_disable_threaded_optimization() { NvDRSSessionHandle session_handle; + if (NvAPI_DRS_CreateSession == nullptr) { + return; + } + if (!nvapi_err_check("NVAPI: Error creating DRS session", NvAPI_DRS_CreateSession(&session_handle))) { NvAPI_Unload(); return; diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h index aa302ded4a..8de607806e 100644 --- a/scene/3d/camera_3d.h +++ b/scene/3d/camera_3d.h @@ -36,6 +36,11 @@ #include "scene/resources/camera_attributes.h" #include "scene/resources/environment.h" +#ifdef MINGW_ENABLED +#undef near +#undef far +#endif + class Camera3D : public Node3D { GDCLASS(Camera3D, Node3D); diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index 79cd1056dd..5603b2dbe4 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -72,6 +72,11 @@ void SceneDebugger::deinitialize() { } } +#ifdef MINGW_ENABLED +#undef near +#undef far +#endif + #ifdef DEBUG_ENABLED Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured) { SceneTree *scene_tree = SceneTree::get_singleton(); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index d3347bc304..cf80bd6c6f 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -515,6 +515,10 @@ bool SceneTree::process(double p_time) { _flush_delete_queue(); + if (unlikely(pending_new_scene)) { + _flush_scene_change(); + } + process_timers(p_time, false); //go through timers process_tweens(p_time, false); @@ -550,10 +554,6 @@ bool SceneTree::process(double p_time) { #endif // _3D_DISABLED #endif // TOOLS_ENABLED - if (unlikely(pending_new_scene)) { - _flush_scene_change(); - } - return _quit; } diff --git a/scene/resources/camera_attributes.cpp b/scene/resources/camera_attributes.cpp index 7c46729af3..323241200c 100644 --- a/scene/resources/camera_attributes.cpp +++ b/scene/resources/camera_attributes.cpp @@ -373,6 +373,11 @@ real_t CameraAttributesPhysical::get_fov() const { return frustum_fov; } +#ifdef MINGW_ENABLED +#undef near +#undef far +#endif + void CameraAttributesPhysical::_update_frustum() { //https://en.wikipedia.org/wiki/Circle_of_confusion#Circle_of_confusion_diameter_limit_based_on_d/1500 Vector2i sensor_size = Vector2i(36, 24); // Matches high-end DSLR, could be made variable if there is demand. diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 5134f4d545..bba1f62023 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -853,7 +853,6 @@ void SceneShaderForwardClustered::set_default_specialization_constants(const Vec void SceneShaderForwardClustered::enable_advanced_shader_group(bool p_needs_multiview) { if (p_needs_multiview || RendererCompositorRD::get_singleton()->is_xr_enabled()) { shader.enable_group(SHADER_GROUP_ADVANCED_MULTIVIEW); - } else { - shader.enable_group(SHADER_GROUP_ADVANCED); } + shader.enable_group(SHADER_GROUP_ADVANCED); } diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp index a389e3e767..cd89bb314b 100644 --- a/servers/rendering/renderer_scene_render.cpp +++ b/servers/rendering/renderer_scene_render.cpp @@ -47,6 +47,11 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, taa_jitter = p_taa_jitter; } +#ifdef MINGW_ENABLED +#undef near +#undef far +#endif + void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect) { ERR_FAIL_COND_MSG(p_view_count != 2, "Incorrect view count for stereoscopic view"); diff --git a/thirdparty/README.md b/thirdparty/README.md index 4fcd85b36e..0baa5f85bc 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -515,6 +515,24 @@ error metrics instead of a combination of distance and attribute errors. Patches for both changes can be found in the `patches` directory. +## mingw-std-threads + +- Upstream: https://github.com/meganz/mingw-std-threads +- Version: git (c931bac289dd431f1dd30fc4a5d1a7be36668073, 2023) +- License: BSD-2-clause + +Files extracted from upstream repository: + +- `LICENSE` +- `mingw.condition_variable.h` +- `mingw.invoke.h` +- `mingw.mutex.h` +- `mingw.shared_mutex.h` +- `mingw.thread.h` + +Once copied, apply `no_except.patch` (needed because Godot is built without exceptions). + + ## minimp3 - Upstream: https://github.com/lieff/minimp3 diff --git a/thirdparty/mingw-std-threads/LICENSE b/thirdparty/mingw-std-threads/LICENSE new file mode 100644 index 0000000000..ac525cf203 --- /dev/null +++ b/thirdparty/mingw-std-threads/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2016, Mega Limited +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/thirdparty/mingw-std-threads/mingw.condition_variable.h b/thirdparty/mingw-std-threads/mingw.condition_variable.h new file mode 100644 index 0000000000..f9e248c154 --- /dev/null +++ b/thirdparty/mingw-std-threads/mingw.condition_variable.h @@ -0,0 +1,564 @@ +/** +* @file condition_variable.h +* @brief std::condition_variable implementation for MinGW +* +* (c) 2013-2016 by Mega Limited, Auckland, New Zealand +* @author Alexander Vassilev +* +* @copyright Simplified (2-clause) BSD License. +* You should have received a copy of the license along with this +* program. +* +* This code is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +* @note +* This file may become part of the mingw-w64 runtime package. If/when this happens, +* the appropriate license will be added, i.e. this code will become dual-licensed, +* and the current BSD 2-clause license will stay. +*/ + +#ifndef MINGW_CONDITIONAL_VARIABLE_H +#define MINGW_CONDITIONAL_VARIABLE_H + +#if !defined(__cplusplus) || (__cplusplus < 201103L) +#error A C++11 compiler is required! +#endif +// Use the standard classes for std::, if available. +#include <condition_variable> + +#include <cassert> +#include <chrono> +#include <system_error> + +#include <sdkddkver.h> // Detect Windows version. +#if (WINVER < _WIN32_WINNT_VISTA) +#include <atomic> +#endif +#if (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)) +#pragma message "The Windows API that MinGW-w32 provides is not fully compatible\ + with Microsoft's API. We'll try to work around this, but we can make no\ + guarantees. This problem does not exist in MinGW-w64." +#include <windows.h> // No further granularity can be expected. +#else +#if (WINVER < _WIN32_WINNT_VISTA) +#include <windef.h> +#include <winbase.h> // For CreateSemaphore +#include <handleapi.h> +#endif +#include <synchapi.h> +#endif + +#include "mingw.mutex.h" +#include "mingw.shared_mutex.h" + +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501) +#error To use the MinGW-std-threads library, you will need to define the macro _WIN32_WINNT to be 0x0501 (Windows XP) or higher. +#endif + +namespace mingw_stdthread +{ +#if defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS) +enum class cv_status { no_timeout, timeout }; +#else +using std::cv_status; +#endif +namespace xp +{ +// Include the XP-compatible condition_variable classes only if actually +// compiling for XP. The XP-compatible classes are slower than the newer +// versions, and depend on features not compatible with Windows Phone 8. +#if (WINVER < _WIN32_WINNT_VISTA) +class condition_variable_any +{ + recursive_mutex mMutex {}; + std::atomic<int> mNumWaiters {0}; + HANDLE mSemaphore; + HANDLE mWakeEvent {}; +public: + using native_handle_type = HANDLE; + native_handle_type native_handle() + { + return mSemaphore; + } + condition_variable_any(const condition_variable_any&) = delete; + condition_variable_any& operator=(const condition_variable_any&) = delete; + condition_variable_any() + : mSemaphore(CreateSemaphoreA(NULL, 0, 0xFFFF, NULL)) + { + if (mSemaphore == NULL) + __builtin_trap(); + mWakeEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (mWakeEvent == NULL) + { + CloseHandle(mSemaphore); + __builtin_trap(); + } + } + ~condition_variable_any() + { + CloseHandle(mWakeEvent); + CloseHandle(mSemaphore); + } +private: + template <class M> + bool wait_impl(M& lock, DWORD timeout) + { + { + lock_guard<recursive_mutex> guard(mMutex); + mNumWaiters++; + } + lock.unlock(); + DWORD ret = WaitForSingleObject(mSemaphore, timeout); + + mNumWaiters--; + SetEvent(mWakeEvent); + lock.lock(); + if (ret == WAIT_OBJECT_0) + return true; + else if (ret == WAIT_TIMEOUT) + return false; +//2 possible cases: +//1)The point in notify_all() where we determine the count to +//increment the semaphore with has not been reached yet: +//we just need to decrement mNumWaiters, but setting the event does not hurt +// +//2)Semaphore has just been released with mNumWaiters just before +//we decremented it. This means that the semaphore count +//after all waiters finish won't be 0 - because not all waiters +//woke up by acquiring the semaphore - we woke up by a timeout. +//The notify_all() must handle this gracefully +// + else + { + using namespace std; + __builtin_trap(); + } + } +public: + template <class M> + void wait(M& lock) + { + wait_impl(lock, INFINITE); + } + template <class M, class Predicate> + void wait(M& lock, Predicate pred) + { + while(!pred()) + { + wait(lock); + }; + } + + void notify_all() noexcept + { + lock_guard<recursive_mutex> lock(mMutex); //block any further wait requests until all current waiters are unblocked + if (mNumWaiters.load() <= 0) + return; + + ReleaseSemaphore(mSemaphore, mNumWaiters, NULL); + while(mNumWaiters > 0) + { + auto ret = WaitForSingleObject(mWakeEvent, 1000); + if (ret == WAIT_FAILED || ret == WAIT_ABANDONED) + std::terminate(); + } + assert(mNumWaiters == 0); +//in case some of the waiters timed out just after we released the +//semaphore by mNumWaiters, it won't be zero now, because not all waiters +//woke up by acquiring the semaphore. So we must zero the semaphore before +//we accept waiters for the next event +//See _wait_impl for details + while(WaitForSingleObject(mSemaphore, 0) == WAIT_OBJECT_0); + } + void notify_one() noexcept + { + lock_guard<recursive_mutex> lock(mMutex); + int targetWaiters = mNumWaiters.load() - 1; + if (targetWaiters <= -1) + return; + ReleaseSemaphore(mSemaphore, 1, NULL); + while(mNumWaiters > targetWaiters) + { + auto ret = WaitForSingleObject(mWakeEvent, 1000); + if (ret == WAIT_FAILED || ret == WAIT_ABANDONED) + std::terminate(); + } + assert(mNumWaiters == targetWaiters); + } + template <class M, class Rep, class Period> + cv_status wait_for(M& lock, + const std::chrono::duration<Rep, Period>& rel_time) + { + using namespace std::chrono; + auto timeout = duration_cast<milliseconds>(rel_time).count(); + DWORD waittime = (timeout < INFINITE) ? ((timeout < 0) ? 0 : static_cast<DWORD>(timeout)) : (INFINITE - 1); + bool ret = wait_impl(lock, waittime) || (timeout >= INFINITE); + return ret?cv_status::no_timeout:cv_status::timeout; + } + + template <class M, class Rep, class Period, class Predicate> + bool wait_for(M& lock, + const std::chrono::duration<Rep, Period>& rel_time, Predicate pred) + { + return wait_until(lock, std::chrono::steady_clock::now()+rel_time, pred); + } + template <class M, class Clock, class Duration> + cv_status wait_until (M& lock, + const std::chrono::time_point<Clock,Duration>& abs_time) + { + return wait_for(lock, abs_time - Clock::now()); + } + template <class M, class Clock, class Duration, class Predicate> + bool wait_until (M& lock, + const std::chrono::time_point<Clock, Duration>& abs_time, + Predicate pred) + { + while (!pred()) + { + if (wait_until(lock, abs_time) == cv_status::timeout) + { + return pred(); + } + } + return true; + } +}; +class condition_variable: condition_variable_any +{ + using base = condition_variable_any; +public: + using base::native_handle_type; + using base::native_handle; + using base::base; + using base::notify_all; + using base::notify_one; + void wait(unique_lock<mutex> &lock) + { + base::wait(lock); + } + template <class Predicate> + void wait(unique_lock<mutex>& lock, Predicate pred) + { + base::wait(lock, pred); + } + template <class Rep, class Period> + cv_status wait_for(unique_lock<mutex>& lock, const std::chrono::duration<Rep, Period>& rel_time) + { + return base::wait_for(lock, rel_time); + } + template <class Rep, class Period, class Predicate> + bool wait_for(unique_lock<mutex>& lock, const std::chrono::duration<Rep, Period>& rel_time, Predicate pred) + { + return base::wait_for(lock, rel_time, pred); + } + template <class Clock, class Duration> + cv_status wait_until (unique_lock<mutex>& lock, const std::chrono::time_point<Clock,Duration>& abs_time) + { + return base::wait_until(lock, abs_time); + } + template <class Clock, class Duration, class Predicate> + bool wait_until (unique_lock<mutex>& lock, const std::chrono::time_point<Clock, Duration>& abs_time, Predicate pred) + { + return base::wait_until(lock, abs_time, pred); + } +}; +#endif // Compiling for XP +} // Namespace mingw_stdthread::xp + +#if (WINVER >= _WIN32_WINNT_VISTA) +namespace vista +{ +// If compiling for Vista or higher, use the native condition variable. +class condition_variable +{ + static constexpr DWORD kInfinite = 0xffffffffl; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" + CONDITION_VARIABLE cvariable_ = CONDITION_VARIABLE_INIT; +#pragma GCC diagnostic pop + + friend class condition_variable_any; + +#if STDMUTEX_RECURSION_CHECKS + template<typename MTX> + inline static void before_wait (MTX * pmutex) + { + pmutex->mOwnerThread.checkSetOwnerBeforeUnlock(); + } + template<typename MTX> + inline static void after_wait (MTX * pmutex) + { + pmutex->mOwnerThread.setOwnerAfterLock(GetCurrentThreadId()); + } +#else + inline static void before_wait (void *) { } + inline static void after_wait (void *) { } +#endif + + bool wait_impl (unique_lock<xp::mutex> & lock, DWORD time) + { + using mutex_handle_type = typename xp::mutex::native_handle_type; + static_assert(std::is_same<mutex_handle_type, PCRITICAL_SECTION>::value, + "Native Win32 condition variable requires std::mutex to \ +use native Win32 critical section objects."); + xp::mutex * pmutex = lock.release(); + before_wait(pmutex); + BOOL success = SleepConditionVariableCS(&cvariable_, + pmutex->native_handle(), + time); + after_wait(pmutex); + lock = unique_lock<xp::mutex>(*pmutex, adopt_lock); + return success; + } + + bool wait_unique (windows7::mutex * pmutex, DWORD time) + { + before_wait(pmutex); + BOOL success = SleepConditionVariableSRW( native_handle(), + pmutex->native_handle(), + time, +// CONDITION_VARIABLE_LOCKMODE_SHARED has a value not specified by +// Microsoft's Dev Center, but is known to be (convertible to) a ULONG. To +// ensure that the value passed to this function is not equal to Microsoft's +// constant, we can either use a static_assert, or simply generate an +// appropriate value. + !CONDITION_VARIABLE_LOCKMODE_SHARED); + after_wait(pmutex); + return success; + } + bool wait_impl (unique_lock<windows7::mutex> & lock, DWORD time) + { + windows7::mutex * pmutex = lock.release(); + bool success = wait_unique(pmutex, time); + lock = unique_lock<windows7::mutex>(*pmutex, adopt_lock); + return success; + } +public: + using native_handle_type = PCONDITION_VARIABLE; + native_handle_type native_handle (void) + { + return &cvariable_; + } + + condition_variable (void) = default; + ~condition_variable (void) = default; + + condition_variable (const condition_variable &) = delete; + condition_variable & operator= (const condition_variable &) = delete; + + void notify_one (void) noexcept + { + WakeConditionVariable(&cvariable_); + } + + void notify_all (void) noexcept + { + WakeAllConditionVariable(&cvariable_); + } + + void wait (unique_lock<mutex> & lock) + { + wait_impl(lock, kInfinite); + } + + template<class Predicate> + void wait (unique_lock<mutex> & lock, Predicate pred) + { + while (!pred()) + wait(lock); + } + + template <class Rep, class Period> + cv_status wait_for(unique_lock<mutex>& lock, + const std::chrono::duration<Rep, Period>& rel_time) + { + using namespace std::chrono; + auto timeout = duration_cast<milliseconds>(rel_time).count(); + DWORD waittime = (timeout < kInfinite) ? ((timeout < 0) ? 0 : static_cast<DWORD>(timeout)) : (kInfinite - 1); + bool result = wait_impl(lock, waittime) || (timeout >= kInfinite); + return result ? cv_status::no_timeout : cv_status::timeout; + } + + template <class Rep, class Period, class Predicate> + bool wait_for(unique_lock<mutex>& lock, + const std::chrono::duration<Rep, Period>& rel_time, + Predicate pred) + { + return wait_until(lock, + std::chrono::steady_clock::now() + rel_time, + std::move(pred)); + } + template <class Clock, class Duration> + cv_status wait_until (unique_lock<mutex>& lock, + const std::chrono::time_point<Clock,Duration>& abs_time) + { + return wait_for(lock, abs_time - Clock::now()); + } + template <class Clock, class Duration, class Predicate> + bool wait_until (unique_lock<mutex>& lock, + const std::chrono::time_point<Clock, Duration>& abs_time, + Predicate pred) + { + while (!pred()) + { + if (wait_until(lock, abs_time) == cv_status::timeout) + { + return pred(); + } + } + return true; + } +}; + +class condition_variable_any +{ + static constexpr DWORD kInfinite = 0xffffffffl; + using native_shared_mutex = windows7::shared_mutex; + + condition_variable internal_cv_ {}; +// When available, the SRW-based mutexes should be faster than the +// CriticalSection-based mutexes. Only try_lock will be unavailable in Vista, +// and try_lock is not used by condition_variable_any. + windows7::mutex internal_mutex_ {}; + + template<class L> + bool wait_impl (L & lock, DWORD time) + { + unique_lock<decltype(internal_mutex_)> internal_lock(internal_mutex_); + lock.unlock(); + bool success = internal_cv_.wait_impl(internal_lock, time); + lock.lock(); + return success; + } +// If the lock happens to be called on a native Windows mutex, skip any extra +// contention. + inline bool wait_impl (unique_lock<mutex> & lock, DWORD time) + { + return internal_cv_.wait_impl(lock, time); + } +// Some shared_mutex functionality is available even in Vista, but it's not +// until Windows 7 that a full implementation is natively possible. The class +// itself is defined, with missing features, at the Vista feature level. + bool wait_impl (unique_lock<native_shared_mutex> & lock, DWORD time) + { + native_shared_mutex * pmutex = lock.release(); + bool success = internal_cv_.wait_unique(pmutex, time); + lock = unique_lock<native_shared_mutex>(*pmutex, adopt_lock); + return success; + } + bool wait_impl (shared_lock<native_shared_mutex> & lock, DWORD time) + { + native_shared_mutex * pmutex = lock.release(); + BOOL success = SleepConditionVariableSRW(native_handle(), + pmutex->native_handle(), time, + CONDITION_VARIABLE_LOCKMODE_SHARED); + lock = shared_lock<native_shared_mutex>(*pmutex, adopt_lock); + return success; + } +public: + using native_handle_type = typename condition_variable::native_handle_type; + + native_handle_type native_handle (void) + { + return internal_cv_.native_handle(); + } + + void notify_one (void) noexcept + { + internal_cv_.notify_one(); + } + + void notify_all (void) noexcept + { + internal_cv_.notify_all(); + } + + condition_variable_any (void) = default; + ~condition_variable_any (void) = default; + + template<class L> + void wait (L & lock) + { + wait_impl(lock, kInfinite); + } + + template<class L, class Predicate> + void wait (L & lock, Predicate pred) + { + while (!pred()) + wait(lock); + } + + template <class L, class Rep, class Period> + cv_status wait_for(L& lock, const std::chrono::duration<Rep,Period>& period) + { + using namespace std::chrono; + auto timeout = duration_cast<milliseconds>(period).count(); + DWORD waittime = (timeout < kInfinite) ? ((timeout < 0) ? 0 : static_cast<DWORD>(timeout)) : (kInfinite - 1); + bool result = wait_impl(lock, waittime) || (timeout >= kInfinite); + return result ? cv_status::no_timeout : cv_status::timeout; + } + + template <class L, class Rep, class Period, class Predicate> + bool wait_for(L& lock, const std::chrono::duration<Rep, Period>& period, + Predicate pred) + { + return wait_until(lock, std::chrono::steady_clock::now() + period, + std::move(pred)); + } + template <class L, class Clock, class Duration> + cv_status wait_until (L& lock, + const std::chrono::time_point<Clock,Duration>& abs_time) + { + return wait_for(lock, abs_time - Clock::now()); + } + template <class L, class Clock, class Duration, class Predicate> + bool wait_until (L& lock, + const std::chrono::time_point<Clock, Duration>& abs_time, + Predicate pred) + { + while (!pred()) + { + if (wait_until(lock, abs_time) == cv_status::timeout) + { + return pred(); + } + } + return true; + } +}; +} // Namespace vista +#endif +#if WINVER < 0x0600 +using xp::condition_variable; +using xp::condition_variable_any; +#else +using vista::condition_variable; +using vista::condition_variable_any; +#endif +} // Namespace mingw_stdthread + +// Push objects into std, but only if they are not already there. +namespace std +{ +// Because of quirks of the compiler, the common "using namespace std;" +// directive would flatten the namespaces and introduce ambiguity where there +// was none. Direct specification (std::), however, would be unaffected. +// Take the safe option, and include only in the presence of MinGW's win32 +// implementation. +#if defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS) +using mingw_stdthread::cv_status; +using mingw_stdthread::condition_variable; +using mingw_stdthread::condition_variable_any; +#elif !defined(MINGW_STDTHREAD_REDUNDANCY_WARNING) // Skip repetition +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#pragma message "This version of MinGW seems to include a win32 port of\ + pthreads, and probably already has C++11 std threading classes implemented,\ + based on pthreads. These classes, found in namespace std, are not overridden\ + by the mingw-std-thread library. If you would still like to use this\ + implementation (as it is more lightweight), use the classes provided in\ + namespace mingw_stdthread." +#endif +} +#endif // MINGW_CONDITIONAL_VARIABLE_H diff --git a/thirdparty/mingw-std-threads/mingw.invoke.h b/thirdparty/mingw-std-threads/mingw.invoke.h new file mode 100644 index 0000000000..d5c9dd38bb --- /dev/null +++ b/thirdparty/mingw-std-threads/mingw.invoke.h @@ -0,0 +1,109 @@ +/// \file mingw.invoke.h +/// \brief Lightweight `invoke` implementation, for C++11 and C++14. +/// +/// (c) 2018-2019 by Nathaniel J. McClatchey, San Jose, CA, United States +/// \author Nathaniel J. McClatchey, PhD +/// +/// \copyright Simplified (2-clause) BSD License. +/// +/// \note This file may become part of the mingw-w64 runtime package. If/when +/// this happens, the appropriate license will be added, i.e. this code will +/// become dual-licensed, and the current BSD 2-clause license will stay. + +#ifndef MINGW_INVOKE_H_ +#define MINGW_INVOKE_H_ + +#include <type_traits> // For std::result_of, etc. +#include <utility> // For std::forward +#include <functional> // For std::reference_wrapper + +namespace mingw_stdthread +{ +namespace detail +{ +// For compatibility, implement std::invoke for C++11 and C++14 +#if __cplusplus < 201703L + template<bool PMemFunc, bool PMemData> + struct Invoker + { + template<class F, class... Args> + inline static typename std::result_of<F(Args...)>::type invoke (F&& f, Args&&... args) + { + return std::forward<F>(f)(std::forward<Args>(args)...); + } + }; + template<bool> + struct InvokerHelper; + + template<> + struct InvokerHelper<false> + { + template<class T1> + inline static auto get (T1&& t1) -> decltype(*std::forward<T1>(t1)) + { + return *std::forward<T1>(t1); + } + + template<class T1> + inline static auto get (const std::reference_wrapper<T1>& t1) -> decltype(t1.get()) + { + return t1.get(); + } + }; + + template<> + struct InvokerHelper<true> + { + template<class T1> + inline static auto get (T1&& t1) -> decltype(std::forward<T1>(t1)) + { + return std::forward<T1>(t1); + } + }; + + template<> + struct Invoker<true, false> + { + template<class T, class F, class T1, class... Args> + inline static auto invoke (F T::* f, T1&& t1, Args&&... args) ->\ + decltype((InvokerHelper<std::is_base_of<T,typename std::decay<T1>::type>::value>::get(std::forward<T1>(t1)).*f)(std::forward<Args>(args)...)) + { + return (InvokerHelper<std::is_base_of<T,typename std::decay<T1>::type>::value>::get(std::forward<T1>(t1)).*f)(std::forward<Args>(args)...); + } + }; + + template<> + struct Invoker<false, true> + { + template<class T, class F, class T1, class... Args> + inline static auto invoke (F T::* f, T1&& t1, Args&&... args) ->\ + decltype(InvokerHelper<std::is_base_of<T,typename std::decay<T1>::type>::value>::get(t1).*f) + { + return InvokerHelper<std::is_base_of<T,typename std::decay<T1>::type>::value>::get(t1).*f; + } + }; + + template<class F, class... Args> + struct InvokeResult + { + typedef Invoker<std::is_member_function_pointer<typename std::remove_reference<F>::type>::value, + std::is_member_object_pointer<typename std::remove_reference<F>::type>::value && + (sizeof...(Args) == 1)> invoker; + inline static auto invoke (F&& f, Args&&... args) -> decltype(invoker::invoke(std::forward<F>(f), std::forward<Args>(args)...)) + { + return invoker::invoke(std::forward<F>(f), std::forward<Args>(args)...); + } + }; + + template<class F, class...Args> + auto invoke (F&& f, Args&&... args) -> decltype(InvokeResult<F, Args...>::invoke(std::forward<F>(f), std::forward<Args>(args)...)) + { + return InvokeResult<F, Args...>::invoke(std::forward<F>(f), std::forward<Args>(args)...); + } +#else + using std::invoke; +#endif +} // Namespace "detail" +} // Namespace "mingw_stdthread" + +#endif diff --git a/thirdparty/mingw-std-threads/mingw.mutex.h b/thirdparty/mingw-std-threads/mingw.mutex.h new file mode 100644 index 0000000000..73698d13cb --- /dev/null +++ b/thirdparty/mingw-std-threads/mingw.mutex.h @@ -0,0 +1,500 @@ +/** +* @file mingw.mutex.h +* @brief std::mutex et al implementation for MinGW +** (c) 2013-2016 by Mega Limited, Auckland, New Zealand +* @author Alexander Vassilev +* +* @copyright Simplified (2-clause) BSD License. +* You should have received a copy of the license along with this +* program. +* +* This code is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +* @note +* This file may become part of the mingw-w64 runtime package. If/when this happens, +* the appropriate license will be added, i.e. this code will become dual-licensed, +* and the current BSD 2-clause license will stay. +*/ + +#ifndef WIN32STDMUTEX_H +#define WIN32STDMUTEX_H + +#if !defined(__cplusplus) || (__cplusplus < 201103L) +#error A C++11 compiler is required! +#endif +// Recursion checks on non-recursive locks have some performance penalty, and +// the C++ standard does not mandate them. The user might want to explicitly +// enable or disable such checks. If the user has no preference, enable such +// checks in debug builds, but not in release builds. +#ifdef STDMUTEX_RECURSION_CHECKS +#elif defined(NDEBUG) +#define STDMUTEX_RECURSION_CHECKS 0 +#else +#define STDMUTEX_RECURSION_CHECKS 1 +#endif + +#include <chrono> +#include <system_error> +#include <atomic> +#include <mutex> //need for call_once() + +#if STDMUTEX_RECURSION_CHECKS || !defined(NDEBUG) +#include <cstdio> +#endif + +#include <sdkddkver.h> // Detect Windows version. + +#if (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)) +#pragma message "The Windows API that MinGW-w32 provides is not fully compatible\ + with Microsoft's API. We'll try to work around this, but we can make no\ + guarantees. This problem does not exist in MinGW-w64." +#include <windows.h> // No further granularity can be expected. +#else +#if STDMUTEX_RECURSION_CHECKS +#include <processthreadsapi.h> // For GetCurrentThreadId +#endif +#include <synchapi.h> // For InitializeCriticalSection, etc. +#include <errhandlingapi.h> // For GetLastError +#include <handleapi.h> +#endif + +// Need for the implementation of invoke +#include "mingw.invoke.h" + +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501) +#error To use the MinGW-std-threads library, you will need to define the macro _WIN32_WINNT to be 0x0501 (Windows XP) or higher. +#endif + +namespace mingw_stdthread +{ +// The _NonRecursive class has mechanisms that do not play nice with direct +// manipulation of the native handle. This forward declaration is part of +// a friend class declaration. +#if STDMUTEX_RECURSION_CHECKS +namespace vista +{ +class condition_variable; +} +#endif +// To make this namespace equivalent to the thread-related subset of std, +// pull in the classes and class templates supplied by std but not by this +// implementation. +using std::lock_guard; +using std::unique_lock; +using std::adopt_lock_t; +using std::defer_lock_t; +using std::try_to_lock_t; +using std::adopt_lock; +using std::defer_lock; +using std::try_to_lock; + +class recursive_mutex +{ + CRITICAL_SECTION mHandle; +public: + typedef LPCRITICAL_SECTION native_handle_type; + native_handle_type native_handle() {return &mHandle;} + recursive_mutex() noexcept : mHandle() + { + InitializeCriticalSection(&mHandle); + } + recursive_mutex (const recursive_mutex&) = delete; + recursive_mutex& operator=(const recursive_mutex&) = delete; + ~recursive_mutex() noexcept + { + DeleteCriticalSection(&mHandle); + } + void lock() + { + EnterCriticalSection(&mHandle); + } + void unlock() + { + LeaveCriticalSection(&mHandle); + } + bool try_lock() + { + return (TryEnterCriticalSection(&mHandle)!=0); + } +}; + +#if STDMUTEX_RECURSION_CHECKS +struct _OwnerThread +{ +// If this is to be read before locking, then the owner-thread variable must +// be atomic to prevent a torn read from spuriously causing errors. + std::atomic<DWORD> mOwnerThread; + constexpr _OwnerThread () noexcept : mOwnerThread(0) {} + static void on_deadlock (void) + { + using namespace std; + fprintf(stderr, "FATAL: Recursive locking of non-recursive mutex\ + detected. Throwing system exception\n"); + fflush(stderr); + __builtin_trap(); + } + DWORD checkOwnerBeforeLock() const + { + DWORD self = GetCurrentThreadId(); + if (mOwnerThread.load(std::memory_order_relaxed) == self) + on_deadlock(); + return self; + } + void setOwnerAfterLock(DWORD id) + { + mOwnerThread.store(id, std::memory_order_relaxed); + } + void checkSetOwnerBeforeUnlock() + { + DWORD self = GetCurrentThreadId(); + if (mOwnerThread.load(std::memory_order_relaxed) != self) + on_deadlock(); + mOwnerThread.store(0, std::memory_order_relaxed); + } +}; +#endif + +// Though the Slim Reader-Writer (SRW) locks used here are not complete until +// Windows 7, implementing partial functionality in Vista will simplify the +// interaction with condition variables. + +//Define SRWLOCK_INIT. + +#if !defined(SRWLOCK_INIT) +#pragma message "SRWLOCK_INIT macro is not defined. Defining automatically." +#define SRWLOCK_INIT {0} +#endif + +#if defined(_WIN32) && (WINVER >= _WIN32_WINNT_VISTA) +namespace windows7 +{ +class mutex +{ + SRWLOCK mHandle; +// Track locking thread for error checking. +#if STDMUTEX_RECURSION_CHECKS + friend class vista::condition_variable; + _OwnerThread mOwnerThread {}; +#endif +public: + typedef PSRWLOCK native_handle_type; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" + constexpr mutex () noexcept : mHandle(SRWLOCK_INIT) { } +#pragma GCC diagnostic pop + mutex (const mutex&) = delete; + mutex & operator= (const mutex&) = delete; + void lock (void) + { +// Note: Undefined behavior if called recursively. +#if STDMUTEX_RECURSION_CHECKS + DWORD self = mOwnerThread.checkOwnerBeforeLock(); +#endif + AcquireSRWLockExclusive(&mHandle); +#if STDMUTEX_RECURSION_CHECKS + mOwnerThread.setOwnerAfterLock(self); +#endif + } + void unlock (void) + { +#if STDMUTEX_RECURSION_CHECKS + mOwnerThread.checkSetOwnerBeforeUnlock(); +#endif + ReleaseSRWLockExclusive(&mHandle); + } +// TryAcquireSRW functions are a Windows 7 feature. +#if (WINVER >= _WIN32_WINNT_WIN7) + bool try_lock (void) + { +#if STDMUTEX_RECURSION_CHECKS + DWORD self = mOwnerThread.checkOwnerBeforeLock(); +#endif + BOOL ret = TryAcquireSRWLockExclusive(&mHandle); +#if STDMUTEX_RECURSION_CHECKS + if (ret) + mOwnerThread.setOwnerAfterLock(self); +#endif + return ret; + } +#endif + native_handle_type native_handle (void) + { + return &mHandle; + } +}; +} // Namespace windows7 +#endif // Compiling for Vista +namespace xp +{ +class mutex +{ + CRITICAL_SECTION mHandle; + std::atomic_uchar mState; +// Track locking thread for error checking. +#if STDMUTEX_RECURSION_CHECKS + friend class vista::condition_variable; + _OwnerThread mOwnerThread {}; +#endif +public: + typedef PCRITICAL_SECTION native_handle_type; + constexpr mutex () noexcept : mHandle(), mState(2) { } + mutex (const mutex&) = delete; + mutex & operator= (const mutex&) = delete; + ~mutex() noexcept + { +// Undefined behavior if the mutex is held (locked) by any thread. +// Undefined behavior if a thread terminates while holding ownership of the +// mutex. + DeleteCriticalSection(&mHandle); + } + void lock (void) + { + unsigned char state = mState.load(std::memory_order_acquire); + while (state) { + if ((state == 2) && mState.compare_exchange_weak(state, 1, std::memory_order_acquire)) + { + InitializeCriticalSection(&mHandle); + mState.store(0, std::memory_order_release); + break; + } + if (state == 1) + { + Sleep(0); + state = mState.load(std::memory_order_acquire); + } + } +#if STDMUTEX_RECURSION_CHECKS + DWORD self = mOwnerThread.checkOwnerBeforeLock(); +#endif + EnterCriticalSection(&mHandle); +#if STDMUTEX_RECURSION_CHECKS + mOwnerThread.setOwnerAfterLock(self); +#endif + } + void unlock (void) + { +#if STDMUTEX_RECURSION_CHECKS + mOwnerThread.checkSetOwnerBeforeUnlock(); +#endif + LeaveCriticalSection(&mHandle); + } + bool try_lock (void) + { + unsigned char state = mState.load(std::memory_order_acquire); + if ((state == 2) && mState.compare_exchange_strong(state, 1, std::memory_order_acquire)) + { + InitializeCriticalSection(&mHandle); + mState.store(0, std::memory_order_release); + } + if (state == 1) + return false; +#if STDMUTEX_RECURSION_CHECKS + DWORD self = mOwnerThread.checkOwnerBeforeLock(); +#endif + BOOL ret = TryEnterCriticalSection(&mHandle); +#if STDMUTEX_RECURSION_CHECKS + if (ret) + mOwnerThread.setOwnerAfterLock(self); +#endif + return ret; + } + native_handle_type native_handle (void) + { + return &mHandle; + } +}; +} // Namespace "xp" +#if (WINVER >= _WIN32_WINNT_WIN7) +using windows7::mutex; +#else +using xp::mutex; +#endif + +class recursive_timed_mutex +{ + static constexpr DWORD kWaitAbandoned = 0x00000080l; + static constexpr DWORD kWaitObject0 = 0x00000000l; + static constexpr DWORD kInfinite = 0xffffffffl; + inline bool try_lock_internal (DWORD ms) noexcept + { + DWORD ret = WaitForSingleObject(mHandle, ms); +#ifndef NDEBUG + if (ret == kWaitAbandoned) + { + using namespace std; + fprintf(stderr, "FATAL: Thread terminated while holding a mutex."); + terminate(); + } +#endif + return (ret == kWaitObject0) || (ret == kWaitAbandoned); + } +protected: + HANDLE mHandle; +// Track locking thread for error checking of non-recursive timed_mutex. For +// standard compliance, this must be defined in same class and at the same +// access-control level as every other variable in the timed_mutex. +#if STDMUTEX_RECURSION_CHECKS + friend class vista::condition_variable; + _OwnerThread mOwnerThread {}; +#endif +public: + typedef HANDLE native_handle_type; + native_handle_type native_handle() const {return mHandle;} + recursive_timed_mutex(const recursive_timed_mutex&) = delete; + recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; + recursive_timed_mutex(): mHandle(CreateMutex(NULL, FALSE, NULL)) {} + ~recursive_timed_mutex() + { + CloseHandle(mHandle); + } + void lock() + { + DWORD ret = WaitForSingleObject(mHandle, kInfinite); +// If (ret == WAIT_ABANDONED), then the thread that held ownership was +// terminated. Behavior is undefined, but Windows will pass ownership to this +// thread. +#ifndef NDEBUG + if (ret == kWaitAbandoned) + { + using namespace std; + fprintf(stderr, "FATAL: Thread terminated while holding a mutex."); + terminate(); + } +#endif + if ((ret != kWaitObject0) && (ret != kWaitAbandoned)) + { + __builtin_trap(); + } + } + void unlock() + { + if (!ReleaseMutex(mHandle)) + __builtin_trap(); + } + bool try_lock() + { + return try_lock_internal(0); + } + template <class Rep, class Period> + bool try_lock_for(const std::chrono::duration<Rep,Period>& dur) + { + using namespace std::chrono; + auto timeout = duration_cast<milliseconds>(dur).count(); + while (timeout > 0) + { + constexpr auto kMaxStep = static_cast<decltype(timeout)>(kInfinite-1); + auto step = (timeout < kMaxStep) ? timeout : kMaxStep; + if (try_lock_internal(static_cast<DWORD>(step))) + return true; + timeout -= step; + } + return false; + } + template <class Clock, class Duration> + bool try_lock_until(const std::chrono::time_point<Clock,Duration>& timeout_time) + { + return try_lock_for(timeout_time - Clock::now()); + } +}; + +// Override if, and only if, it is necessary for error-checking. +#if STDMUTEX_RECURSION_CHECKS +class timed_mutex: recursive_timed_mutex +{ +public: + timed_mutex() = default; + timed_mutex(const timed_mutex&) = delete; + timed_mutex& operator=(const timed_mutex&) = delete; + void lock() + { + DWORD self = mOwnerThread.checkOwnerBeforeLock(); + recursive_timed_mutex::lock(); + mOwnerThread.setOwnerAfterLock(self); + } + void unlock() + { + mOwnerThread.checkSetOwnerBeforeUnlock(); + recursive_timed_mutex::unlock(); + } + template <class Rep, class Period> + bool try_lock_for(const std::chrono::duration<Rep,Period>& dur) + { + DWORD self = mOwnerThread.checkOwnerBeforeLock(); + bool ret = recursive_timed_mutex::try_lock_for(dur); + if (ret) + mOwnerThread.setOwnerAfterLock(self); + return ret; + } + template <class Clock, class Duration> + bool try_lock_until(const std::chrono::time_point<Clock,Duration>& timeout_time) + { + return try_lock_for(timeout_time - Clock::now()); + } + bool try_lock () + { + return try_lock_for(std::chrono::milliseconds(0)); + } +}; +#else +typedef recursive_timed_mutex timed_mutex; +#endif + +class once_flag +{ +// When available, the SRW-based mutexes should be faster than the +// CriticalSection-based mutexes. Only try_lock will be unavailable in Vista, +// and try_lock is not used by once_flag. +#if (_WIN32_WINNT == _WIN32_WINNT_VISTA) + windows7::mutex mMutex; +#else + mutex mMutex; +#endif + std::atomic_bool mHasRun; + once_flag(const once_flag&) = delete; + once_flag& operator=(const once_flag&) = delete; + template<class Callable, class... Args> + friend void call_once(once_flag& once, Callable&& f, Args&&... args); +public: + constexpr once_flag() noexcept: mMutex(), mHasRun(false) {} +}; + +template<class Callable, class... Args> +void call_once(once_flag& flag, Callable&& func, Args&&... args) +{ + if (flag.mHasRun.load(std::memory_order_acquire)) + return; + lock_guard<decltype(flag.mMutex)> lock(flag.mMutex); + if (flag.mHasRun.load(std::memory_order_relaxed)) + return; + detail::invoke(std::forward<Callable>(func),std::forward<Args>(args)...); + flag.mHasRun.store(true, std::memory_order_release); +} +} // Namespace mingw_stdthread + +// Push objects into std, but only if they are not already there. +namespace std +{ +// Because of quirks of the compiler, the common "using namespace std;" +// directive would flatten the namespaces and introduce ambiguity where there +// was none. Direct specification (std::), however, would be unaffected. +// Take the safe option, and include only in the presence of MinGW's win32 +// implementation. +#if defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS) +using mingw_stdthread::recursive_mutex; +using mingw_stdthread::mutex; +using mingw_stdthread::recursive_timed_mutex; +using mingw_stdthread::timed_mutex; +using mingw_stdthread::once_flag; +using mingw_stdthread::call_once; +#elif !defined(MINGW_STDTHREAD_REDUNDANCY_WARNING) // Skip repetition +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#pragma message "This version of MinGW seems to include a win32 port of\ + pthreads, and probably already has C++11 std threading classes implemented,\ + based on pthreads. These classes, found in namespace std, are not overridden\ + by the mingw-std-thread library. If you would still like to use this\ + implementation (as it is more lightweight), use the classes provided in\ + namespace mingw_stdthread." +#endif +} +#endif // WIN32STDMUTEX_H diff --git a/thirdparty/mingw-std-threads/mingw.shared_mutex.h b/thirdparty/mingw-std-threads/mingw.shared_mutex.h new file mode 100644 index 0000000000..5375b0fbd1 --- /dev/null +++ b/thirdparty/mingw-std-threads/mingw.shared_mutex.h @@ -0,0 +1,503 @@ +/// \file mingw.shared_mutex.h +/// \brief Standard-compliant shared_mutex for MinGW +/// +/// (c) 2017 by Nathaniel J. McClatchey, Athens OH, United States +/// \author Nathaniel J. McClatchey +/// +/// \copyright Simplified (2-clause) BSD License. +/// +/// \note This file may become part of the mingw-w64 runtime package. If/when +/// this happens, the appropriate license will be added, i.e. this code will +/// become dual-licensed, and the current BSD 2-clause license will stay. +/// \note Target Windows version is determined by WINVER, which is determined in +/// <windows.h> from _WIN32_WINNT, which can itself be set by the user. + +// Notes on the namespaces: +// - The implementation can be accessed directly in the namespace +// mingw_stdthread. +// - Objects will be brought into namespace std by a using directive. This +// will cause objects declared in std (such as MinGW's implementation) to +// hide this implementation's definitions. +// - To avoid poluting the namespace with implementation details, all objects +// to be pushed into std will be placed in mingw_stdthread::visible. +// The end result is that if MinGW supplies an object, it is automatically +// used. If MinGW does not supply an object, this implementation's version will +// instead be used. + +#ifndef MINGW_SHARED_MUTEX_H_ +#define MINGW_SHARED_MUTEX_H_ + +#if !defined(__cplusplus) || (__cplusplus < 201103L) +#error A C++11 compiler is required! +#endif + +#include <cassert> +// For descriptive errors. +#include <system_error> +// Implementing a shared_mutex without OS support will require atomic read- +// modify-write capacity. +#include <atomic> +// For timing in shared_lock and shared_timed_mutex. +#include <chrono> +#include <limits> + +// Use MinGW's shared_lock class template, if it's available. Requires C++14. +// If unavailable (eg. because this library is being used in C++11), then an +// implementation of shared_lock is provided by this header. +#if (__cplusplus >= 201402L) +#include <shared_mutex> +#endif + +// For defer_lock_t, adopt_lock_t, and try_to_lock_t +#include "mingw.mutex.h" +// For this_thread::yield. +//#include "mingw.thread.h" + +// Might be able to use native Slim Reader-Writer (SRW) locks. +#ifdef _WIN32 +#include <sdkddkver.h> // Detect Windows version. +#if (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)) +#pragma message "The Windows API that MinGW-w32 provides is not fully compatible\ + with Microsoft's API. We'll try to work around this, but we can make no\ + guarantees. This problem does not exist in MinGW-w64." +#include <windows.h> // No further granularity can be expected. +#else +#include <synchapi.h> +#endif +#endif + +namespace mingw_stdthread +{ +// Define a portable atomics-based shared_mutex +namespace portable +{ +class shared_mutex +{ + typedef uint_fast16_t counter_type; + std::atomic<counter_type> mCounter {0}; + static constexpr counter_type kWriteBit = 1 << (std::numeric_limits<counter_type>::digits - 1); + +#if STDMUTEX_RECURSION_CHECKS +// Runtime checker for verifying owner threads. Note: Exclusive mode only. + _OwnerThread mOwnerThread {}; +#endif +public: + typedef shared_mutex * native_handle_type; + + shared_mutex () = default; + +// No form of copying or moving should be allowed. + shared_mutex (const shared_mutex&) = delete; + shared_mutex & operator= (const shared_mutex&) = delete; + + ~shared_mutex () + { +// Terminate if someone tries to destroy an owned mutex. + assert(mCounter.load(std::memory_order_relaxed) == 0); + } + + void lock_shared (void) + { + counter_type expected = mCounter.load(std::memory_order_relaxed); + do + { +// Delay if writing or if too many readers are attempting to read. + if (expected >= kWriteBit - 1) + { + using namespace std; + expected = mCounter.load(std::memory_order_relaxed); + continue; + } + if (mCounter.compare_exchange_weak(expected, + static_cast<counter_type>(expected + 1), + std::memory_order_acquire, + std::memory_order_relaxed)) + break; + } + while (true); + } + + bool try_lock_shared (void) + { + counter_type expected = mCounter.load(std::memory_order_relaxed) & static_cast<counter_type>(~kWriteBit); + if (expected + 1 == kWriteBit) + return false; + else + return mCounter.compare_exchange_strong( expected, + static_cast<counter_type>(expected + 1), + std::memory_order_acquire, + std::memory_order_relaxed); + } + + void unlock_shared (void) + { + using namespace std; +#ifndef NDEBUG + if (!(mCounter.fetch_sub(1, memory_order_release) & static_cast<counter_type>(~kWriteBit))) + __builtin_trap(); +#else + mCounter.fetch_sub(1, memory_order_release); +#endif + } + +// Behavior is undefined if a lock was previously acquired. + void lock (void) + { +#if STDMUTEX_RECURSION_CHECKS + DWORD self = mOwnerThread.checkOwnerBeforeLock(); +#endif + using namespace std; +// Might be able to use relaxed memory order... +// Wait for the write-lock to be unlocked, then claim the write slot. + counter_type current; + while ((current = mCounter.fetch_or(kWriteBit, std::memory_order_acquire)) & kWriteBit); + //this_thread::yield(); +// Wait for readers to finish up. + while (current != kWriteBit) + { + //this_thread::yield(); + current = mCounter.load(std::memory_order_acquire); + } +#if STDMUTEX_RECURSION_CHECKS + mOwnerThread.setOwnerAfterLock(self); +#endif + } + + bool try_lock (void) + { +#if STDMUTEX_RECURSION_CHECKS + DWORD self = mOwnerThread.checkOwnerBeforeLock(); +#endif + counter_type expected = 0; + bool ret = mCounter.compare_exchange_strong(expected, kWriteBit, + std::memory_order_acquire, + std::memory_order_relaxed); +#if STDMUTEX_RECURSION_CHECKS + if (ret) + mOwnerThread.setOwnerAfterLock(self); +#endif + return ret; + } + + void unlock (void) + { +#if STDMUTEX_RECURSION_CHECKS + mOwnerThread.checkSetOwnerBeforeUnlock(); +#endif + using namespace std; +#ifndef NDEBUG + if (mCounter.load(memory_order_relaxed) != kWriteBit) + __builtin_trap(); +#endif + mCounter.store(0, memory_order_release); + } + + native_handle_type native_handle (void) + { + return this; + } +}; + +} // Namespace portable + +// The native shared_mutex implementation primarily uses features of Windows +// Vista, but the features used for try_lock and try_lock_shared were not +// introduced until Windows 7. To allow limited use while compiling for Vista, +// I define the class without try_* functions in that case. +// Only fully-featured implementations will be placed into namespace std. +#if defined(_WIN32) && (WINVER >= _WIN32_WINNT_VISTA) +namespace vista +{ +class condition_variable_any; +} + +namespace windows7 +{ +// We already #include "mingw.mutex.h". May as well reduce redundancy. +class shared_mutex : windows7::mutex +{ +// Allow condition_variable_any (and only condition_variable_any) to treat a +// shared_mutex as its base class. + friend class vista::condition_variable_any; +public: + using windows7::mutex::native_handle_type; + using windows7::mutex::lock; + using windows7::mutex::unlock; + using windows7::mutex::native_handle; + + void lock_shared (void) + { + AcquireSRWLockShared(native_handle()); + } + + void unlock_shared (void) + { + ReleaseSRWLockShared(native_handle()); + } + +// TryAcquireSRW functions are a Windows 7 feature. +#if (WINVER >= _WIN32_WINNT_WIN7) + bool try_lock_shared (void) + { + return TryAcquireSRWLockShared(native_handle()) != 0; + } + + using windows7::mutex::try_lock; +#endif +}; + +} // Namespace windows7 +#endif // Compiling for Vista +#if (defined(_WIN32) && (WINVER >= _WIN32_WINNT_WIN7)) +using windows7::shared_mutex; +#else +using portable::shared_mutex; +#endif + +class shared_timed_mutex : shared_mutex +{ + typedef shared_mutex Base; +public: + using Base::lock; + using Base::try_lock; + using Base::unlock; + using Base::lock_shared; + using Base::try_lock_shared; + using Base::unlock_shared; + + template< class Clock, class Duration > + bool try_lock_until ( const std::chrono::time_point<Clock,Duration>& cutoff ) + { + do + { + if (try_lock()) + return true; + } + while (std::chrono::steady_clock::now() < cutoff); + return false; + } + + template< class Rep, class Period > + bool try_lock_for (const std::chrono::duration<Rep,Period>& rel_time) + { + return try_lock_until(std::chrono::steady_clock::now() + rel_time); + } + + template< class Clock, class Duration > + bool try_lock_shared_until ( const std::chrono::time_point<Clock,Duration>& cutoff ) + { + do + { + if (try_lock_shared()) + return true; + } + while (std::chrono::steady_clock::now() < cutoff); + return false; + } + + template< class Rep, class Period > + bool try_lock_shared_for (const std::chrono::duration<Rep,Period>& rel_time) + { + return try_lock_shared_until(std::chrono::steady_clock::now() + rel_time); + } +}; + +#if __cplusplus >= 201402L +using std::shared_lock; +#else +// If not supplied by shared_mutex (eg. because C++14 is not supported), I +// supply the various helper classes that the header should have defined. +template<class Mutex> +class shared_lock +{ + Mutex * mMutex; + bool mOwns; +// Reduce code redundancy + void verify_lockable (void) + { + using namespace std; + if (mMutex == nullptr) + __builtin_trap(); + if (mOwns) + __builtin_trap(); + } +public: + typedef Mutex mutex_type; + + shared_lock (void) noexcept + : mMutex(nullptr), mOwns(false) + { + } + + shared_lock (shared_lock<Mutex> && other) noexcept + : mMutex(other.mutex_), mOwns(other.owns_) + { + other.mMutex = nullptr; + other.mOwns = false; + } + + explicit shared_lock (mutex_type & m) + : mMutex(&m), mOwns(true) + { + mMutex->lock_shared(); + } + + shared_lock (mutex_type & m, defer_lock_t) noexcept + : mMutex(&m), mOwns(false) + { + } + + shared_lock (mutex_type & m, adopt_lock_t) + : mMutex(&m), mOwns(true) + { + } + + shared_lock (mutex_type & m, try_to_lock_t) + : mMutex(&m), mOwns(m.try_lock_shared()) + { + } + + template< class Rep, class Period > + shared_lock( mutex_type& m, const std::chrono::duration<Rep,Period>& timeout_duration ) + : mMutex(&m), mOwns(m.try_lock_shared_for(timeout_duration)) + { + } + + template< class Clock, class Duration > + shared_lock( mutex_type& m, const std::chrono::time_point<Clock,Duration>& timeout_time ) + : mMutex(&m), mOwns(m.try_lock_shared_until(timeout_time)) + { + } + + shared_lock& operator= (shared_lock<Mutex> && other) noexcept + { + if (&other != this) + { + if (mOwns) + mMutex->unlock_shared(); + mMutex = other.mMutex; + mOwns = other.mOwns; + other.mMutex = nullptr; + other.mOwns = false; + } + return *this; + } + + + ~shared_lock (void) + { + if (mOwns) + mMutex->unlock_shared(); + } + + shared_lock (const shared_lock<Mutex> &) = delete; + shared_lock& operator= (const shared_lock<Mutex> &) = delete; + +// Shared locking + void lock (void) + { + verify_lockable(); + mMutex->lock_shared(); + mOwns = true; + } + + bool try_lock (void) + { + verify_lockable(); + mOwns = mMutex->try_lock_shared(); + return mOwns; + } + + template< class Clock, class Duration > + bool try_lock_until( const std::chrono::time_point<Clock,Duration>& cutoff ) + { + verify_lockable(); + do + { + mOwns = mMutex->try_lock_shared(); + if (mOwns) + return mOwns; + } + while (std::chrono::steady_clock::now() < cutoff); + return false; + } + + template< class Rep, class Period > + bool try_lock_for (const std::chrono::duration<Rep,Period>& rel_time) + { + return try_lock_until(std::chrono::steady_clock::now() + rel_time); + } + + void unlock (void) + { + using namespace std; + if (!mOwns) + __builtin_trap(); + mMutex->unlock_shared(); + mOwns = false; + } + +// Modifiers + void swap (shared_lock<Mutex> & other) noexcept + { + using namespace std; + swap(mMutex, other.mMutex); + swap(mOwns, other.mOwns); + } + + mutex_type * release (void) noexcept + { + mutex_type * ptr = mMutex; + mMutex = nullptr; + mOwns = false; + return ptr; + } +// Observers + mutex_type * mutex (void) const noexcept + { + return mMutex; + } + + bool owns_lock (void) const noexcept + { + return mOwns; + } + + explicit operator bool () const noexcept + { + return owns_lock(); + } +}; + +template< class Mutex > +void swap( shared_lock<Mutex>& lhs, shared_lock<Mutex>& rhs ) noexcept +{ + lhs.swap(rhs); +} +#endif // C++11 +} // Namespace mingw_stdthread + +namespace std +{ +// Because of quirks of the compiler, the common "using namespace std;" +// directive would flatten the namespaces and introduce ambiguity where there +// was none. Direct specification (std::), however, would be unaffected. +// Take the safe option, and include only in the presence of MinGW's win32 +// implementation. +#if (__cplusplus < 201703L) || (defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS)) +using mingw_stdthread::shared_mutex; +#endif +#if (__cplusplus < 201402L) || (defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS)) +using mingw_stdthread::shared_timed_mutex; +using mingw_stdthread::shared_lock; +#elif !defined(MINGW_STDTHREAD_REDUNDANCY_WARNING) // Skip repetition +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#pragma message "This version of MinGW seems to include a win32 port of\ + pthreads, and probably already has C++ std threading classes implemented,\ + based on pthreads. These classes, found in namespace std, are not overridden\ + by the mingw-std-thread library. If you would still like to use this\ + implementation (as it is more lightweight), use the classes provided in\ + namespace mingw_stdthread." +#endif +} // Namespace std +#endif // MINGW_SHARED_MUTEX_H_ diff --git a/thirdparty/mingw-std-threads/mingw.thread.h b/thirdparty/mingw-std-threads/mingw.thread.h new file mode 100644 index 0000000000..7ca09e25f5 --- /dev/null +++ b/thirdparty/mingw-std-threads/mingw.thread.h @@ -0,0 +1,360 @@ +/** +* @file mingw.thread.h +* @brief std::thread implementation for MinGW +* (c) 2013-2016 by Mega Limited, Auckland, New Zealand +* @author Alexander Vassilev +* +* @copyright Simplified (2-clause) BSD License. +* You should have received a copy of the license along with this +* program. +* +* This code is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +* @note +* This file may become part of the mingw-w64 runtime package. If/when this happens, +* the appropriate license will be added, i.e. this code will become dual-licensed, +* and the current BSD 2-clause license will stay. +*/ + +#ifndef WIN32STDTHREAD_H +#define WIN32STDTHREAD_H + +#if !defined(__cplusplus) || (__cplusplus < 201103L) +#error A C++11 compiler is required! +#endif + +// Use the standard classes for std::, if available. +#include <thread> + +#include <cstddef> // For std::size_t +#include <cerrno> // Detect error type. +#include <exception> // For std::terminate +#include <system_error> // For std::system_error +#include <functional> // For std::hash +#include <tuple> // For std::tuple +#include <chrono> // For sleep timing. +#include <memory> // For std::unique_ptr +#include <iosfwd> // Stream output for thread ids. +#include <utility> // For std::swap, std::forward + +#include "mingw.invoke.h" + +#if (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)) +#pragma message "The Windows API that MinGW-w32 provides is not fully compatible\ + with Microsoft's API. We'll try to work around this, but we can make no\ + guarantees. This problem does not exist in MinGW-w64." +#include <windows.h> // No further granularity can be expected. +#else +#include <synchapi.h> // For WaitForSingleObject +#include <handleapi.h> // For CloseHandle, etc. +#include <sysinfoapi.h> // For GetNativeSystemInfo +#include <processthreadsapi.h> // For GetCurrentThreadId +#endif +#include <process.h> // For _beginthreadex + +#ifndef NDEBUG +#include <cstdio> +#endif + +#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501) +#error To use the MinGW-std-threads library, you will need to define the macro _WIN32_WINNT to be 0x0501 (Windows XP) or higher. +#endif + +// Instead of INVALID_HANDLE_VALUE, _beginthreadex returns 0. +namespace mingw_stdthread +{ +namespace detail +{ + template<std::size_t...> + struct IntSeq {}; + + template<std::size_t N, std::size_t... S> + struct GenIntSeq : GenIntSeq<N-1, N-1, S...> { }; + + template<std::size_t... S> + struct GenIntSeq<0, S...> { typedef IntSeq<S...> type; }; + +// Use a template specialization to avoid relying on compiler optimization +// when determining the parameter integer sequence. + template<class Func, class T, typename... Args> + class ThreadFuncCall; +// We can't define the Call struct in the function - the standard forbids template methods in that case + template<class Func, std::size_t... S, typename... Args> + class ThreadFuncCall<Func, detail::IntSeq<S...>, Args...> + { + static_assert(sizeof...(S) == sizeof...(Args), "Args must match."); + using Tuple = std::tuple<typename std::decay<Args>::type...>; + typename std::decay<Func>::type mFunc; + Tuple mArgs; + + public: + ThreadFuncCall(Func&& aFunc, Args&&... aArgs) + : mFunc(std::forward<Func>(aFunc)), + mArgs(std::forward<Args>(aArgs)...) + { + } + + void callFunc() + { + detail::invoke(std::move(mFunc), std::move(std::get<S>(mArgs)) ...); + } + }; + +// Allow construction of threads without exposing implementation. + class ThreadIdTool; +} // Namespace "detail" + +class thread +{ +public: + class id + { + DWORD mId = 0; + friend class thread; + friend class std::hash<id>; + friend class detail::ThreadIdTool; + explicit id(DWORD aId) noexcept : mId(aId){} + public: + id (void) noexcept = default; + friend bool operator==(id x, id y) noexcept {return x.mId == y.mId; } + friend bool operator!=(id x, id y) noexcept {return x.mId != y.mId; } + friend bool operator< (id x, id y) noexcept {return x.mId < y.mId; } + friend bool operator<=(id x, id y) noexcept {return x.mId <= y.mId; } + friend bool operator> (id x, id y) noexcept {return x.mId > y.mId; } + friend bool operator>=(id x, id y) noexcept {return x.mId >= y.mId; } + + template<class _CharT, class _Traits> + friend std::basic_ostream<_CharT, _Traits>& + operator<<(std::basic_ostream<_CharT, _Traits>& __out, id __id) + { + if (__id.mId == 0) + { + return __out << "(invalid std::thread::id)"; + } + else + { + return __out << __id.mId; + } + } + }; +private: + static constexpr HANDLE kInvalidHandle = nullptr; + static constexpr DWORD kInfinite = 0xffffffffl; + HANDLE mHandle; + id mThreadId; + + template <class Call> + static unsigned __stdcall threadfunc(void* arg) + { + std::unique_ptr<Call> call(static_cast<Call*>(arg)); + call->callFunc(); + return 0; + } + + static unsigned int _hardware_concurrency_helper() noexcept + { + SYSTEM_INFO sysinfo; +// This is one of the few functions used by the library which has a nearly- +// equivalent function defined in earlier versions of Windows. Include the +// workaround, just as a reminder that it does exist. +#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) + ::GetNativeSystemInfo(&sysinfo); +#else + ::GetSystemInfo(&sysinfo); +#endif + return sysinfo.dwNumberOfProcessors; + } +public: + typedef HANDLE native_handle_type; + id get_id() const noexcept {return mThreadId;} + native_handle_type native_handle() const {return mHandle;} + thread(): mHandle(kInvalidHandle), mThreadId(){} + + thread(thread&& other) + :mHandle(other.mHandle), mThreadId(other.mThreadId) + { + other.mHandle = kInvalidHandle; + other.mThreadId = id{}; + } + + thread(const thread &other)=delete; + + template<class Func, typename... Args> + explicit thread(Func&& func, Args&&... args) : mHandle(), mThreadId() + { + using ArgSequence = typename detail::GenIntSeq<sizeof...(Args)>::type; + using Call = detail::ThreadFuncCall<Func, ArgSequence, Args...>; + auto call = new Call( + std::forward<Func>(func), std::forward<Args>(args)...); + unsigned id_receiver; + auto int_handle = _beginthreadex(NULL, 0, threadfunc<Call>, + static_cast<LPVOID>(call), 0, &id_receiver); + if (int_handle == 0) + { + mHandle = kInvalidHandle; + int errnum = errno; + delete call; +// Note: Should only throw EINVAL, EAGAIN, EACCES + __builtin_trap(); + } else { + mThreadId.mId = id_receiver; + mHandle = reinterpret_cast<HANDLE>(int_handle); + } + } + + bool joinable() const {return mHandle != kInvalidHandle;} + +// Note: Due to lack of synchronization, this function has a race condition +// if called concurrently, which leads to undefined behavior. The same applies +// to all other member functions of this class, but this one is mentioned +// explicitly. + void join() + { + using namespace std; + if (get_id() == id(GetCurrentThreadId())) + __builtin_trap(); + if (mHandle == kInvalidHandle) + __builtin_trap(); + if (!joinable()) + __builtin_trap(); + WaitForSingleObject(mHandle, kInfinite); + CloseHandle(mHandle); + mHandle = kInvalidHandle; + mThreadId = id{}; + } + + ~thread() + { + if (joinable()) + { +#ifndef NDEBUG + std::printf("Error: Must join() or detach() a thread before \ +destroying it.\n"); +#endif + std::terminate(); + } + } + thread& operator=(const thread&) = delete; + thread& operator=(thread&& other) noexcept + { + if (joinable()) + { +#ifndef NDEBUG + std::printf("Error: Must join() or detach() a thread before \ +moving another thread to it.\n"); +#endif + std::terminate(); + } + swap(std::forward<thread>(other)); + return *this; + } + void swap(thread&& other) noexcept + { + std::swap(mHandle, other.mHandle); + std::swap(mThreadId.mId, other.mThreadId.mId); + } + + static unsigned int hardware_concurrency() noexcept + { + static unsigned int cached = _hardware_concurrency_helper(); + return cached; + } + + void detach() + { + if (!joinable()) + { + using namespace std; + __builtin_trap(); + } + if (mHandle != kInvalidHandle) + { + CloseHandle(mHandle); + mHandle = kInvalidHandle; + } + mThreadId = id{}; + } +}; + +namespace detail +{ + class ThreadIdTool + { + public: + static thread::id make_id (DWORD base_id) noexcept + { + return thread::id(base_id); + } + }; +} // Namespace "detail" + +namespace this_thread +{ + inline thread::id get_id() noexcept + { + return detail::ThreadIdTool::make_id(GetCurrentThreadId()); + } + inline void yield() noexcept {Sleep(0);} + template< class Rep, class Period > + void sleep_for( const std::chrono::duration<Rep,Period>& sleep_duration) + { + static constexpr DWORD kInfinite = 0xffffffffl; + using namespace std::chrono; + using rep = milliseconds::rep; + rep ms = duration_cast<milliseconds>(sleep_duration).count(); + while (ms > 0) + { + constexpr rep kMaxRep = static_cast<rep>(kInfinite - 1); + auto sleepTime = (ms < kMaxRep) ? ms : kMaxRep; + Sleep(static_cast<DWORD>(sleepTime)); + ms -= sleepTime; + } + } + template <class Clock, class Duration> + void sleep_until(const std::chrono::time_point<Clock,Duration>& sleep_time) + { + sleep_for(sleep_time-Clock::now()); + } +} +} // Namespace mingw_stdthread + +namespace std +{ +// Because of quirks of the compiler, the common "using namespace std;" +// directive would flatten the namespaces and introduce ambiguity where there +// was none. Direct specification (std::), however, would be unaffected. +// Take the safe option, and include only in the presence of MinGW's win32 +// implementation. +#if defined(__MINGW32__ ) && !defined(_GLIBCXX_HAS_GTHREADS) +using mingw_stdthread::thread; +// Remove ambiguity immediately, to avoid problems arising from the above. +//using std::thread; +namespace this_thread +{ +using namespace mingw_stdthread::this_thread; +} +#elif !defined(MINGW_STDTHREAD_REDUNDANCY_WARNING) // Skip repetition +#define MINGW_STDTHREAD_REDUNDANCY_WARNING +#pragma message "This version of MinGW seems to include a win32 port of\ + pthreads, and probably already has C++11 std threading classes implemented,\ + based on pthreads. These classes, found in namespace std, are not overridden\ + by the mingw-std-thread library. If you would still like to use this\ + implementation (as it is more lightweight), use the classes provided in\ + namespace mingw_stdthread." +#endif + +// Specialize hash for this implementation's thread::id, even if the +// std::thread::id already has a hash. +template<> +struct hash<mingw_stdthread::thread::id> +{ + typedef mingw_stdthread::thread::id argument_type; + typedef size_t result_type; + size_t operator() (const argument_type & i) const noexcept + { + return i.mId; + } +}; +} +#endif // WIN32STDTHREAD_H diff --git a/thirdparty/mingw-std-threads/no_except.patch b/thirdparty/mingw-std-threads/no_except.patch new file mode 100644 index 0000000000..6151103a8a --- /dev/null +++ b/thirdparty/mingw-std-threads/no_except.patch @@ -0,0 +1,137 @@ +diff --git a/thirdparty/mingw-std-threads/mingw.condition_variable.h b/thirdparty/mingw-std-threads/mingw.condition_variable.h +index 50c5ebd6df..f9e248c154 100644 +--- a/thirdparty/mingw-std-threads/mingw.condition_variable.h ++++ b/thirdparty/mingw-std-threads/mingw.condition_variable.h +@@ -87,12 +87,12 @@ public: + : mSemaphore(CreateSemaphoreA(NULL, 0, 0xFFFF, NULL)) + { + if (mSemaphore == NULL) +- throw std::system_error(GetLastError(), std::generic_category()); ++ __builtin_trap(); + mWakeEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (mWakeEvent == NULL) + { + CloseHandle(mSemaphore); +- throw std::system_error(GetLastError(), std::generic_category()); ++ __builtin_trap(); + } + } + ~condition_variable_any() +@@ -132,7 +132,7 @@ private: + else + { + using namespace std; +- throw system_error(make_error_code(errc::protocol_error)); ++ __builtin_trap(); + } + } + public: +diff --git a/thirdparty/mingw-std-threads/mingw.mutex.h b/thirdparty/mingw-std-threads/mingw.mutex.h +index 03efa13f8b..73698d13cb 100644 +--- a/thirdparty/mingw-std-threads/mingw.mutex.h ++++ b/thirdparty/mingw-std-threads/mingw.mutex.h +@@ -132,7 +132,7 @@ struct _OwnerThread + fprintf(stderr, "FATAL: Recursive locking of non-recursive mutex\ + detected. Throwing system exception\n"); + fflush(stderr); +- throw system_error(make_error_code(errc::resource_deadlock_would_occur)); ++ __builtin_trap(); + } + DWORD checkOwnerBeforeLock() const + { +@@ -364,13 +364,13 @@ public: + #endif + if ((ret != kWaitObject0) && (ret != kWaitAbandoned)) + { +- throw std::system_error(GetLastError(), std::system_category()); ++ __builtin_trap(); + } + } + void unlock() + { + if (!ReleaseMutex(mHandle)) +- throw std::system_error(GetLastError(), std::system_category()); ++ __builtin_trap(); + } + bool try_lock() + { +diff --git a/thirdparty/mingw-std-threads/mingw.shared_mutex.h b/thirdparty/mingw-std-threads/mingw.shared_mutex.h +index ff1ac65135..5375b0fbd1 100644 +--- a/thirdparty/mingw-std-threads/mingw.shared_mutex.h ++++ b/thirdparty/mingw-std-threads/mingw.shared_mutex.h +@@ -134,7 +134,7 @@ public: + using namespace std; + #ifndef NDEBUG + if (!(mCounter.fetch_sub(1, memory_order_release) & static_cast<counter_type>(~kWriteBit))) +- throw system_error(make_error_code(errc::operation_not_permitted)); ++ __builtin_trap(); + #else + mCounter.fetch_sub(1, memory_order_release); + #endif +@@ -187,7 +187,7 @@ public: + using namespace std; + #ifndef NDEBUG + if (mCounter.load(memory_order_relaxed) != kWriteBit) +- throw system_error(make_error_code(errc::operation_not_permitted)); ++ __builtin_trap(); + #endif + mCounter.store(0, memory_order_release); + } +@@ -317,9 +317,9 @@ class shared_lock + { + using namespace std; + if (mMutex == nullptr) +- throw system_error(make_error_code(errc::operation_not_permitted)); ++ __builtin_trap(); + if (mOwns) +- throw system_error(make_error_code(errc::resource_deadlock_would_occur)); ++ __builtin_trap(); + } + public: + typedef Mutex mutex_type; +@@ -432,7 +432,7 @@ public: + { + using namespace std; + if (!mOwns) +- throw system_error(make_error_code(errc::operation_not_permitted)); ++ __builtin_trap(); + mMutex->unlock_shared(); + mOwns = false; + } +diff --git a/thirdparty/mingw-std-threads/mingw.thread.h b/thirdparty/mingw-std-threads/mingw.thread.h +index bcdd1a36a8..7ca09e25f5 100644 +--- a/thirdparty/mingw-std-threads/mingw.thread.h ++++ b/thirdparty/mingw-std-threads/mingw.thread.h +@@ -196,7 +196,7 @@ public: + int errnum = errno; + delete call; + // Note: Should only throw EINVAL, EAGAIN, EACCES +- throw std::system_error(errnum, std::generic_category()); ++ __builtin_trap(); + } else { + mThreadId.mId = id_receiver; + mHandle = reinterpret_cast<HANDLE>(int_handle); +@@ -213,11 +213,11 @@ public: + { + using namespace std; + if (get_id() == id(GetCurrentThreadId())) +- throw system_error(make_error_code(errc::resource_deadlock_would_occur)); ++ __builtin_trap(); + if (mHandle == kInvalidHandle) +- throw system_error(make_error_code(errc::no_such_process)); ++ __builtin_trap(); + if (!joinable()) +- throw system_error(make_error_code(errc::invalid_argument)); ++ __builtin_trap(); + WaitForSingleObject(mHandle, kInfinite); + CloseHandle(mHandle); + mHandle = kInvalidHandle; +@@ -266,7 +266,7 @@ moving another thread to it.\n"); + if (!joinable()) + { + using namespace std; +- throw system_error(make_error_code(errc::invalid_argument)); ++ __builtin_trap(); + } + if (mHandle != kInvalidHandle) + { |