mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-26 12:30:05 +00:00
Functional spdlogging implementation with fmtlib
This commit is contained in:
parent
fee58ce458
commit
f9d6f7bc32
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -28,3 +28,6 @@
|
|||||||
[submodule "spdlog"]
|
[submodule "spdlog"]
|
||||||
path = externals/spdlog
|
path = externals/spdlog
|
||||||
url = https://github.com/gabime/spdlog.git
|
url = https://github.com/gabime/spdlog.git
|
||||||
|
[submodule "fmt"]
|
||||||
|
path = externals/fmt
|
||||||
|
url = https://github.com/fmtlib/fmt
|
||||||
|
1
externals/CMakeLists.txt
vendored
1
externals/CMakeLists.txt
vendored
@ -51,4 +51,5 @@ endif()
|
|||||||
|
|
||||||
# Spdlog
|
# Spdlog
|
||||||
add_library(spdlog INTERFACE)
|
add_library(spdlog INTERFACE)
|
||||||
|
target_compile_definitions(spdlog INTERFACE -DSPDLOG_FMT_EXTERNAL=1)
|
||||||
target_include_directories(spdlog INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/spdlog/include)
|
target_include_directories(spdlog INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/spdlog/include)
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# Enable modules to include each other's files
|
# Enable modules to include each other's files
|
||||||
include_directories(.)
|
include_directories(.)
|
||||||
|
# Include fmtlib so it can be used across the application for logging
|
||||||
|
include_directories(../externals/fmt)
|
||||||
|
|
||||||
add_subdirectory(common)
|
add_subdirectory(common)
|
||||||
add_subdirectory(core)
|
add_subdirectory(core)
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include "game_list_p.h"
|
#include "game_list_p.h"
|
||||||
#include "ui_settings.h"
|
#include "ui_settings.h"
|
||||||
|
|
||||||
REGISTER_LOGGER("Class Name");
|
REGISTER_LOGGER("Game List");
|
||||||
|
|
||||||
GameList::SearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist) {
|
GameList::SearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist) {
|
||||||
this->gamelist = gamelist;
|
this->gamelist = gamelist;
|
||||||
@ -319,7 +319,7 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
|
|||||||
void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
|
void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
|
||||||
if (!FileUtil::Exists(dir_path.toStdString()) ||
|
if (!FileUtil::Exists(dir_path.toStdString()) ||
|
||||||
!FileUtil::IsDirectory(dir_path.toStdString())) {
|
!FileUtil::IsDirectory(dir_path.toStdString())) {
|
||||||
LOG_ERROR(Frontend, "Could not find game list folder at %s", dir_path.toLocal8Bit().data());
|
SPDLOG_ERROR("Could not find game list folder at {}", dir_path.toLocal8Bit().data());
|
||||||
search_field->setFilterResult(0, 0);
|
search_field->setFilterResult(0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -369,7 +369,7 @@ static bool HasSupportedFileExtension(const std::string& file_name) {
|
|||||||
|
|
||||||
void GameList::RefreshGameDirectory() {
|
void GameList::RefreshGameDirectory() {
|
||||||
if (!UISettings::values.gamedir.isEmpty() && current_worker != nullptr) {
|
if (!UISettings::values.gamedir.isEmpty() && current_worker != nullptr) {
|
||||||
LOG_INFO(Frontend, "Change detected in the games directory. Reloading game list.");
|
SPDLOG_INFO("Change detected in the games directory. Reloading game list.");
|
||||||
search_field->clear();
|
search_field->clear();
|
||||||
PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
|
PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
|
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
REGISTER_LOGGER("Main");
|
||||||
|
|
||||||
GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
|
GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
|
||||||
Pica::g_debug_context = Pica::DebugContext::Construct();
|
Pica::g_debug_context = Pica::DebugContext::Construct();
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
@ -321,14 +323,13 @@ bool GMainWindow::LoadROM(const QString& filename) {
|
|||||||
if (result != Core::System::ResultStatus::Success) {
|
if (result != Core::System::ResultStatus::Success) {
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case Core::System::ResultStatus::ErrorGetLoader:
|
case Core::System::ResultStatus::ErrorGetLoader:
|
||||||
LOG_CRITICAL(Frontend, "Failed to obtain loader for %s!",
|
SPDLOG_CRITICAL("Failed to obtain loader for {}!", filename.toStdString());
|
||||||
filename.toStdString().c_str());
|
|
||||||
QMessageBox::critical(this, tr("Error while loading ROM!"),
|
QMessageBox::critical(this, tr("Error while loading ROM!"),
|
||||||
tr("The ROM format is not supported."));
|
tr("The ROM format is not supported."));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Core::System::ResultStatus::ErrorSystemMode:
|
case Core::System::ResultStatus::ErrorSystemMode:
|
||||||
LOG_CRITICAL(Frontend, "Failed to load ROM!");
|
SPDLOG_CRITICAL("Failed to load ROM!");
|
||||||
QMessageBox::critical(this, tr("Error while loading ROM!"),
|
QMessageBox::critical(this, tr("Error while loading ROM!"),
|
||||||
tr("Could not determine the system mode."));
|
tr("Could not determine the system mode."));
|
||||||
break;
|
break;
|
||||||
@ -377,7 +378,7 @@ bool GMainWindow::LoadROM(const QString& filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::BootGame(const QString& filename) {
|
void GMainWindow::BootGame(const QString& filename) {
|
||||||
LOG_INFO(Frontend, "Citra starting...");
|
SPDLOG_INFO("Citra starting...");
|
||||||
StoreRecentFile(filename); // Put the filename on top of the list
|
StoreRecentFile(filename); // Put the filename on top of the list
|
||||||
|
|
||||||
if (!LoadROM(filename))
|
if (!LoadROM(filename))
|
||||||
@ -503,7 +504,7 @@ void GMainWindow::OnGameListOpenSaveFolder(u64 program_id) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO(Frontend, "Opening save data path for program_id=%" PRIu64, program_id);
|
SPDLOG_INFO("Opening save data path for program_id={0:#x}", program_id);
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(qpath));
|
QDesktopServices::openUrl(QUrl::fromLocalFile(qpath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,8 +99,7 @@ endif()
|
|||||||
create_directory_groups(${SRCS} ${HEADERS})
|
create_directory_groups(${SRCS} ${HEADERS})
|
||||||
|
|
||||||
add_library(common STATIC ${SRCS} ${HEADERS})
|
add_library(common STATIC ${SRCS} ${HEADERS})
|
||||||
|
target_link_libraries(common PUBLIC Boost::boost fmt microprofile spdlog)
|
||||||
target_link_libraries(common PUBLIC Boost::boost microprofile spdlog)
|
|
||||||
|
|
||||||
if (ARCHITECTURE_x86_64)
|
if (ARCHITECTURE_x86_64)
|
||||||
target_link_libraries(common PRIVATE xbyak)
|
target_link_libraries(common PRIVATE xbyak)
|
||||||
|
@ -1,8 +1,31 @@
|
|||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/backend_spdlog.h"
|
#include "common/logging/backend_spdlog.h"
|
||||||
#include "common/logging/formatter.h"
|
#include "common/logging/formatter.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
|
|
||||||
|
static spdlog::level::level_enum GetLevel(Log::Level log_level) {
|
||||||
|
switch (log_level) {
|
||||||
|
case Log::Level::Trace:
|
||||||
|
return spdlog::level::trace;
|
||||||
|
case Log::Level::Debug:
|
||||||
|
return spdlog::level::debug;
|
||||||
|
case Log::Level::Info:
|
||||||
|
return spdlog::level::info;
|
||||||
|
case Log::Level::Warning:
|
||||||
|
return spdlog::level::warn;
|
||||||
|
case Log::Level::Error:
|
||||||
|
return spdlog::level::err;
|
||||||
|
case Log::Level::Critical:
|
||||||
|
return spdlog::level::critical;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return spdlog::level::off;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Log {
|
namespace Log {
|
||||||
|
|
||||||
SpdLogBackend& SpdLogBackend::instance() {
|
SpdLogBackend& SpdLogBackend::instance() {
|
||||||
@ -31,54 +54,18 @@ SpdLogBackend::~SpdLogBackend() {
|
|||||||
spdlog::drop_all();
|
spdlog::drop_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::shared_ptr<spdlog::logger> SpdLogBackend::GetLogger(u32 logger) const {
|
const std::shared_ptr<spdlog::logger>& SpdLogBackend::GetLogger(u32 logger) const {
|
||||||
return loggers[logger];
|
return loggers[logger];
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 SpdLogBackend::RegisterLogger(const char* class_name) {
|
u32 SpdLogBackend::RegisterLogger(const char* class_name) {
|
||||||
loggers.push_back(std::make_shared<spdlog::logger>(class_name, sinks.begin(), sinks.end()));
|
loggers.push_back(spdlog::create(class_name, sinks.begin(), sinks.end()));
|
||||||
return loggers.size() - 1;
|
return loggers.size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
spdlog::level_t GetLevel(Level log_level) {
|
void SpdLogImpl(u32 logger, Level log_level, const char* format, fmt::ArgList& args) {
|
||||||
switch (log_level) {
|
|
||||||
case Level::Trace:
|
|
||||||
return spdlog::level::trace;
|
|
||||||
case Level::Debug:
|
|
||||||
return spdlog::level::debug;
|
|
||||||
case Level::Info:
|
|
||||||
return spdlog::level::info;
|
|
||||||
case Level::Warning:
|
|
||||||
return spdlog::level::warn;
|
|
||||||
case Level::Error:
|
|
||||||
return spdlog::level::err;
|
|
||||||
case Level::Critical:
|
|
||||||
return spdlog::level::critical;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return spdlog::level::off;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Arg1, typename... Args>
|
|
||||||
void SpdLogMessage(u32 logger, Level log_level, const char* filename, unsigned int line_nr,
|
|
||||||
const char* function, const char* format, const Arg1& arg, const Args&... args) {
|
|
||||||
auto log = SpdLogBackend::instance().GetLogger(logger);
|
auto log = SpdLogBackend::instance().GetLogger(logger);
|
||||||
fmt::MemoryWriter formatting_buffer;
|
log->log(GetLevel(log_level), format, args);
|
||||||
formatting_buffer << Common::TrimSourcePath(filename) << ':' << function << ':' << line_nr
|
|
||||||
<< ": " << format;
|
|
||||||
log->log(GetLevel(log_level), formatting_buffer.c_str(), arg, args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void SpdLogMessage(u32 logger, Level log_level, const char* filename, unsigned int line_nr,
|
|
||||||
const char* function, const T& msg) {
|
|
||||||
auto log = SpdLogBackend::instance().GetLogger(logger);
|
|
||||||
fmt::MemoryWriter formatting_buffer;
|
|
||||||
formatting_buffer << Common::TrimSourcePath(filename) << ':' << function << ':' << line_nr
|
|
||||||
<< ": " << msg;
|
|
||||||
log->log(GetLevel(log_level), formatting_buffer.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 RegisterLogger(const char* class_name) {
|
u32 RegisterLogger(const char* class_name) {
|
||||||
|
@ -10,11 +10,11 @@ public:
|
|||||||
static SpdLogBackend& instance();
|
static SpdLogBackend& instance();
|
||||||
|
|
||||||
SpdLogBackend(SpdLogBackend const&) = delete;
|
SpdLogBackend(SpdLogBackend const&) = delete;
|
||||||
void operator=(SpdLogBackend const&) = delete;
|
SpdLogBackend& operator=(SpdLogBackend const&) = delete;
|
||||||
|
|
||||||
u32 RegisterLogger(const char* class_name);
|
u32 RegisterLogger(const char* class_name);
|
||||||
|
|
||||||
const std::shared_ptr<spdlog::logger> GetLogger(u32 logger) const;
|
const std::shared_ptr<spdlog::logger>& GetLogger(u32 logger) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SpdLogBackend();
|
SpdLogBackend();
|
||||||
|
@ -3,11 +3,7 @@
|
|||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/formatter.h"
|
#include "common/logging/formatter.h"
|
||||||
|
|
||||||
namespace Log {
|
static const char* GetLevelName(spdlog::level_t log_level) {
|
||||||
|
|
||||||
Formatter::Formatter() {}
|
|
||||||
|
|
||||||
const char* GetLevelName(spdlog::level_t log_level) {
|
|
||||||
switch (log_level) {
|
switch (log_level) {
|
||||||
case spdlog::level::trace:
|
case spdlog::level::trace:
|
||||||
return "Trace";
|
return "Trace";
|
||||||
@ -16,7 +12,7 @@ const char* GetLevelName(spdlog::level_t log_level) {
|
|||||||
case spdlog::level::info:
|
case spdlog::level::info:
|
||||||
return "Info";
|
return "Info";
|
||||||
case spdlog::level::warn:
|
case spdlog::level::warn:
|
||||||
return "Warn";
|
return "Warning";
|
||||||
case spdlog::level::err:
|
case spdlog::level::err:
|
||||||
return "Error";
|
return "Error";
|
||||||
case spdlog::level::critical:
|
case spdlog::level::critical:
|
||||||
@ -27,6 +23,8 @@ const char* GetLevelName(spdlog::level_t log_level) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Log {
|
||||||
|
|
||||||
void Formatter::format(spdlog::details::log_msg& msg) {
|
void Formatter::format(spdlog::details::log_msg& msg) {
|
||||||
using std::chrono::steady_clock;
|
using std::chrono::steady_clock;
|
||||||
using std::chrono::duration_cast;
|
using std::chrono::duration_cast;
|
||||||
|
@ -5,7 +5,7 @@ namespace Log {
|
|||||||
class Formatter : public spdlog::formatter {
|
class Formatter : public spdlog::formatter {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Formatter();
|
explicit Formatter() = default;
|
||||||
Formatter(const Formatter&) = delete;
|
Formatter(const Formatter&) = delete;
|
||||||
Formatter& operator=(const Formatter&) = delete;
|
Formatter& operator=(const Formatter&) = delete;
|
||||||
void format(spdlog::details::log_msg& msg) override;
|
void format(spdlog::details::log_msg& msg) override;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Log {
|
namespace Log {
|
||||||
@ -106,12 +107,19 @@ void LogMessage(Class log_class, Level log_level, const char* filename, unsigned
|
|||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
|
||||||
|
void SpdLogImpl(u32 logger, Level log_level, const char* format, fmt::ArgList& args);
|
||||||
|
|
||||||
template <typename Arg1, typename... Args>
|
template <typename Arg1, typename... Args>
|
||||||
void SpdLogMessage(u32 logger, Level log_level, const char* filename, unsigned int line_nr,
|
void SpdLogMessage(u32 logger, Level log_level, const char* filename, unsigned int line_nr,
|
||||||
const char* function, const char* format, const Arg1& arg, const Args&... args);
|
const char* function, const Arg1& format, const Args&... args) {
|
||||||
template <typename T>
|
typedef fmt::internal::ArgArray<sizeof...(Args)> ArgArray;
|
||||||
void SpdLogMessage(u32 logger, Level log_level, const char* filename, unsigned int line_nr,
|
typename ArgArray::Type array{ArgArray::template make<fmt::BasicFormatter<char>>(args)...};
|
||||||
const char* function, const T& msg);
|
fmt::MemoryWriter formatting_buffer;
|
||||||
|
formatting_buffer << Common::TrimSourcePath(filename) << ':' << function << ':' << line_nr
|
||||||
|
<< ": " << format;
|
||||||
|
SpdLogImpl(logger, log_level, formatting_buffer.c_str(),
|
||||||
|
fmt::ArgList(fmt::internal::make_type(args...), array));
|
||||||
|
}
|
||||||
|
|
||||||
u32 RegisterLogger(const char* class_name);
|
u32 RegisterLogger(const char* class_name);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user