mirror of
https://github.com/godotengine/godot.git
synced 2024-11-21 03:18:37 +08:00
commit
132ba0ed97
@ -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;
|
||||
|
@ -76,6 +76,11 @@ protected:
|
||||
};
|
||||
|
||||
public:
|
||||
void flush() {
|
||||
|
||||
f.flush();
|
||||
};
|
||||
|
||||
void store_8(uint8_t p_dest) {
|
||||
|
||||
f.store_8(p_dest);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
||||
|
252
core/io/logger.cpp
Normal file
252
core/io/logger.cpp
Normal file
@ -0,0 +1,252 @@
|
||||
/*************************************************************************/
|
||||
/* 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;
|
||||
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, p_list);
|
||||
}
|
||||
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]);
|
||||
}
|
||||
}
|
107
core/io/logger.h
Normal file
107
core/io/logger.h
Normal file
@ -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
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
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);
|
||||
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) {
|
||||
|
||||
_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);
|
||||
};
|
||||
@ -533,9 +532,12 @@ OS::OS() {
|
||||
|
||||
_allow_hidpi = true;
|
||||
_stack_bottom = (void *)(&stack_bottom);
|
||||
|
||||
_logger = NULL;
|
||||
_set_logger(memnew(StdLogger));
|
||||
}
|
||||
|
||||
OS::~OS() {
|
||||
|
||||
memdelete(_logger);
|
||||
singleton = NULL;
|
||||
}
|
||||
|
21
core/os/os.h
21
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;
|
||||
|
||||
|
@ -223,6 +223,12 @@ Error FileAccessUnix::get_error() const {
|
||||
return last_error;
|
||||
}
|
||||
|
||||
void FileAccessUnix::flush() {
|
||||
|
||||
ERR_FAIL_COND(!f);
|
||||
fflush(f);
|
||||
}
|
||||
|
||||
void FileAccessUnix::store_8(uint8_t p_dest) {
|
||||
|
||||
ERR_FAIL_COND(!f);
|
||||
|
@ -72,6 +72,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
|
||||
|
@ -64,39 +64,7 @@
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
extern bool _print_error_enabled;
|
||||
|
||||
void OS_Unix::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
||||
|
||||
if (!_print_error_enabled)
|
||||
return;
|
||||
|
||||
const char *err_details;
|
||||
if (p_rationale && p_rationale[0])
|
||||
err_details = p_rationale;
|
||||
else
|
||||
err_details = p_code;
|
||||
|
||||
switch (p_type) {
|
||||
case ERR_ERROR:
|
||||
print("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||
print("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_WARNING:
|
||||
print("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||
print("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_SCRIPT:
|
||||
print("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||
print("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_SHADER:
|
||||
print("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||
print("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#include <unistd.h>
|
||||
|
||||
void OS_Unix::debug_break() {
|
||||
|
||||
@ -165,29 +133,16 @@ void OS_Unix::initialize_core() {
|
||||
}
|
||||
}
|
||||
|
||||
void OS_Unix::initialize_logger() {
|
||||
Vector<Logger *> loggers;
|
||||
loggers.push_back(memnew(UnixTerminalLogger));
|
||||
loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
|
||||
_set_logger(memnew(CompositeLogger(loggers)));
|
||||
}
|
||||
|
||||
void OS_Unix::finalize_core() {
|
||||
}
|
||||
|
||||
void OS_Unix::vprint(const char *p_format, va_list p_list, bool p_stder) {
|
||||
|
||||
if (p_stder) {
|
||||
|
||||
vfprintf(stderr, p_format, p_list);
|
||||
fflush(stderr);
|
||||
} else {
|
||||
|
||||
vprintf(p_format, p_list);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
void OS_Unix::print(const char *p_format, ...) {
|
||||
|
||||
va_list argp;
|
||||
va_start(argp, p_format);
|
||||
vprintf(p_format, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
void OS_Unix::alert(const String &p_alert, const String &p_title) {
|
||||
|
||||
fprintf(stderr, "ERROR: %s\n", p_alert.utf8().get_data());
|
||||
@ -559,4 +514,38 @@ String OS_Unix::get_executable_path() const {
|
||||
#endif
|
||||
}
|
||||
|
||||
void UnixTerminalLogger::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_details;
|
||||
if (p_rationale && p_rationale[0])
|
||||
err_details = p_rationale;
|
||||
else
|
||||
err_details = p_code;
|
||||
|
||||
switch (p_type) {
|
||||
case ERR_WARNING:
|
||||
logf_error("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||
logf_error("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_SCRIPT:
|
||||
logf_error("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||
logf_error("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_SHADER:
|
||||
logf_error("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||
logf_error("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_ERROR:
|
||||
default:
|
||||
logf_error("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||
logf_error("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UnixTerminalLogger::~UnixTerminalLogger() {}
|
||||
|
||||
#endif
|
||||
|
@ -54,11 +54,11 @@ protected:
|
||||
virtual int get_audio_driver_count() const;
|
||||
virtual const char *get_audio_driver_name(int p_driver) const;
|
||||
|
||||
virtual void initialize_logger();
|
||||
virtual void initialize_core();
|
||||
virtual int unix_initialize_audio(int p_audio_driver);
|
||||
//virtual void initialize(int p_video_driver,int p_audio_driver);
|
||||
|
||||
//virtual void finalize();
|
||||
virtual void finalize_core();
|
||||
|
||||
String stdin_buf;
|
||||
@ -66,10 +66,6 @@ protected:
|
||||
String get_global_settings_path() const;
|
||||
|
||||
public:
|
||||
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 vprint(const char *p_format, va_list p_list, bool p_stder = false);
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||
virtual String get_stdin_string(bool p_block);
|
||||
|
||||
@ -120,6 +116,12 @@ public:
|
||||
//virtual void run( MainLoop * p_main_loop );
|
||||
};
|
||||
|
||||
class UnixTerminalLogger : public StdLogger {
|
||||
public:
|
||||
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 ~UnixTerminalLogger();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
71
drivers/unix/syslog_logger.cpp
Normal file
71
drivers/unix/syslog_logger.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/*************************************************************************/
|
||||
/* syslog_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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef UNIX_ENABLED
|
||||
|
||||
#include "syslog_logger.h"
|
||||
#include "print_string.h"
|
||||
#include <syslog.h>
|
||||
|
||||
void SyslogLogger::logv(const char *p_format, va_list p_list, bool p_err) {
|
||||
if (!should_log(p_err)) {
|
||||
return;
|
||||
}
|
||||
|
||||
vsyslog(p_err ? LOG_ERR : LOG_INFO, p_format, p_list);
|
||||
}
|
||||
|
||||
void SyslogLogger::print_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;
|
||||
|
||||
syslog(p_type == ERR_WARNING ? LOG_WARNING : LOG_ERR, "%s: %s\n At: %s:%i:%s() - %s", err_type, err_details, p_file, p_line, p_function, p_code);
|
||||
}
|
||||
|
||||
SyslogLogger::~SyslogLogger() {
|
||||
}
|
||||
|
||||
#endif
|
48
drivers/unix/syslog_logger.h
Normal file
48
drivers/unix/syslog_logger.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*************************************************************************/
|
||||
/* syslog_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 SYSLOG_LOGGER_H
|
||||
#define SYSLOG_LOGGER_H
|
||||
|
||||
#ifdef UNIX_ENABLED
|
||||
|
||||
#include "io/logger.h"
|
||||
|
||||
class SyslogLogger : public Logger {
|
||||
public:
|
||||
virtual void logv(const char *p_format, va_list p_list, bool p_err);
|
||||
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);
|
||||
|
||||
virtual ~SyslogLogger();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -162,10 +162,10 @@ Error DirAccessWindows::make_dir(String p_dir) {
|
||||
|
||||
GLOBAL_LOCK_FUNCTION
|
||||
|
||||
p_dir = fix_path(p_dir);
|
||||
if (p_dir.is_rel_path())
|
||||
p_dir = get_current_dir().plus_file(p_dir);
|
||||
|
||||
p_dir = fix_path(p_dir);
|
||||
p_dir = p_dir.replace("/", "\\");
|
||||
|
||||
bool success;
|
||||
|
@ -207,6 +207,12 @@ Error FileAccessWindows::get_error() const {
|
||||
return last_error;
|
||||
}
|
||||
|
||||
void FileAccessWindows::flush() {
|
||||
|
||||
ERR_FAIL_COND(!f);
|
||||
fflush(f);
|
||||
}
|
||||
|
||||
void FileAccessWindows::store_8(uint8_t p_dest) {
|
||||
|
||||
ERR_FAIL_COND(!f);
|
||||
|
@ -64,6 +64,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
|
||||
|
@ -231,7 +231,6 @@ void Main::print_help(const char *p_binary) {
|
||||
}
|
||||
|
||||
Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_phase) {
|
||||
|
||||
RID_OwnerBase::init_rid();
|
||||
|
||||
OS::get_singleton()->initialize_core();
|
||||
@ -254,6 +253,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
||||
|
||||
register_core_settings(); //here globals is present
|
||||
|
||||
OS::get_singleton()->initialize_logger();
|
||||
|
||||
translation_server = memnew(TranslationServer);
|
||||
performance = memnew(Performance);
|
||||
globals->add_singleton(ProjectSettings::Singleton("Performance", performance));
|
||||
|
@ -146,6 +146,11 @@ Error FileAccessAndroid::get_error() const {
|
||||
return eof ? ERR_FILE_EOF : OK; //not sure what else it may happen
|
||||
}
|
||||
|
||||
void FileAccessAndroid::flush() {
|
||||
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
void FileAccessAndroid::store_8(uint8_t p_dest) {
|
||||
|
||||
ERR_FAIL();
|
||||
|
@ -63,6 +63,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
|
||||
|
@ -157,6 +157,9 @@ Error FileAccessJAndroid::get_error() const {
|
||||
return OK;
|
||||
}
|
||||
|
||||
void FileAccessJAndroid::flush() {
|
||||
}
|
||||
|
||||
void FileAccessJAndroid::store_8(uint8_t p_dest) {
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,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
|
||||
|
@ -47,6 +47,15 @@
|
||||
#include "file_access_jandroid.h"
|
||||
#endif
|
||||
|
||||
class AndroidLogger : public Logger {
|
||||
public:
|
||||
virtual void logv(const char *p_format, va_list p_list, bool p_err) {
|
||||
__android_log_vprint(p_err ? ANDROID_LOG_ERROR : ANDROID_LOG_INFO, "godot", p_format, p_list);
|
||||
}
|
||||
|
||||
virtual ~AndroidLogger() {}
|
||||
};
|
||||
|
||||
int OS_Android::get_video_driver_count() const {
|
||||
|
||||
return 1;
|
||||
@ -111,6 +120,13 @@ void OS_Android::initialize_core() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void OS_Android::initialize_logger() {
|
||||
Vector<Logger *> loggers;
|
||||
loggers.push_back(memnew(AndroidLogger));
|
||||
loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
|
||||
_set_logger(memnew(CompositeLogger(loggers)));
|
||||
}
|
||||
|
||||
void OS_Android::set_opengl_extensions(const char *p_gl_extensions) {
|
||||
|
||||
ERR_FAIL_COND(!p_gl_extensions);
|
||||
@ -162,23 +178,9 @@ void OS_Android::delete_main_loop() {
|
||||
}
|
||||
|
||||
void OS_Android::finalize() {
|
||||
|
||||
memdelete(input);
|
||||
}
|
||||
|
||||
void OS_Android::vprint(const char *p_format, va_list p_list, bool p_stderr) {
|
||||
|
||||
__android_log_vprint(p_stderr ? ANDROID_LOG_ERROR : ANDROID_LOG_INFO, "godot", p_format, p_list);
|
||||
}
|
||||
|
||||
void OS_Android::print(const char *p_format, ...) {
|
||||
|
||||
va_list argp;
|
||||
va_start(argp, p_format);
|
||||
__android_log_vprint(ANDROID_LOG_INFO, "godot", p_format, argp);
|
||||
va_end(argp);
|
||||
}
|
||||
|
||||
void OS_Android::alert(const String &p_alert, const String &p_title) {
|
||||
|
||||
//print("ALERT: %s\n", p_alert.utf8().get_data());
|
||||
@ -737,6 +739,8 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI
|
||||
set_keep_screen_on_func = p_set_keep_screen_on_func;
|
||||
alert_func = p_alert_func;
|
||||
use_reload_hooks = false;
|
||||
|
||||
_set_logger(memnew(AndroidLogger));
|
||||
}
|
||||
|
||||
OS_Android::~OS_Android() {
|
||||
|
@ -149,6 +149,7 @@ public:
|
||||
virtual int get_audio_driver_count() const;
|
||||
virtual const char *get_audio_driver_name(int p_driver) const;
|
||||
|
||||
virtual void initialize_logger();
|
||||
virtual void initialize_core();
|
||||
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||
|
||||
@ -161,8 +162,6 @@ public:
|
||||
|
||||
static OS *get_singleton();
|
||||
|
||||
virtual void vprint(const char *p_format, va_list p_list, bool p_stderr = false);
|
||||
virtual void print(const char *p_format, ...);
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||
|
||||
virtual void set_mouse_show(bool p_show);
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "core/os/dir_access.h"
|
||||
#include "core/os/file_access.h"
|
||||
#include "core/project_settings.h"
|
||||
#include "drivers/unix/syslog_logger.h"
|
||||
|
||||
#include "sem_iphone.h"
|
||||
|
||||
@ -98,6 +99,13 @@ void OSIPhone::initialize_core() {
|
||||
SemaphoreIphone::make_default();
|
||||
};
|
||||
|
||||
void OSIPhone::initialize_logger() {
|
||||
Vector<Logger *> loggers;
|
||||
loggers.push_back(memnew(SyslogLogger));
|
||||
loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
|
||||
_set_logger(memnew(CompositeLogger(loggers)));
|
||||
}
|
||||
|
||||
void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
|
||||
|
||||
supported_orientations = 0;
|
||||
@ -568,6 +576,8 @@ OSIPhone::OSIPhone(int width, int height) {
|
||||
vm.resizable = false;
|
||||
set_video_mode(vm);
|
||||
event_count = 0;
|
||||
|
||||
_set_logger(memnew(SyslogLogger));
|
||||
};
|
||||
|
||||
OSIPhone::~OSIPhone() {
|
||||
|
@ -90,6 +90,7 @@ private:
|
||||
|
||||
virtual VideoMode get_default_video_mode() const;
|
||||
|
||||
virtual void initialize_logger();
|
||||
virtual void initialize_core();
|
||||
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||
|
||||
|
@ -85,6 +85,10 @@ void OS_JavaScript::initialize_core() {
|
||||
FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix> >(FileAccess::ACCESS_RESOURCES);
|
||||
}
|
||||
|
||||
void OS_JavaScript::initialize_logger() {
|
||||
_set_logger(memnew(StdLogger));
|
||||
}
|
||||
|
||||
void OS_JavaScript::set_opengl_extensions(const char *p_gl_extensions) {
|
||||
|
||||
ERR_FAIL_COND(!p_gl_extensions);
|
||||
|
@ -92,6 +92,7 @@ public:
|
||||
virtual int get_audio_driver_count() const;
|
||||
virtual const char *get_audio_driver_name(int p_driver) const;
|
||||
|
||||
virtual void initialize_logger();
|
||||
virtual void initialize_core();
|
||||
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||
|
||||
@ -104,11 +105,6 @@ public:
|
||||
|
||||
//static OS* get_singleton();
|
||||
|
||||
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) {
|
||||
|
||||
OS::print_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
|
||||
}
|
||||
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||
|
||||
virtual void set_mouse_mode(MouseMode p_mode);
|
||||
|
@ -127,6 +127,7 @@ protected:
|
||||
virtual const char *get_video_driver_name(int p_driver) const;
|
||||
virtual VideoMode get_default_video_mode() const;
|
||||
|
||||
virtual void initialize_logger();
|
||||
virtual void initialize_core();
|
||||
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||
virtual void finalize();
|
||||
@ -141,8 +142,6 @@ public:
|
||||
|
||||
virtual String get_name();
|
||||
|
||||
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 alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||
|
||||
virtual void set_cursor_shape(CursorShape p_shape);
|
||||
|
@ -1145,43 +1145,67 @@ String OS_OSX::get_name() {
|
||||
return "OSX";
|
||||
}
|
||||
|
||||
void OS_OSX::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
|
||||
if (!_print_error_enabled)
|
||||
return;
|
||||
class OSXTerminalLogger : public StdLogger {
|
||||
public:
|
||||
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) {
|
||||
if (!should_log(true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *err_details;
|
||||
if (p_rationale && p_rationale[0])
|
||||
err_details = p_rationale;
|
||||
else
|
||||
err_details = p_code;
|
||||
const char *err_details;
|
||||
if (p_rationale && p_rationale[0])
|
||||
err_details = p_rationale;
|
||||
else
|
||||
err_details = p_code;
|
||||
|
||||
switch (p_type) {
|
||||
case ERR_ERROR:
|
||||
os_log_error(OS_LOG_DEFAULT, "ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
|
||||
print("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||
print("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_WARNING:
|
||||
os_log_info(OS_LOG_DEFAULT, "WARNING: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
|
||||
print("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||
print("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_SCRIPT:
|
||||
os_log_error(OS_LOG_DEFAULT, "SCRIPT ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
|
||||
print("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||
print("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_SHADER:
|
||||
os_log_error(OS_LOG_DEFAULT, "SHADER ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
|
||||
print("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||
print("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
switch (p_type) {
|
||||
case ERR_WARNING:
|
||||
os_log_info(OS_LOG_DEFAULT,
|
||||
"WARNING: %{public}s: %{public}s\nAt: %{public}s:%i.",
|
||||
p_function, err_details, p_file, p_line);
|
||||
logf_error("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function,
|
||||
err_details);
|
||||
logf_error("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_SCRIPT:
|
||||
os_log_error(OS_LOG_DEFAULT,
|
||||
"SCRIPT ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.",
|
||||
p_function, err_details, p_file, p_line);
|
||||
logf_error("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function,
|
||||
err_details);
|
||||
logf_error("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_SHADER:
|
||||
os_log_error(OS_LOG_DEFAULT,
|
||||
"SHADER ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.",
|
||||
p_function, err_details, p_file, p_line);
|
||||
logf_error("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function,
|
||||
err_details);
|
||||
logf_error("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_ERROR:
|
||||
default:
|
||||
os_log_error(OS_LOG_DEFAULT,
|
||||
"ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.",
|
||||
p_function, err_details, p_file, p_line);
|
||||
logf_error("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
|
||||
logf_error("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
OS_Unix::print_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
|
||||
|
||||
typedef UnixTerminalLogger OSXTerminalLogger;
|
||||
#endif
|
||||
|
||||
void OS_OSX::initialize_logger() {
|
||||
Vector<Logger *> loggers;
|
||||
loggers.push_back(memnew(OSXTerminalLogger));
|
||||
loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
|
||||
_set_logger(memnew(CompositeLogger(loggers)));
|
||||
}
|
||||
|
||||
void OS_OSX::alert(const String &p_alert, const String &p_title) {
|
||||
@ -2016,6 +2040,8 @@ OS_OSX::OS_OSX() {
|
||||
window_size = Vector2(1024, 600);
|
||||
zoomed = false;
|
||||
display_scale = 1.0;
|
||||
|
||||
_set_logger(memnew(OSXTerminalLogger));
|
||||
}
|
||||
|
||||
bool OS_OSX::_check_internal_feature_support(const String &p_feature) {
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "platform/windows/packet_peer_udp_winsock.h"
|
||||
#include "platform/windows/stream_peer_winsock.h"
|
||||
#include "platform/windows/tcp_server_winsock.h"
|
||||
#include "platform/windows/windows_terminal_logger.h"
|
||||
#include "project_settings.h"
|
||||
#include "servers/audio_server.h"
|
||||
#include "servers/visual/visual_server_raster.h"
|
||||
@ -182,6 +183,13 @@ void OSUWP::initialize_core() {
|
||||
cursor_shape = CURSOR_ARROW;
|
||||
}
|
||||
|
||||
void OSUWP::initialize_logger() {
|
||||
Vector<Logger *> loggers;
|
||||
loggers.push_back(memnew(WindowsTerminalLogger));
|
||||
loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
|
||||
_set_logger(memnew(CompositeLogger(loggers)));
|
||||
}
|
||||
|
||||
bool OSUWP::can_draw() const {
|
||||
|
||||
return !minimized;
|
||||
@ -371,32 +379,6 @@ void OSUWP::finalize() {
|
||||
void OSUWP::finalize_core() {
|
||||
}
|
||||
|
||||
void OSUWP::vprint(const char *p_format, va_list p_list, bool p_stderr) {
|
||||
|
||||
char buf[16384 + 1];
|
||||
int len = vsnprintf(buf, 16384, p_format, p_list);
|
||||
if (len <= 0)
|
||||
return;
|
||||
buf[len] = 0;
|
||||
|
||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, buf, len, NULL, 0);
|
||||
if (wlen < 0)
|
||||
return;
|
||||
|
||||
wchar_t *wbuf = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
|
||||
MultiByteToWideChar(CP_UTF8, 0, buf, len, wbuf, wlen);
|
||||
wbuf[wlen] = 0;
|
||||
|
||||
if (p_stderr)
|
||||
fwprintf(stderr, L"%s", wbuf);
|
||||
else
|
||||
wprintf(L"%s", wbuf);
|
||||
|
||||
free(wbuf);
|
||||
|
||||
fflush(stdout);
|
||||
};
|
||||
|
||||
void OSUWP::alert(const String &p_alert, const String &p_title) {
|
||||
|
||||
Platform::String ^ alert = ref new Platform::String(p_alert.c_str());
|
||||
@ -520,30 +502,6 @@ OS::VideoMode OSUWP::get_video_mode(int p_screen) const {
|
||||
void OSUWP::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
|
||||
}
|
||||
|
||||
void OSUWP::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_details;
|
||||
if (p_rationale && p_rationale[0])
|
||||
err_details = p_rationale;
|
||||
else
|
||||
err_details = p_code;
|
||||
|
||||
switch (p_type) {
|
||||
case ERR_ERROR:
|
||||
print("ERROR: %s: %s\n", p_function, err_details);
|
||||
print(" At: %s:%i\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_WARNING:
|
||||
print("WARNING: %s: %s\n", p_function, err_details);
|
||||
print(" At: %s:%i\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_SCRIPT:
|
||||
print("SCRIPT ERROR: %s: %s\n", p_function, err_details);
|
||||
print(" At: %s:%i\n", p_file, p_line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
String OSUWP::get_name() {
|
||||
|
||||
return "UWP";
|
||||
@ -890,6 +848,8 @@ OSUWP::OSUWP() {
|
||||
mouse_mode_changed = CreateEvent(NULL, TRUE, FALSE, L"os_mouse_mode_changed");
|
||||
|
||||
AudioDriverManager::add_driver(&audio_driver);
|
||||
|
||||
_set_logger(memnew(WindowsTerminalLogger));
|
||||
}
|
||||
|
||||
OSUWP::~OSUWP() {
|
||||
|
@ -163,6 +163,7 @@ protected:
|
||||
virtual int get_audio_driver_count() const;
|
||||
virtual const char *get_audio_driver_name(int p_driver) const;
|
||||
|
||||
virtual void initialize_logger();
|
||||
virtual void initialize_core();
|
||||
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||
|
||||
@ -180,9 +181,6 @@ public:
|
||||
// Event to send to the app wrapper
|
||||
HANDLE mouse_mode_changed;
|
||||
|
||||
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);
|
||||
|
||||
virtual void vprint(const char *p_format, va_list p_list, bool p_stderr = false);
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||
String get_stdin_string(bool p_block);
|
||||
|
||||
|
@ -19,6 +19,7 @@ common_win = [
|
||||
"stream_peer_winsock.cpp",
|
||||
"joypad.cpp",
|
||||
"power_windows.cpp",
|
||||
"windows_terminal_logger.cpp"
|
||||
]
|
||||
|
||||
restarget = "godot_res" + env["OBJSUFFIX"]
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "servers/visual/visual_server_wrap_mt.h"
|
||||
#include "stream_peer_winsock.h"
|
||||
#include "tcp_server_winsock.h"
|
||||
#include "windows_terminal_logger.h"
|
||||
|
||||
#include <process.h>
|
||||
#include <regstr.h>
|
||||
@ -205,6 +206,13 @@ void OS_Windows::initialize_core() {
|
||||
cursor_shape = CURSOR_ARROW;
|
||||
}
|
||||
|
||||
void OS_Windows::initialize_logger() {
|
||||
Vector<Logger *> loggers;
|
||||
loggers.push_back(memnew(WindowsTerminalLogger));
|
||||
loggers.push_back(memnew(RotatedFileLogger("user://logs/log.txt")));
|
||||
_set_logger(memnew(CompositeLogger(loggers)));
|
||||
}
|
||||
|
||||
bool OS_Windows::can_draw() const {
|
||||
|
||||
return !minimized;
|
||||
@ -1231,38 +1239,6 @@ void OS_Windows::finalize_core() {
|
||||
StreamPeerWinsock::cleanup();
|
||||
}
|
||||
|
||||
void OS_Windows::vprint(const char *p_format, va_list p_list, bool p_stderr) {
|
||||
|
||||
const unsigned int BUFFER_SIZE = 16384;
|
||||
char buf[BUFFER_SIZE + 1]; // +1 for the terminating character
|
||||
int len = vsnprintf(buf, BUFFER_SIZE, p_format, p_list);
|
||||
if (len <= 0)
|
||||
return;
|
||||
if (len >= BUFFER_SIZE)
|
||||
len = BUFFER_SIZE; // Output is too big, will be truncated
|
||||
buf[len] = 0;
|
||||
|
||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, buf, len, NULL, 0);
|
||||
if (wlen < 0)
|
||||
return;
|
||||
|
||||
wchar_t *wbuf = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
|
||||
MultiByteToWideChar(CP_UTF8, 0, buf, len, wbuf, wlen);
|
||||
wbuf[wlen] = 0;
|
||||
|
||||
if (p_stderr)
|
||||
fwprintf(stderr, L"%ls", wbuf);
|
||||
else
|
||||
wprintf(L"%ls", wbuf);
|
||||
|
||||
#ifdef STDOUT_FILE
|
||||
//vwfprintf(stdo,p_format,p_list);
|
||||
#endif
|
||||
free(wbuf);
|
||||
|
||||
fflush(stdout);
|
||||
};
|
||||
|
||||
void OS_Windows::alert(const String &p_alert, const String &p_title) {
|
||||
|
||||
if (!is_no_window_mode_enabled())
|
||||
@ -1676,107 +1652,6 @@ void OS_Windows::request_attention() {
|
||||
FlashWindowEx(&info);
|
||||
}
|
||||
|
||||
void OS_Windows::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
|
||||
|
||||
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (!hCon || hCon == INVALID_HANDLE_VALUE) {
|
||||
|
||||
const char *err_details;
|
||||
if (p_rationale && p_rationale[0])
|
||||
err_details = p_rationale;
|
||||
else
|
||||
err_details = p_code;
|
||||
|
||||
switch (p_type) {
|
||||
case ERR_ERROR:
|
||||
print("ERROR: %s: %s\n", p_function, err_details);
|
||||
print(" At: %s:%i\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_WARNING:
|
||||
print("WARNING: %s: %s\n", p_function, err_details);
|
||||
print(" At: %s:%i\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_SCRIPT:
|
||||
print("SCRIPT ERROR: %s: %s\n", p_function, err_details);
|
||||
print(" At: %s:%i\n", p_file, p_line);
|
||||
break;
|
||||
case ERR_SHADER:
|
||||
print("SHADER ERROR: %s: %s\n", p_function, err_details);
|
||||
print(" At: %s:%i\n", p_file, p_line);
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO sbi; //original
|
||||
GetConsoleScreenBufferInfo(hCon, &sbi);
|
||||
|
||||
WORD current_fg = sbi.wAttributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
|
||||
WORD current_bg = sbi.wAttributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY);
|
||||
|
||||
uint32_t basecol = 0;
|
||||
switch (p_type) {
|
||||
case ERR_ERROR: basecol = FOREGROUND_RED; break;
|
||||
case ERR_WARNING: basecol = FOREGROUND_RED | FOREGROUND_GREEN; break;
|
||||
case ERR_SCRIPT: basecol = FOREGROUND_RED | FOREGROUND_BLUE; break;
|
||||
case ERR_SHADER: basecol = FOREGROUND_GREEN | FOREGROUND_BLUE; break;
|
||||
}
|
||||
|
||||
basecol |= current_bg;
|
||||
|
||||
if (p_rationale && p_rationale[0]) {
|
||||
|
||||
SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
|
||||
switch (p_type) {
|
||||
case ERR_ERROR: print("ERROR: "); break;
|
||||
case ERR_WARNING: print("WARNING: "); break;
|
||||
case ERR_SCRIPT: print("SCRIPT ERROR: "); break;
|
||||
case ERR_SHADER: print("SHADER ERROR: "); break;
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
|
||||
print("%s\n", p_rationale);
|
||||
|
||||
SetConsoleTextAttribute(hCon, basecol);
|
||||
switch (p_type) {
|
||||
case ERR_ERROR: print(" At: "); break;
|
||||
case ERR_WARNING: print(" At: "); break;
|
||||
case ERR_SCRIPT: print(" At: "); break;
|
||||
case ERR_SHADER: print(" At: "); break;
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hCon, current_fg | current_bg);
|
||||
print("%s:%i\n", p_file, p_line);
|
||||
|
||||
} else {
|
||||
|
||||
SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
|
||||
switch (p_type) {
|
||||
case ERR_ERROR: print("ERROR: %s: ", p_function); break;
|
||||
case ERR_WARNING: print("WARNING: %s: ", p_function); break;
|
||||
case ERR_SCRIPT: print("SCRIPT ERROR: %s: ", p_function); break;
|
||||
case ERR_SHADER: print("SCRIPT ERROR: %s: ", p_function); break;
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
|
||||
print("%s\n", p_code);
|
||||
|
||||
SetConsoleTextAttribute(hCon, basecol);
|
||||
switch (p_type) {
|
||||
case ERR_ERROR: print(" At: "); break;
|
||||
case ERR_WARNING: print(" At: "); break;
|
||||
case ERR_SCRIPT: print(" At: "); break;
|
||||
case ERR_SHADER: print(" At: "); break;
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hCon, current_fg | current_bg);
|
||||
print("%s:%i\n", p_file, p_line);
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hCon, sbi.wAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
String OS_Windows::get_name() {
|
||||
|
||||
return "Windows";
|
||||
@ -2429,6 +2304,8 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
|
||||
#ifdef XAUDIO2_ENABLED
|
||||
AudioDriverManager::add_driver(&driver_xaudio2);
|
||||
#endif
|
||||
|
||||
_set_logger(memnew(WindowsTerminalLogger));
|
||||
}
|
||||
|
||||
OS_Windows::~OS_Windows() {
|
||||
|
@ -152,6 +152,7 @@ protected:
|
||||
virtual int get_audio_driver_count() const;
|
||||
virtual const char *get_audio_driver_name(int p_driver) const;
|
||||
|
||||
virtual void initialize_logger();
|
||||
virtual void initialize_core();
|
||||
virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
|
||||
|
||||
@ -180,9 +181,6 @@ protected:
|
||||
public:
|
||||
LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
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);
|
||||
|
||||
virtual void vprint(const char *p_format, va_list p_list, bool p_stderr = false);
|
||||
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
|
||||
String get_stdin_string(bool p_block);
|
||||
|
||||
|
157
platform/windows/windows_terminal_logger.cpp
Normal file
157
platform/windows/windows_terminal_logger.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
/*************************************************************************/
|
||||
/* windows_terminal_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 "windows_terminal_logger.h"
|
||||
|
||||
#ifdef WINDOWS_ENABLED
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
void WindowsTerminalLogger::logv(const char *p_format, va_list p_list, bool p_err) {
|
||||
if (!should_log(p_err)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned int BUFFER_SIZE = 16384;
|
||||
char buf[BUFFER_SIZE + 1]; // +1 for the terminating character
|
||||
int len = vsnprintf(buf, BUFFER_SIZE, p_format, p_list);
|
||||
if (len <= 0)
|
||||
return;
|
||||
if (len >= BUFFER_SIZE)
|
||||
len = BUFFER_SIZE; // Output is too big, will be truncated
|
||||
buf[len] = 0;
|
||||
|
||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, buf, len, NULL, 0);
|
||||
if (wlen < 0)
|
||||
return;
|
||||
|
||||
wchar_t *wbuf = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
|
||||
MultiByteToWideChar(CP_UTF8, 0, buf, len, wbuf, wlen);
|
||||
wbuf[wlen] = 0;
|
||||
|
||||
if (p_err)
|
||||
fwprintf(stderr, L"%ls", wbuf);
|
||||
else
|
||||
wprintf(L"%ls", wbuf);
|
||||
|
||||
free(wbuf);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
|
||||
void WindowsTerminalLogger::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;
|
||||
}
|
||||
|
||||
#ifndef UWP_ENABLED
|
||||
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (!hCon || hCon == INVALID_HANDLE_VALUE) {
|
||||
#endif
|
||||
StdLogger::log_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
|
||||
#ifndef UWP_ENABLED
|
||||
} else {
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO sbi; //original
|
||||
GetConsoleScreenBufferInfo(hCon, &sbi);
|
||||
|
||||
WORD current_fg = sbi.wAttributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
|
||||
WORD current_bg = sbi.wAttributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY);
|
||||
|
||||
uint32_t basecol = 0;
|
||||
switch (p_type) {
|
||||
case ERR_ERROR: basecol = FOREGROUND_RED; break;
|
||||
case ERR_WARNING: basecol = FOREGROUND_RED | FOREGROUND_GREEN; break;
|
||||
case ERR_SCRIPT: basecol = FOREGROUND_RED | FOREGROUND_BLUE; break;
|
||||
case ERR_SHADER: basecol = FOREGROUND_GREEN | FOREGROUND_BLUE; break;
|
||||
}
|
||||
|
||||
basecol |= current_bg;
|
||||
|
||||
if (p_rationale && p_rationale[0]) {
|
||||
|
||||
SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
|
||||
switch (p_type) {
|
||||
case ERR_ERROR: logf("ERROR: "); break;
|
||||
case ERR_WARNING: logf("WARNING: "); break;
|
||||
case ERR_SCRIPT: logf("SCRIPT ERROR: "); break;
|
||||
case ERR_SHADER: logf("SHADER ERROR: "); break;
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
|
||||
logf("%s\n", p_rationale);
|
||||
|
||||
SetConsoleTextAttribute(hCon, basecol);
|
||||
switch (p_type) {
|
||||
case ERR_ERROR: logf(" At: "); break;
|
||||
case ERR_WARNING: logf(" At: "); break;
|
||||
case ERR_SCRIPT: logf(" At: "); break;
|
||||
case ERR_SHADER: logf(" At: "); break;
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hCon, current_fg | current_bg);
|
||||
logf("%s:%i\n", p_file, p_line);
|
||||
|
||||
} else {
|
||||
|
||||
SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
|
||||
switch (p_type) {
|
||||
case ERR_ERROR: logf("ERROR: %s: ", p_function); break;
|
||||
case ERR_WARNING: logf("WARNING: %s: ", p_function); break;
|
||||
case ERR_SCRIPT: logf("SCRIPT ERROR: %s: ", p_function); break;
|
||||
case ERR_SHADER: logf("SCRIPT ERROR: %s: ", p_function); break;
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY);
|
||||
logf("%s\n", p_code);
|
||||
|
||||
SetConsoleTextAttribute(hCon, basecol);
|
||||
switch (p_type) {
|
||||
case ERR_ERROR: logf(" At: "); break;
|
||||
case ERR_WARNING: logf(" At: "); break;
|
||||
case ERR_SCRIPT: logf(" At: "); break;
|
||||
case ERR_SHADER: logf(" At: "); break;
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hCon, current_fg | current_bg);
|
||||
logf("%s:%i\n", p_file, p_line);
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hCon, sbi.wAttributes);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
WindowsTerminalLogger::~WindowsTerminalLogger() {}
|
||||
|
||||
#endif
|
47
platform/windows/windows_terminal_logger.h
Normal file
47
platform/windows/windows_terminal_logger.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*************************************************************************/
|
||||
/* windows_terminal_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 WINDOWS_TERMINAL_LOGGER_H
|
||||
#define WINDOWS_TERMINAL_LOGGER_H
|
||||
|
||||
#ifdef WINDOWS_ENABLED
|
||||
|
||||
#include "io/logger.h"
|
||||
|
||||
class WindowsTerminalLogger : public StdLogger {
|
||||
public:
|
||||
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 ~WindowsTerminalLogger();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user