diff options
Diffstat (limited to 'core')
28 files changed, 500 insertions, 41 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index f47d540351..b47e611a51 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -453,6 +453,11 @@ int _OS::get_power_percent_left() { return OS::get_singleton()->get_power_percent_left(); } +bool _OS::has_feature(const String &p_feature) const { + + return OS::get_singleton()->has_feature(p_feature); +} + /* enum Weekday { DAY_SUNDAY, @@ -755,6 +760,11 @@ bool _OS::can_draw() const { return OS::get_singleton()->can_draw(); } +bool _OS::is_userfs_persistent() const { + + return OS::get_singleton()->is_userfs_persistent(); +} + int _OS::get_processor_count() const { return OS::get_singleton()->get_processor_count(); @@ -858,6 +868,10 @@ void _OS::hide_virtual_keyboard() { OS::get_singleton()->hide_virtual_keyboard(); } +int _OS::get_virtual_keyboard_height() { + return OS::get_singleton()->get_virtual_keyboard_height(); +} + void _OS::print_all_resources(const String &p_to_file) { OS::get_singleton()->print_all_resources(p_to_file); @@ -1051,6 +1065,7 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_model_name"), &_OS::get_model_name); ClassDB::bind_method(D_METHOD("can_draw"), &_OS::can_draw); + ClassDB::bind_method(D_METHOD("is_userfs_persistent"), &_OS::is_userfs_persistent); ClassDB::bind_method(D_METHOD("is_stdout_verbose"), &_OS::is_stdout_verbose); ClassDB::bind_method(D_METHOD("can_use_threads"), &_OS::can_use_threads); @@ -1064,6 +1079,7 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("has_virtual_keyboard"), &_OS::has_virtual_keyboard); ClassDB::bind_method(D_METHOD("show_virtual_keyboard", "existing_text"), &_OS::show_virtual_keyboard, DEFVAL("")); ClassDB::bind_method(D_METHOD("hide_virtual_keyboard"), &_OS::hide_virtual_keyboard); + ClassDB::bind_method(D_METHOD("get_virtual_keyboard_height"), &_OS::get_virtual_keyboard_height); ClassDB::bind_method(D_METHOD("print_resources_in_use", "short"), &_OS::print_resources_in_use, DEFVAL(false)); ClassDB::bind_method(D_METHOD("print_all_resources", "tofile"), &_OS::print_all_resources, DEFVAL("")); @@ -1099,6 +1115,8 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("set_use_vsync", "enable"), &_OS::set_use_vsync); ClassDB::bind_method(D_METHOD("is_vsync_enabled"), &_OS::is_vsync_enabled); + ClassDB::bind_method(D_METHOD("has_feature", "tag_name"), &_OS::has_feature); + ClassDB::bind_method(D_METHOD("get_power_state"), &_OS::get_power_state); ClassDB::bind_method(D_METHOD("get_power_seconds_left"), &_OS::get_power_seconds_left); ClassDB::bind_method(D_METHOD("get_power_percent_left"), &_OS::get_power_percent_left); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index f12ab9f000..7f8c734e36 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -204,6 +204,7 @@ public: bool has_virtual_keyboard() const; void show_virtual_keyboard(const String &p_existing_text = ""); void hide_virtual_keyboard(); + int get_virtual_keyboard_height(); void print_resources_in_use(bool p_short = false); void print_all_resources(const String &p_to_file); @@ -266,6 +267,8 @@ public: bool can_draw() const; + bool is_userfs_persistent() const; + bool is_stdout_verbose() const; int get_processor_count() const; @@ -315,6 +318,8 @@ public: int get_power_seconds_left(); int get_power_percent_left(); + bool has_feature(const String &p_feature) const; + static _OS *get_singleton() { return singleton; } _OS(); diff --git a/core/error_macros.cpp b/core/error_macros.cpp index 5919d38375..170a22e8dd 100644 --- a/core/error_macros.cpp +++ b/core/error_macros.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "error_macros.h" +#include "io/logger.h" #include "os/os.h" bool _err_error_exists = false; @@ -79,7 +80,7 @@ void remove_error_handler(ErrorHandlerList *p_handler) { void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, ErrorHandlerType p_type) { - OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, _err_error_exists ? OS::get_singleton()->get_last_error() : "", (OS::ErrorType)p_type); + OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, _err_error_exists ? OS::get_singleton()->get_last_error() : "", (Logger::ErrorType)p_type); _global_lock(); ErrorHandlerList *l = error_handler_list; diff --git a/core/io/file_access_buffered_fa.h b/core/io/file_access_buffered_fa.h index 9e41834561..309fc16d09 100644 --- a/core/io/file_access_buffered_fa.h +++ b/core/io/file_access_buffered_fa.h @@ -76,6 +76,11 @@ protected: }; public: + void flush() { + + f.flush(); + }; + void store_8(uint8_t p_dest) { f.store_8(p_dest); diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index 4750945854..514e3c65f0 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -338,6 +338,13 @@ Error FileAccessCompressed::get_error() const { return read_eof ? ERR_FILE_EOF : OK; } +void FileAccessCompressed::flush() { + ERR_FAIL_COND(!f); + ERR_FAIL_COND(!writing); + + // compressed files keep data in memory till close() +} + void FileAccessCompressed::store_8(uint8_t p_dest) { ERR_FAIL_COND(!f); diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h index 1a57e2d4ee..1d99e5bfd4 100644 --- a/core/io/file_access_compressed.h +++ b/core/io/file_access_compressed.h @@ -84,6 +84,7 @@ public: virtual Error get_error() const; ///< get last error + virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte virtual bool file_exists(const String &p_name); ///< return true if a file exists diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 461c5bafe2..c93e12f7da 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -268,6 +268,12 @@ void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) { } } +void FileAccessEncrypted::flush() { + ERR_FAIL_COND(!writing); + + // encrypted files keep data in memory till close() +} + void FileAccessEncrypted::store_8(uint8_t p_dest) { ERR_FAIL_COND(!writing); diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h index 82f60ac654..d83fed3e0e 100644 --- a/core/io/file_access_encrypted.h +++ b/core/io/file_access_encrypted.h @@ -71,6 +71,7 @@ public: virtual Error get_error() const; ///< get last error + virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index b948394385..0a5815fca8 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -170,6 +170,10 @@ Error FileAccessMemory::get_error() const { return pos >= length ? ERR_FILE_EOF : OK; } +void FileAccessMemory::flush() { + ERR_FAIL_COND(!data); +} + void FileAccessMemory::store_8(uint8_t p_byte) { ERR_FAIL_COND(!data); diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h index b7b8430089..23392719b4 100644 --- a/core/io/file_access_memory.h +++ b/core/io/file_access_memory.h @@ -62,6 +62,7 @@ public: virtual Error get_error() const; ///< get last error + virtual void flush(); virtual void store_8(uint8_t p_byte); ///< store a byte virtual void store_buffer(const uint8_t *p_src, int p_length); ///< store an array of bytes diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index 8c624226a1..a224abd9e7 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -456,6 +456,10 @@ Error FileAccessNetwork::get_error() const { return pos == total_size ? ERR_FILE_EOF : OK; } +void FileAccessNetwork::flush() { + ERR_FAIL(); +} + void FileAccessNetwork::store_8(uint8_t p_dest) { ERR_FAIL(); diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index abbe378b60..20614476d0 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -155,6 +155,7 @@ public: virtual Error get_error() const; ///< get last error + virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte virtual bool file_exists(const String &p_path); ///< return true if a file exists diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index ff4c28ec39..a7eb8ce6a9 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -293,6 +293,11 @@ Error FileAccessPack::get_error() const { return OK; } +void FileAccessPack::flush() { + + ERR_FAIL(); +} + void FileAccessPack::store_8(uint8_t p_dest) { ERR_FAIL(); diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 3deb0d2bd3..12187a353a 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -161,6 +161,7 @@ public: virtual Error get_error() const; + virtual void flush(); virtual void store_8(uint8_t p_dest); virtual void store_buffer(const uint8_t *p_src, int p_length); diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index 73b23ac702..ec809011a9 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -353,6 +353,11 @@ Error FileAccessZip::get_error() const { return OK; }; +void FileAccessZip::flush() { + + ERR_FAIL(); +} + void FileAccessZip::store_8(uint8_t p_dest) { ERR_FAIL(); diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index a40e1a753d..0977b241ee 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -108,6 +108,7 @@ public: virtual Error get_error() const; ///< get last error + virtual void flush(); virtual void store_8(uint8_t p_dest); ///< store a byte virtual bool file_exists(const String &p_name); ///< return true if a file exists diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index dd56db9bf9..b8c0a2b616 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -297,7 +297,7 @@ Error HTTPClient::poll() { case StreamPeerTCP::STATUS_CONNECTED: { if (ssl) { Ref<StreamPeerSSL> ssl = StreamPeerSSL::create(); - Error err = ssl->connect_to_stream(tcp_connection, true, ssl_verify_host ? conn_host : String()); + Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, ssl_verify_host ? conn_host : String()); if (err != OK) { close(); status = STATUS_SSL_HANDSHAKE_ERROR; diff --git a/core/io/logger.cpp b/core/io/logger.cpp new file mode 100644 index 0000000000..b94007d316 --- /dev/null +++ b/core/io/logger.cpp @@ -0,0 +1,255 @@ +/*************************************************************************/ +/* logger.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "logger.h" +#include "os/dir_access.h" +#include "os/os.h" +#include "print_string.h" + +bool Logger::should_log(bool p_err) { + return (!p_err || _print_error_enabled) && (p_err || _print_line_enabled); +} + +void Logger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) { + if (!should_log(true)) { + return; + } + + const char *err_type = "**ERROR**"; + switch (p_type) { + case ERR_ERROR: err_type = "**ERROR**"; break; + case ERR_WARNING: err_type = "**WARNING**"; break; + case ERR_SCRIPT: err_type = "**SCRIPT ERROR**"; break; + case ERR_SHADER: err_type = "**SHADER ERROR**"; break; + default: ERR_PRINT("Unknown error type"); break; + } + + const char *err_details; + if (p_rationale && *p_rationale) + err_details = p_rationale; + else + err_details = p_code; + + logf_error("%s: %s\n", err_type, err_details); + logf_error(" At: %s:%i:%s() - %s\n", p_file, p_line, p_function, p_code); +} + +void Logger::logf(const char *p_format, ...) { + if (!should_log(false)) { + return; + } + + va_list argp; + va_start(argp, p_format); + + logv(p_format, argp, false); + + va_end(argp); +} + +void Logger::logf_error(const char *p_format, ...) { + if (!should_log(true)) { + return; + } + + va_list argp; + va_start(argp, p_format); + + logv(p_format, argp, true); + + va_end(argp); +} + +Logger::~Logger() {} + +void RotatedFileLogger::close_file() { + if (file) { + memdelete(file); + file = NULL; + } +} + +void RotatedFileLogger::clear_old_backups() { + int max_backups = max_files - 1; // -1 for the current file + + String basename = base_path.get_basename(); + String extension = "." + base_path.get_extension(); + + DirAccess *da = DirAccess::open(base_path.get_base_dir()); + if (!da) { + return; + } + + da->list_dir_begin(); + String f = da->get_next(); + Set<String> backups; + while (f != String()) { + if (!da->current_is_dir() && f.begins_with(basename) && f.ends_with(extension) && f != base_path) { + backups.insert(f); + } + f = da->get_next(); + } + da->list_dir_end(); + + if (backups.size() > max_backups) { + // since backups are appended with timestamp and Set iterates them in sorted order, + // first backups are the oldest + int to_delete = backups.size() - max_backups; + for (Set<String>::Element *E = backups.front(); E && to_delete > 0; E = E->next(), --to_delete) { + da->remove(E->get()); + } + } + + memdelete(da); +} + +void RotatedFileLogger::rotate_file() { + close_file(); + + if (FileAccess::exists(base_path)) { + if (max_files > 1) { + char timestamp[21]; + OS::Date date = OS::get_singleton()->get_date(); + OS::Time time = OS::get_singleton()->get_time(); + sprintf(timestamp, "-%04d-%02d-%02d-%02d-%02d-%02d", date.year, date.month, date.day + 1, time.hour, time.min, time.sec); + + String backup_name = base_path.get_basename() + timestamp + "." + base_path.get_extension(); + + DirAccess *da = DirAccess::open(base_path.get_base_dir()); + if (da) { + da->copy(base_path, backup_name); + memdelete(da); + } + clear_old_backups(); + } + } else { + DirAccess *da = DirAccess::create(DirAccess::ACCESS_USERDATA); + if (da) { + da->make_dir_recursive(base_path.get_base_dir()); + memdelete(da); + } + } + + file = FileAccess::open(base_path, FileAccess::WRITE); +} + +RotatedFileLogger::RotatedFileLogger(const String &p_base_path, int p_max_files) { + file = NULL; + base_path = p_base_path.simplify_path(); + max_files = p_max_files > 0 ? p_max_files : 1; + + rotate_file(); +} + +void RotatedFileLogger::logv(const char *p_format, va_list p_list, bool p_err) { + if (!should_log(p_err)) { + return; + } + + if (file) { + const int static_buf_size = 512; + char static_buf[static_buf_size]; + char *buf = static_buf; + va_list list_copy; + va_copy(list_copy, p_list); + int len = vsnprintf(buf, static_buf_size, p_format, p_list); + if (len >= static_buf_size) { + buf = (char *)Memory::alloc_static(len + 1); + vsnprintf(buf, len + 1, p_format, list_copy); + } + va_end(list_copy); + file->store_buffer((uint8_t *)buf, len); + if (len >= static_buf_size) { + Memory::free_static(buf); + } +#ifdef DEBUG_ENABLED + const bool need_flush = true; +#else + bool need_flush = p_err; +#endif + if (need_flush) { + file->flush(); + } + } +} + +RotatedFileLogger::~RotatedFileLogger() { + close_file(); +} + +void StdLogger::logv(const char *p_format, va_list p_list, bool p_err) { + if (!should_log(p_err)) { + return; + } + + if (p_err) { + vfprintf(stderr, p_format, p_list); + } else { + vprintf(p_format, p_list); +#ifdef DEBUG_ENABLED + fflush(stdout); +#endif + } +} + +StdLogger::~StdLogger() {} + +CompositeLogger::CompositeLogger(Vector<Logger *> p_loggers) { + loggers = p_loggers; +} + +void CompositeLogger::logv(const char *p_format, va_list p_list, bool p_err) { + if (!should_log(p_err)) { + return; + } + + for (int i = 0; i < loggers.size(); ++i) { + va_list list_copy; + va_copy(list_copy, p_list); + loggers[i]->logv(p_format, list_copy, p_err); + va_end(list_copy); + } +} + +void CompositeLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) { + if (!should_log(true)) { + return; + } + + for (int i = 0; i < loggers.size(); ++i) { + loggers[i]->log_error(p_function, p_file, p_line, p_code, p_rationale, p_type); + } +} + +CompositeLogger::~CompositeLogger() { + for (int i = 0; i < loggers.size(); ++i) { + memdelete(loggers[i]); + } +} diff --git a/core/io/logger.h b/core/io/logger.h new file mode 100644 index 0000000000..cf0cc7699f --- /dev/null +++ b/core/io/logger.h @@ -0,0 +1,107 @@ +/*************************************************************************/ +/* logger.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef LOGGER_H +#define LOGGER_H + +#include "os/file_access.h" +#include "ustring.h" +#include "vector.h" +#include <stdarg.h> + +class Logger { +protected: + bool should_log(bool p_err); + +public: + enum ErrorType { + ERR_ERROR, + ERR_WARNING, + ERR_SCRIPT, + ERR_SHADER + }; + + virtual void logv(const char *p_format, va_list p_list, bool p_err) = 0; + virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR); + + void logf(const char *p_format, ...); + void logf_error(const char *p_format, ...); + + virtual ~Logger(); +}; + +/** + * Writes messages to stdout/stderr. + */ +class StdLogger : public Logger { + +public: + virtual void logv(const char *p_format, va_list p_list, bool p_err); + virtual ~StdLogger(); +}; + +/** + * Writes messages to the specified file. If the file already exists, creates a copy (backup) + * of it with timestamp appended to the file name. Maximum number of backups is configurable. + * When maximum is reached, the oldest backups are erased. With the maximum being equal to 1, + * it acts as a simple file logger. + */ +class RotatedFileLogger : public Logger { + String base_path; + int max_files; + + FileAccess *file; + + void rotate_file_without_closing(); + void close_file(); + void clear_old_backups(); + void rotate_file(); + +public: + RotatedFileLogger(const String &p_base_path, int p_max_files = 10); + + virtual void logv(const char *p_format, va_list p_list, bool p_err); + + virtual ~RotatedFileLogger(); +}; + +class CompositeLogger : public Logger { + Vector<Logger *> loggers; + +public: + CompositeLogger(Vector<Logger *> p_loggers); + + virtual void logv(const char *p_format, va_list p_list, bool p_err); + virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR); + + virtual ~CompositeLogger(); +}; + +#endif
\ No newline at end of file diff --git a/core/io/resource_import.cpp b/core/io/resource_import.cpp index bc7ea47762..401d704222 100644 --- a/core/io/resource_import.cpp +++ b/core/io/resource_import.cpp @@ -77,7 +77,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy if (assign != String()) { if (!path_found && assign.begins_with("path.") && r_path_and_type.path == String()) { String feature = assign.get_slicec('.', 1); - if (OS::get_singleton()->check_feature_support(feature)) { + if (OS::get_singleton()->has_feature(feature)) { r_path_and_type.path = value; path_found = true; //first match must have priority } diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 89cb4a22c2..ed0d491679 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -492,7 +492,7 @@ void ResourceLoader::reload_translation_remaps() { void ResourceLoader::load_translation_remaps() { - if (!ProjectSettings::get_singleton()->has("locale/translation_remaps")) + if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) return; Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps"); diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index b969b58bfb..fcb3b58fed 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -55,7 +55,7 @@ FileAccess *FileAccess::create(AccessType p_access) { bool FileAccess::exists(const String &p_name) { - if (PackedData::get_singleton()->has_path(p_name)) + if (PackedData::get_singleton() && PackedData::get_singleton()->has_path(p_name)) return true; FileAccess *f = open(p_name, READ); diff --git a/core/os/file_access.h b/core/os/file_access.h index 34e7549fa3..455dd1ea99 100644 --- a/core/os/file_access.h +++ b/core/os/file_access.h @@ -119,6 +119,7 @@ public: virtual Error get_error() const = 0; ///< get last error + virtual void flush() = 0; virtual void store_8(uint8_t p_dest) = 0; ///< store a byte virtual void store_16(uint16_t p_dest); ///< store 16 bits uint virtual void store_32(uint32_t p_dest); ///< store 32 bits uint diff --git a/core/os/os.cpp b/core/os/os.cpp index 437ce01a5e..eb5d5be33d 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -62,20 +62,20 @@ void OS::debug_break(){ // something }; -void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) { - - const char *err_type = "**ERROR**"; - switch (p_type) { - case ERR_ERROR: err_type = "**ERROR**"; break; - case ERR_WARNING: err_type = "**WARNING**"; break; - case ERR_SCRIPT: err_type = "**SCRIPT ERROR**"; break; - case ERR_SHADER: err_type = "**SHADER ERROR**"; break; - default: ERR_PRINT("Unknown error type"); break; +void OS::_set_logger(Logger *p_logger) { + if (_logger) { + memdelete(_logger); } + _logger = p_logger; +} + +void OS::initialize_logger() { + _set_logger(memnew(StdLogger)); +} + +void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type) { - if (p_rationale && *p_rationale) - print("%s: %s\n ", err_type, p_rationale); - print("%s: At: %s:%i:%s() - %s\n", err_type, p_file, p_line, p_function, p_code); + _logger->log_error(p_function, p_file, p_line, p_code, p_rationale, p_type); } void OS::print(const char *p_format, ...) { @@ -83,17 +83,16 @@ void OS::print(const char *p_format, ...) { va_list argp; va_start(argp, p_format); - vprint(p_format, argp); + _logger->logv(p_format, argp, false); va_end(argp); }; void OS::printerr(const char *p_format, ...) { - va_list argp; va_start(argp, p_format); - vprint(p_format, argp, true); + _logger->logv(p_format, argp, true); va_end(argp); }; @@ -194,6 +193,10 @@ void OS::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_scr void OS::hide_virtual_keyboard() { } +int OS::get_virtual_keyboard_height() const { + return 0; +} + void OS::print_all_resources(String p_to_file) { ERR_FAIL_COND(p_to_file != "" && _OSPRF); @@ -495,7 +498,7 @@ int OS::get_power_percent_left() { return -1; } -bool OS::check_feature_support(const String &p_feature) { +bool OS::has_feature(const String &p_feature) { if (p_feature == get_name()) return true; @@ -507,6 +510,13 @@ bool OS::check_feature_support(const String &p_feature) { return true; #endif + if (sizeof(void *) == 8 && p_feature == "64") { + return true; + } + if (sizeof(void *) == 4 && p_feature == "32") { + return true; + } + if (_check_internal_feature_support(p_feature)) return true; @@ -531,11 +541,14 @@ OS::OS() { _render_thread_mode = RENDER_THREAD_SAFE; - _allow_hidpi = true; + _allow_hidpi = false; _stack_bottom = (void *)(&stack_bottom); + + _logger = NULL; + _set_logger(memnew(StdLogger)); } OS::~OS() { - + memdelete(_logger); singleton = NULL; } diff --git a/core/os/os.h b/core/os/os.h index 3806217f55..6fcfd71332 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -32,6 +32,7 @@ #include "engine.h" #include "image.h" +#include "io/logger.h" #include "list.h" #include "os/main_loop.h" #include "ustring.h" @@ -61,6 +62,11 @@ class OS { void *_stack_bottom; + Logger *_logger; + +protected: + void _set_logger(Logger *p_logger); + public: typedef void (*ImeCallback)(void *p_inp, String p_text, Point2 p_selection); @@ -108,6 +114,7 @@ protected: virtual int get_audio_driver_count() const = 0; virtual const char *get_audio_driver_name(int p_driver) const = 0; + virtual void initialize_logger(); virtual void initialize_core() = 0; virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) = 0; @@ -127,18 +134,10 @@ public: static OS *get_singleton(); - enum ErrorType { - ERR_ERROR, - ERR_WARNING, - ERR_SCRIPT, - ERR_SHADER - }; + void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type = Logger::ERR_ERROR); + void print(const char *p_format, ...); + void printerr(const char *p_format, ...); - virtual void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR); - - virtual void print(const char *p_format, ...); - virtual void printerr(const char *p_format, ...); - virtual void vprint(const char *p_format, va_list p_list, bool p_stderr = false) = 0; virtual void alert(const String &p_alert, const String &p_title = "ALERT!") = 0; virtual String get_stdin_string(bool p_block = true) = 0; @@ -284,6 +283,8 @@ public: virtual bool can_draw() const = 0; + virtual bool is_userfs_persistent() const { return true; } + bool is_stdout_verbose() const; virtual void disable_crash_handler() {} @@ -314,6 +315,9 @@ public: virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2()); virtual void hide_virtual_keyboard(); + // returns height of the currently shown virtual keyboard (0 if keyboard is hidden) + virtual int get_virtual_keyboard_height() const; + virtual void set_cursor_shape(CursorShape p_shape) = 0; virtual bool get_swap_ok_cancel() { return false; } @@ -426,7 +430,7 @@ public: virtual int get_power_seconds_left(); virtual int get_power_percent_left(); - bool check_feature_support(const String &p_feature); + bool has_feature(const String &p_feature); /** * Returns the stack bottom of the main thread of the application. diff --git a/core/project_settings.cpp b/core/project_settings.cpp index 14ebe87dc5..ff2be87b07 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -152,7 +152,7 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { bool override_valid = false; for (int i = 1; i < s.size(); i++) { String feature = s[i].strip_edges(); - if (OS::get_singleton()->check_feature_support(feature) || custom_features.has(feature)) { + if (OS::get_singleton()->has_feature(feature) || custom_features.has(feature)) { override_valid = true; break; } @@ -420,7 +420,7 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack) { return OK; } -bool ProjectSettings::has(String p_var) const { +bool ProjectSettings::has_setting(String p_var) const { _THREAD_SAFE_METHOD_ @@ -800,7 +800,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default) { Variant ret; - if (ProjectSettings::get_singleton()->has(p_var)) { + if (ProjectSettings::get_singleton()->has_setting(p_var)) { ret = ProjectSettings::get_singleton()->get(p_var); } else { ProjectSettings::get_singleton()->set(p_var, p_default); @@ -907,9 +907,19 @@ Variant ProjectSettings::property_get_revert(const String &p_name) { return props[p_name].initial; } +void ProjectSettings::set_setting(const String &p_setting, const Variant &p_value) { + set(p_setting, p_value); +} + +Variant ProjectSettings::get_setting(const String &p_setting) const { + return get(p_setting); +} + void ProjectSettings::_bind_methods() { - ClassDB::bind_method(D_METHOD("has", "name"), &ProjectSettings::has); + ClassDB::bind_method(D_METHOD("has_setting", "name"), &ProjectSettings::has_setting); + ClassDB::bind_method(D_METHOD("set_setting", "name", "value"), &ProjectSettings::set_setting); + ClassDB::bind_method(D_METHOD("get_setting", "name"), &ProjectSettings::get_setting); ClassDB::bind_method(D_METHOD("set_order", "name", "position"), &ProjectSettings::set_order); ClassDB::bind_method(D_METHOD("get_order", "name"), &ProjectSettings::get_order); ClassDB::bind_method(D_METHOD("set_initial_value", "name", "value"), &ProjectSettings::set_initial_value); diff --git a/core/project_settings.h b/core/project_settings.h index 718ab2a011..ea6034dc84 100644 --- a/core/project_settings.h +++ b/core/project_settings.h @@ -119,7 +119,10 @@ protected: static void _bind_methods(); public: - bool has(String p_var) const; + void set_setting(const String &p_setting, const Variant &p_value); + Variant get_setting(const String &p_setting) const; + + bool has_setting(String p_var) const; String localize_path(const String &p_path) const; String globalize_path(const String &p_path) const; diff --git a/core/translation.cpp b/core/translation.cpp index f1f9c72b85..27e3b202d0 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -1052,7 +1052,7 @@ TranslationServer *TranslationServer::singleton = NULL; bool TranslationServer::_load_translations(const String &p_from) { - if (ProjectSettings::get_singleton()->has(p_from)) { + if (ProjectSettings::get_singleton()->has_setting(p_from)) { PoolVector<String> translations = ProjectSettings::get_singleton()->get(p_from); int tcount = translations.size(); |