mirror of
https://github.com/godotengine/godot.git
synced 2024-10-22 21:21:53 +00:00
Compare commits
6 Commits
aa7227ae69
...
170394a5c4
Author | SHA1 | Date | |
---|---|---|---|
|
170394a5c4 | ||
|
de6002fabd | ||
|
533c616cb8 | ||
|
152e24c7de | ||
|
ca7840073c | ||
|
d5d509bbd6 |
|
@ -556,6 +556,11 @@ String OS::get_cache_dir() const {
|
|||
return ::OS::get_singleton()->get_cache_path();
|
||||
}
|
||||
|
||||
String OS::get_tmp_dir() const {
|
||||
// Exposed as `get_tmp_dir()` instead of `get_tmp_path()` for consistency with other exposed OS methods.
|
||||
return ::OS::get_singleton()->get_tmp_path();
|
||||
}
|
||||
|
||||
bool OS::is_debug_build() const {
|
||||
#ifdef DEBUG_ENABLED
|
||||
return true;
|
||||
|
@ -678,6 +683,7 @@ void OS::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_config_dir"), &OS::get_config_dir);
|
||||
ClassDB::bind_method(D_METHOD("get_data_dir"), &OS::get_data_dir);
|
||||
ClassDB::bind_method(D_METHOD("get_cache_dir"), &OS::get_cache_dir);
|
||||
ClassDB::bind_method(D_METHOD("get_tmp_dir"), &OS::get_tmp_dir);
|
||||
ClassDB::bind_method(D_METHOD("get_unique_id"), &OS::get_unique_id);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_keycode_string", "code"), &OS::get_keycode_string);
|
||||
|
|
|
@ -245,6 +245,7 @@ public:
|
|||
String get_config_dir() const;
|
||||
String get_data_dir() const;
|
||||
String get_cache_dir() const;
|
||||
String get_tmp_dir() const;
|
||||
|
||||
Error set_thread_name(const String &p_name);
|
||||
::Thread::ID get_thread_caller_id() const;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/io/file_access.h"
|
||||
#include "core/object/class_db.h"
|
||||
#include "core/os/memory.h"
|
||||
#include "core/os/os.h"
|
||||
#include "core/templates/local_vector.h"
|
||||
|
@ -323,6 +324,33 @@ Ref<DirAccess> DirAccess::create(AccessType p_access) {
|
|||
return da;
|
||||
}
|
||||
|
||||
Ref<DirAccess> DirAccess::create_tmp(const String &p_prefix, bool p_keep) {
|
||||
Ref<DirAccess> dir_access = DirAccess::open(OS::get_singleton()->get_tmp_path());
|
||||
String hash;
|
||||
while (true) {
|
||||
hash = itos(Math::rand()).sha256_text().substr(0, 10);
|
||||
if (!DirAccess::exists(hash)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
String path = (p_prefix.is_empty()
|
||||
? ""
|
||||
: p_prefix + "-") +
|
||||
hash;
|
||||
Error err = dir_access->make_dir(path);
|
||||
if (err != OK) {
|
||||
return Ref<DirAccess>();
|
||||
}
|
||||
err = dir_access->change_dir(path);
|
||||
if (err != OK) {
|
||||
return Ref<DirAccess>();
|
||||
}
|
||||
dir_access->_is_tmp = true;
|
||||
dir_access->_tmp_keep_after_free = p_keep;
|
||||
dir_access->_tmp_path = dir_access->get_current_dir();
|
||||
return dir_access;
|
||||
}
|
||||
|
||||
Error DirAccess::get_open_error() {
|
||||
return last_dir_open_error;
|
||||
}
|
||||
|
@ -552,9 +580,35 @@ bool DirAccess::is_case_sensitive(const String &p_path) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
void DirAccess::_delete_tmp() {
|
||||
// Remove created tmp directory.
|
||||
if (!_is_tmp || _tmp_keep_after_free) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DirAccess::exists(_tmp_path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Error err;
|
||||
{
|
||||
Ref<DirAccess> dir_access = DirAccess::open(_tmp_path, &err);
|
||||
if (err != OK) {
|
||||
return;
|
||||
}
|
||||
err = dir_access->erase_contents_recursive();
|
||||
if (err != OK) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DirAccess::remove_absolute(_tmp_path);
|
||||
}
|
||||
|
||||
void DirAccess::_bind_methods() {
|
||||
ClassDB::bind_static_method("DirAccess", D_METHOD("open", "path"), &DirAccess::_open);
|
||||
ClassDB::bind_static_method("DirAccess", D_METHOD("get_open_error"), &DirAccess::get_open_error);
|
||||
ClassDB::bind_static_method("DirAccess", D_METHOD("create_tmp", "prefix", "keep"), &DirAccess::create_tmp, DEFVAL(""), DEFVAL(false));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("list_dir_begin"), &DirAccess::list_dir_begin, DEFVAL(false), DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("get_next"), &DirAccess::_get_next);
|
||||
|
@ -598,3 +652,7 @@ void DirAccess::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "include_navigational"), "set_include_navigational", "get_include_navigational");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "include_hidden"), "set_include_hidden", "get_include_hidden");
|
||||
}
|
||||
|
||||
DirAccess::~DirAccess() {
|
||||
_delete_tmp();
|
||||
}
|
||||
|
|
|
@ -61,6 +61,11 @@ private:
|
|||
bool include_navigational = false;
|
||||
bool include_hidden = false;
|
||||
|
||||
bool _is_tmp = false;
|
||||
bool _tmp_keep_after_free = false;
|
||||
String _tmp_path;
|
||||
void _delete_tmp();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
|
@ -128,6 +133,7 @@ public:
|
|||
static Ref<DirAccess> create_for_path(const String &p_path);
|
||||
|
||||
static Ref<DirAccess> create(AccessType p_access);
|
||||
static Ref<DirAccess> create_tmp(const String &p_prefix = "", bool p_keep = false);
|
||||
static Error get_open_error();
|
||||
|
||||
template <typename T>
|
||||
|
@ -162,7 +168,7 @@ public:
|
|||
virtual bool is_case_sensitive(const String &p_path) const;
|
||||
|
||||
DirAccess() {}
|
||||
virtual ~DirAccess() {}
|
||||
virtual ~DirAccess();
|
||||
};
|
||||
|
||||
#endif // DIR_ACCESS_H
|
||||
|
|
|
@ -68,6 +68,19 @@ void FileAccess::_set_access_type(AccessType p_access) {
|
|||
_access_type = p_access;
|
||||
}
|
||||
|
||||
void FileAccess::_delete_tmp() {
|
||||
// Remove created tmp file.
|
||||
if (!_is_tmp_file || _tmp_keep_after_use) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!FileAccess::exists(_tmp_path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DirAccess::remove_absolute(_tmp_path);
|
||||
}
|
||||
|
||||
Ref<FileAccess> FileAccess::create_for_path(const String &p_path) {
|
||||
Ref<FileAccess> ret;
|
||||
if (p_path.begins_with("res://")) {
|
||||
|
@ -83,6 +96,42 @@ Ref<FileAccess> FileAccess::create_for_path(const String &p_path) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
Ref<FileAccess> FileAccess::create_tmp(int p_mode_flags, const String &p_extension, bool p_keep, Error *r_error) {
|
||||
const String TMP_DIR = OS::get_singleton()->get_tmp_path();
|
||||
String extension = p_extension;
|
||||
if (extension.begins_with(".")) {
|
||||
extension = extension.replace_first(".", "");
|
||||
}
|
||||
String hash;
|
||||
String tmp_file_path;
|
||||
while (true) {
|
||||
hash = itos(Math::rand()).sha256_text().substr(0, 10);
|
||||
tmp_file_path = TMP_DIR.path_join(hash + (extension.is_empty() ? "" : "." + extension));
|
||||
if (!DirAccess::exists(tmp_file_path)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Error err;
|
||||
{
|
||||
// Create file first with WRITE mode.
|
||||
// Otherwise, it would fail to open with a READ mode.
|
||||
Ref<FileAccess> ret = FileAccess::open(tmp_file_path, FileAccess::ModeFlags::WRITE, &err);
|
||||
if (err != OK) {
|
||||
*r_error = err;
|
||||
return Ref<FileAccess>();
|
||||
}
|
||||
ret->flush();
|
||||
}
|
||||
// Open then the tmp file with the correct mode flag.
|
||||
Ref<FileAccess> ret = FileAccess::open(tmp_file_path, p_mode_flags, &err);
|
||||
if (ret.is_valid()) {
|
||||
ret->_is_tmp_file = true;
|
||||
ret->_tmp_keep_after_use = p_keep;
|
||||
ret->_tmp_path = ret->get_path_absolute();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Error FileAccess::reopen(const String &p_path, int p_mode_flags) {
|
||||
return open_internal(p_path, p_mode_flags);
|
||||
}
|
||||
|
@ -810,6 +859,7 @@ void FileAccess::_bind_methods() {
|
|||
ClassDB::bind_static_method("FileAccess", D_METHOD("open_encrypted_with_pass", "path", "mode_flags", "pass"), &FileAccess::open_encrypted_pass);
|
||||
ClassDB::bind_static_method("FileAccess", D_METHOD("open_compressed", "path", "mode_flags", "compression_mode"), &FileAccess::open_compressed, DEFVAL(0));
|
||||
ClassDB::bind_static_method("FileAccess", D_METHOD("get_open_error"), &FileAccess::get_open_error);
|
||||
ClassDB::bind_static_method("FileAccess", D_METHOD("create_tmp", "mode_flags", "extension", "keep"), &FileAccess::_create_tmp, DEFVAL(""), DEFVAL(false));
|
||||
|
||||
ClassDB::bind_static_method("FileAccess", D_METHOD("get_file_as_bytes", "path"), &FileAccess::_get_file_as_bytes);
|
||||
ClassDB::bind_static_method("FileAccess", D_METHOD("get_file_as_string", "path"), &FileAccess::_get_file_as_string);
|
||||
|
@ -897,3 +947,7 @@ void FileAccess::_bind_methods() {
|
|||
BIND_BITFIELD_FLAG(UNIX_SET_GROUP_ID);
|
||||
BIND_BITFIELD_FLAG(UNIX_RESTRICTED_DELETE);
|
||||
}
|
||||
|
||||
FileAccess::~FileAccess() {
|
||||
_delete_tmp();
|
||||
}
|
||||
|
|
|
@ -122,6 +122,11 @@ private:
|
|||
|
||||
static Ref<FileAccess> _open(const String &p_path, ModeFlags p_mode_flags);
|
||||
|
||||
bool _is_tmp_file = false;
|
||||
bool _tmp_keep_after_use = false;
|
||||
String _tmp_path;
|
||||
void _delete_tmp();
|
||||
|
||||
public:
|
||||
static void set_file_close_fail_notify_callback(FileCloseFailNotify p_cbk) { close_fail_notify = p_cbk; }
|
||||
|
||||
|
@ -228,13 +233,18 @@ public:
|
|||
static PackedByteArray _get_file_as_bytes(const String &p_path) { return get_file_as_bytes(p_path, &last_file_open_error); }
|
||||
static String _get_file_as_string(const String &p_path) { return get_file_as_string(p_path, &last_file_open_error); }
|
||||
|
||||
static Ref<FileAccess> create_tmp(int p_mode_flags, const String &p_extension = "", bool p_keep = false, Error *r_error = nullptr);
|
||||
static Ref<FileAccess> _create_tmp(int p_mode_flags, const String &p_extension = "", bool p_keep = false) {
|
||||
return create_tmp(p_mode_flags, p_extension, p_keep, &last_file_open_error);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void make_default(AccessType p_access) {
|
||||
create_func[p_access] = _create_builtin<T>;
|
||||
}
|
||||
|
||||
FileAccess() {}
|
||||
virtual ~FileAccess() {}
|
||||
virtual ~FileAccess();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(FileAccess::CompressionMode);
|
||||
|
|
|
@ -276,6 +276,10 @@ String OS::get_cache_path() const {
|
|||
return ".";
|
||||
}
|
||||
|
||||
String OS::get_tmp_path() const {
|
||||
return ".";
|
||||
}
|
||||
|
||||
// Path to macOS .app bundle resources
|
||||
String OS::get_bundle_resource_dir() const {
|
||||
return ".";
|
||||
|
|
|
@ -274,6 +274,7 @@ public:
|
|||
virtual String get_data_path() const;
|
||||
virtual String get_config_path() const;
|
||||
virtual String get_cache_path() const;
|
||||
virtual String get_tmp_path() const;
|
||||
virtual String get_bundle_resource_dir() const;
|
||||
virtual String get_bundle_icon_path() const;
|
||||
|
||||
|
|
|
@ -104,6 +104,16 @@
|
|||
[b]Note:[/b] This method is implemented on macOS, Linux, and Windows.
|
||||
</description>
|
||||
</method>
|
||||
<method name="create_tmp" qualifiers="static">
|
||||
<return type="DirAccess" />
|
||||
<param index="0" name="prefix" type="String" default="""" />
|
||||
<param index="1" name="keep" type="bool" default="false" />
|
||||
<description>
|
||||
Creates a temporary directory.
|
||||
If [param keep] is [code]true[/code], the directory will outlive the [DirAccess] instance. When [code]false[/code], the directory will be deleted, including all its files.
|
||||
If the returned value is [code]null[/code], use [method get_open_error] to get some context.
|
||||
</description>
|
||||
</method>
|
||||
<method name="current_is_dir" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<description>
|
||||
|
|
|
@ -50,6 +50,17 @@
|
|||
[b]Note:[/b] [FileAccess] will automatically close when it's freed, which happens when it goes out of scope or when it gets assigned with [code]null[/code]. In C# the reference must be disposed after we are done using it, this can be done with the [code]using[/code] statement or calling the [code]Dispose[/code] method directly.
|
||||
</description>
|
||||
</method>
|
||||
<method name="create_tmp" qualifiers="static">
|
||||
<return type="FileAccess" />
|
||||
<param index="0" name="mode_flags" type="int" />
|
||||
<param index="1" name="extension" type="String" default="""" />
|
||||
<param index="2" name="keep" type="bool" default="false" />
|
||||
<description>
|
||||
Creates a temporary file.
|
||||
If [param extension] is not empty, it will be appended to the temporary file name.
|
||||
If [param keep] is [code]true[/code], the file will outlive the [FileAccess] instance.
|
||||
</description>
|
||||
</method>
|
||||
<method name="eof_reached" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<description>
|
||||
|
|
|
@ -526,6 +526,12 @@
|
|||
[b]Note:[/b] Thread IDs are not deterministic and may be reused across application restarts.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_tmp_dir" qualifiers="const">
|
||||
<return type="String" />
|
||||
<description>
|
||||
Returns the [i]global[/i] temporary data directory according to the operating system's standards.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_unique_id" qualifiers="const">
|
||||
<return type="String" />
|
||||
<description>
|
||||
|
|
|
@ -225,6 +225,10 @@ String OS_Unix::get_version() const {
|
|||
return "";
|
||||
}
|
||||
|
||||
String OS_Unix::get_tmp_path() const {
|
||||
return "/tmp";
|
||||
}
|
||||
|
||||
double OS_Unix::get_unix_time() const {
|
||||
struct timeval tv_now;
|
||||
gettimeofday(&tv_now, nullptr);
|
||||
|
|
|
@ -72,6 +72,8 @@ public:
|
|||
virtual String get_distribution_name() const override;
|
||||
virtual String get_version() const override;
|
||||
|
||||
virtual String get_tmp_path() const override;
|
||||
|
||||
virtual DateTime get_datetime(bool p_utc) const override;
|
||||
virtual TimeZoneInfo get_time_zone_info() const override;
|
||||
|
||||
|
|
|
@ -54,6 +54,10 @@ String EditorPaths::get_cache_dir() const {
|
|||
return cache_dir;
|
||||
}
|
||||
|
||||
String EditorPaths::get_tmp_dir() const {
|
||||
return tmp_dir;
|
||||
}
|
||||
|
||||
String EditorPaths::get_project_data_dir() const {
|
||||
return project_data_dir;
|
||||
}
|
||||
|
@ -160,6 +164,7 @@ EditorPaths::EditorPaths() {
|
|||
config_dir = data_dir;
|
||||
cache_path = exe_path;
|
||||
cache_dir = data_dir.path_join("cache");
|
||||
tmp_dir = data_dir.path_join("tmp");
|
||||
} else {
|
||||
// Typically XDG_DATA_HOME or %APPDATA%.
|
||||
data_path = OS::get_singleton()->get_data_path();
|
||||
|
@ -174,6 +179,7 @@ EditorPaths::EditorPaths() {
|
|||
} else {
|
||||
cache_dir = cache_path.path_join(OS::get_singleton()->get_godot_dir_name());
|
||||
}
|
||||
tmp_dir = OS::get_singleton()->get_tmp_path();
|
||||
}
|
||||
|
||||
paths_valid = (!data_path.is_empty() && !config_path.is_empty() && !cache_path.is_empty());
|
||||
|
|
|
@ -42,6 +42,7 @@ class EditorPaths : public Object {
|
|||
String data_dir; // Editor data (templates, shader cache, etc.).
|
||||
String config_dir; // Editor config (settings, profiles, themes, etc.).
|
||||
String cache_dir; // Editor cache (thumbnails, tmp generated files).
|
||||
String tmp_dir; // Editor temporary directory.
|
||||
String project_data_dir; // Project-specific data (metadata, shader cache, etc.).
|
||||
bool self_contained = false; // Self-contained means everything goes to `editor_data` dir.
|
||||
String self_contained_file; // Self-contained file with configuration.
|
||||
|
@ -61,6 +62,7 @@ public:
|
|||
String get_data_dir() const;
|
||||
String get_config_dir() const;
|
||||
String get_cache_dir() const;
|
||||
String get_tmp_dir() const;
|
||||
String get_project_data_dir() const;
|
||||
String get_export_templates_dir() const;
|
||||
String get_debug_keystore_path() const;
|
||||
|
|
|
@ -131,6 +131,18 @@ public class GodotIO {
|
|||
return activity.getCacheDir().getAbsolutePath();
|
||||
}
|
||||
|
||||
public String getTmpDir() {
|
||||
File tmpDir = new File(getCacheDir() + "/tmp");
|
||||
|
||||
if (!tmpDir.exists()) {
|
||||
if (!tmpDir.mkdirs()) {
|
||||
Log.e(TAG, "Unable to create tmp dir");
|
||||
}
|
||||
}
|
||||
|
||||
return tmpDir.getAbsolutePath();
|
||||
}
|
||||
|
||||
public String getDataDir() {
|
||||
return activity.getFilesDir().getAbsolutePath();
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc
|
|||
|
||||
_open_URI = p_env->GetMethodID(cls, "openURI", "(Ljava/lang/String;)I");
|
||||
_get_cache_dir = p_env->GetMethodID(cls, "getCacheDir", "()Ljava/lang/String;");
|
||||
_get_tmp_dir = p_env->GetMethodID(cls, "getTmpDir", "()Ljava/lang/String;");
|
||||
_get_data_dir = p_env->GetMethodID(cls, "getDataDir", "()Ljava/lang/String;");
|
||||
_get_display_cutouts = p_env->GetMethodID(cls, "getDisplayCutouts", "()[I"),
|
||||
_get_display_safe_area = p_env->GetMethodID(cls, "getDisplaySafeArea", "()[I"),
|
||||
|
@ -106,6 +107,17 @@ String GodotIOJavaWrapper::get_cache_dir() {
|
|||
}
|
||||
}
|
||||
|
||||
String GodotIOJavaWrapper::get_tmp_dir() {
|
||||
if (_get_tmp_dir) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
ERR_FAIL_NULL_V(env, String());
|
||||
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_tmp_dir);
|
||||
return jstring_to_string(s, env);
|
||||
} else {
|
||||
return String();
|
||||
}
|
||||
}
|
||||
|
||||
String GodotIOJavaWrapper::get_user_data_dir() {
|
||||
if (_get_data_dir) {
|
||||
JNIEnv *env = get_jni_env();
|
||||
|
|
|
@ -48,6 +48,7 @@ private:
|
|||
jmethodID _open_URI = 0;
|
||||
jmethodID _get_cache_dir = 0;
|
||||
jmethodID _get_data_dir = 0;
|
||||
jmethodID _get_tmp_dir = 0;
|
||||
jmethodID _get_display_cutouts = 0;
|
||||
jmethodID _get_display_safe_area = 0;
|
||||
jmethodID _get_locale = 0;
|
||||
|
@ -71,6 +72,7 @@ public:
|
|||
|
||||
Error open_uri(const String &p_uri);
|
||||
String get_cache_dir();
|
||||
String get_tmp_dir();
|
||||
String get_user_data_dir();
|
||||
String get_locale();
|
||||
String get_model();
|
||||
|
|
|
@ -677,6 +677,19 @@ String OS_Android::get_cache_path() const {
|
|||
return ".";
|
||||
}
|
||||
|
||||
String OS_Android::get_tmp_path() const {
|
||||
if (!tmp_dir_cache.is_empty()) {
|
||||
return tmp_dir_cache;
|
||||
}
|
||||
|
||||
String tmp_dir = godot_io_java->get_tmp_dir();
|
||||
if (!tmp_dir.is_empty()) {
|
||||
tmp_dir_cache = _remove_symlink(tmp_dir);
|
||||
return tmp_dir_cache;
|
||||
}
|
||||
return ".";
|
||||
}
|
||||
|
||||
String OS_Android::get_unique_id() const {
|
||||
String unique_id = godot_io_java->get_unique_id();
|
||||
if (!unique_id.is_empty()) {
|
||||
|
|
|
@ -58,6 +58,7 @@ private:
|
|||
|
||||
mutable String data_dir_cache;
|
||||
mutable String cache_dir_cache;
|
||||
mutable String tmp_dir_cache;
|
||||
mutable String remote_fs_dir;
|
||||
|
||||
AudioDriverOpenSL audio_driver_android;
|
||||
|
@ -148,6 +149,7 @@ public:
|
|||
virtual String get_user_data_dir() const override;
|
||||
virtual String get_data_path() const override;
|
||||
virtual String get_cache_path() const override;
|
||||
virtual String get_tmp_path() const override;
|
||||
virtual String get_resource_dir() const override;
|
||||
virtual String get_locale() const override;
|
||||
virtual String get_model_name() const override;
|
||||
|
|
|
@ -117,6 +117,7 @@ public:
|
|||
virtual String get_user_data_dir() const override;
|
||||
|
||||
virtual String get_cache_path() const override;
|
||||
virtual String get_tmp_path() const override;
|
||||
|
||||
virtual String get_locale() const override;
|
||||
|
||||
|
|
|
@ -336,6 +336,22 @@ String OS_IOS::get_cache_path() const {
|
|||
return ret;
|
||||
}
|
||||
|
||||
String OS_IOS::get_tmp_path() const {
|
||||
static String ret;
|
||||
if (ret.is_empty()) {
|
||||
NSURL *url = [NSURL fileURLWithPath:NSTemporaryDirectory()
|
||||
isDirectory:YES];
|
||||
if (url) {
|
||||
NSString *url_path = [url absoluteString];
|
||||
ret.parse_utf8([url_path UTF8String]);
|
||||
if (ret.begins_with("file://")) {
|
||||
ret = ret.replace_first("file://", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
String OS_IOS::get_locale() const {
|
||||
NSString *preferedLanguage = [NSLocale preferredLanguages].firstObject;
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ public:
|
|||
virtual String get_config_path() const override;
|
||||
virtual String get_data_path() const override;
|
||||
virtual String get_cache_path() const override;
|
||||
virtual String get_tmp_path() const override;
|
||||
virtual String get_bundle_resource_dir() const override;
|
||||
virtual String get_bundle_icon_path() const override;
|
||||
virtual String get_godot_dir_name() const override;
|
||||
|
|
|
@ -267,6 +267,22 @@ String OS_MacOS::get_cache_path() const {
|
|||
return get_config_path();
|
||||
}
|
||||
|
||||
String OS_MacOS::get_tmp_path() const {
|
||||
static String ret;
|
||||
if (ret.is_empty()) {
|
||||
NSURL *url = [NSURL fileURLWithPath:NSTemporaryDirectory()
|
||||
isDirectory:YES];
|
||||
if (url) {
|
||||
NSString *url_path = [url absoluteString];
|
||||
ret.parse_utf8([url_path UTF8String]);
|
||||
if (ret.begins_with("file://")) {
|
||||
ret = ret.replace_first("file://", "");
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
String OS_MacOS::get_bundle_resource_dir() const {
|
||||
String ret;
|
||||
|
||||
|
|
|
@ -1850,16 +1850,35 @@ String OS_Windows::get_cache_path() const {
|
|||
if (has_environment("LOCALAPPDATA")) {
|
||||
cache_path_cache = get_environment("LOCALAPPDATA").replace("\\", "/");
|
||||
}
|
||||
if (cache_path_cache.is_empty() && has_environment("TEMP")) {
|
||||
cache_path_cache = get_environment("TEMP").replace("\\", "/");
|
||||
}
|
||||
if (cache_path_cache.is_empty()) {
|
||||
cache_path_cache = get_config_path();
|
||||
cache_path_cache = get_tmp_path();
|
||||
}
|
||||
}
|
||||
return cache_path_cache;
|
||||
}
|
||||
|
||||
String OS_Windows::get_tmp_path() const {
|
||||
static String tmp_path_cache;
|
||||
if (tmp_path_cache.is_empty()) {
|
||||
{
|
||||
// Get the tmp path from the Windows API.
|
||||
void *get_temp_path = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetTempPathW");
|
||||
if (get_temp_path) {
|
||||
Vector<WCHAR> tmp_path;
|
||||
tmp_path.resize(MAX_PATH);
|
||||
DWORD tmp_path_length = GetTempPathW(MAX_PATH, (LPWSTR)tmp_path.ptrw());
|
||||
if (tmp_path_length > 0 && tmp_path_length < MAX_PATH) {
|
||||
tmp_path_cache = String::utf16((const char16_t *)tmp_path.ptr(), tmp_path_length / sizeof(WCHAR));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tmp_path_cache.is_empty()) {
|
||||
tmp_path_cache = get_config_path();
|
||||
}
|
||||
}
|
||||
return tmp_path_cache;
|
||||
}
|
||||
|
||||
// Get properly capitalized engine name for system paths
|
||||
String OS_Windows::get_godot_dir_name() const {
|
||||
return String(VERSION_SHORT_NAME).capitalize();
|
||||
|
|
|
@ -215,6 +215,7 @@ public:
|
|||
virtual String get_config_path() const override;
|
||||
virtual String get_data_path() const override;
|
||||
virtual String get_cache_path() const override;
|
||||
virtual String get_tmp_path() const override;
|
||||
virtual String get_godot_dir_name() const override;
|
||||
|
||||
virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const override;
|
||||
|
|
|
@ -7260,6 +7260,10 @@ void RenderingDevice::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(DEBUG_PASS);
|
||||
}
|
||||
|
||||
void RenderingDevice::make_current() {
|
||||
render_thread_id = Thread::get_caller_id();
|
||||
}
|
||||
|
||||
RenderingDevice::~RenderingDevice() {
|
||||
finalize();
|
||||
|
||||
|
|
|
@ -1496,6 +1496,8 @@ public:
|
|||
|
||||
static RenderingDevice *get_singleton();
|
||||
|
||||
void make_current();
|
||||
|
||||
RenderingDevice();
|
||||
~RenderingDevice();
|
||||
|
||||
|
|
|
@ -370,6 +370,8 @@ Size2i RenderingServerDefault::get_maximum_viewport_size() const {
|
|||
void RenderingServerDefault::_assign_mt_ids(WorkerThreadPool::TaskID p_pump_task_id) {
|
||||
server_thread = Thread::get_caller_id();
|
||||
server_task_id = p_pump_task_id;
|
||||
// This is needed because the main RD is created on the main thread.
|
||||
RenderingDevice::get_singleton()->make_current();
|
||||
}
|
||||
|
||||
void RenderingServerDefault::_thread_exit() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user