From 901e1d3b0c056551fbb9a164e24143907c894ee4 Mon Sep 17 00:00:00 2001 From: Gin <> Date: Mon, 19 Jan 2026 20:48:48 -0800 Subject: [PATCH 1/3] create global UI-free logger --- Common/Cpp/Logging/FileLogger.h | 2 +- Common/Cpp/Logging/GlobalLogger.cpp | 32 +++++++++++++++++++ Common/Cpp/Logging/GlobalLogger.h | 32 +++++++++++++++++++ .../Logging/FileWindowLogger.cpp | 29 ++++------------- .../Logging/FileWindowLogger.h | 9 ++++-- .../Source/CommonFramework/Logging/Logger.cpp | 1 + .../Source/CommonFramework/Logging/Logger.h | 7 +--- .../Source/CommonFramework/Main.cpp | 4 +++ .../CommonFramework/Windows/MainWindow.cpp | 2 +- SerialPrograms/cmake/SourceFiles.cmake | 2 ++ 10 files changed, 87 insertions(+), 33 deletions(-) create mode 100644 Common/Cpp/Logging/GlobalLogger.cpp create mode 100644 Common/Cpp/Logging/GlobalLogger.h diff --git a/Common/Cpp/Logging/FileLogger.h b/Common/Cpp/Logging/FileLogger.h index 9f08fe7d79..33d123b1b6 100644 --- a/Common/Cpp/Logging/FileLogger.h +++ b/Common/Cpp/Logging/FileLogger.h @@ -31,7 +31,7 @@ struct FileLoggerConfig{ }; -// A Qt-free file logger that: +// A file logger that: // 1. Writes log messages to a file asynchronously via a background thread // 2. Supports log rotation when the file exceeds a configured size // 3. Notifies registered listeners when a log message is written (for UI integration) diff --git a/Common/Cpp/Logging/GlobalLogger.cpp b/Common/Cpp/Logging/GlobalLogger.cpp new file mode 100644 index 0000000000..b27f7b2ffe --- /dev/null +++ b/Common/Cpp/Logging/GlobalLogger.cpp @@ -0,0 +1,32 @@ +/* Global Logger + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include "GlobalLogger.h" + +namespace PokemonAutomation{ + + +static FileLoggerConfig _global_logger_config; + +void initialize_global_logger(FileLoggerConfig config){ + _global_logger_config = std::move(config); + // auto& logger = global_logger_raw(); + // logger.log("Initialized logger with path " + config.file_path); +} + +Logger& global_logger_raw(){ + auto get_config = [&](){ + if (_global_logger_config.file_path.size() == 0){ + _global_logger_config.file_path = "."; + } + return _global_logger_config; + }; + static FileLogger logger(get_config()); + return logger; +} + + +} diff --git a/Common/Cpp/Logging/GlobalLogger.h b/Common/Cpp/Logging/GlobalLogger.h new file mode 100644 index 0000000000..d7072db575 --- /dev/null +++ b/Common/Cpp/Logging/GlobalLogger.h @@ -0,0 +1,32 @@ +/* Global Logger + * + * From: https://github.com/PokemonAutomation/ + * + * Provides a global file logger instance for application-wide logging. + * This is a Qt-free logger that can be used before Qt is initialized. + */ + +#ifndef PokemonAutomation_Logging_GlobalLogger_H +#define PokemonAutomation_Logging_GlobalLogger_H + +#include "FileLogger.h" + +namespace PokemonAutomation{ + + +// Call this function at very beginning of the main function to initialize the global file logger. +// Call `global_logger_raw()` to retrieve the global file logger afterwards. +// If not called, a default logger with default file path of "." will be created. +void initialize_global_logger(FileLoggerConfig config); + + +// Return a global raw `FileLogger`. `FileLogger` is defined in FileLogger.h. +// "raw" here means the logger does not add any timestamp or tags to the incoming log lines. +// Suggest calling `initialize_global_logger()` at very beginning of the main function to +// initialize the logger first. Otherwise a default logger with default file path of "." +// will be created. +Logger& global_logger_raw(); + + +} +#endif diff --git a/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.cpp b/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.cpp index 7a5c3f1df0..43bcc0124b 100644 --- a/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.cpp +++ b/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.cpp @@ -21,32 +21,17 @@ using std::endl; namespace PokemonAutomation{ - -Logger& global_logger_raw(){ - auto get_log_filepath = [&](){ - QString application_name(QCoreApplication::applicationName()); - if (application_name.size() == 0){ - application_name = "SerialPrograms"; - } - return USER_FILE_PATH() + (application_name + ".log").toStdString(); - }; - - static FileWindowLogger logger(get_log_filepath(), LOG_HISTORY_LINES); - return logger; +FileWindowLogger& global_file_window_logger(){ + static FileWindowLogger file_winodw_logger; + return file_winodw_logger; } - FileWindowLogger::~FileWindowLogger(){ m_file_logger.remove_listener(*this); } -FileWindowLogger::FileWindowLogger(const std::string& path, size_t max_queue_size) - : m_file_logger(FileLoggerConfig{ - .file_path = path, - .max_queue_size = max_queue_size, - .max_file_size_bytes = 50 * 1024 * 1024, // 50MB - .last_log_max_lines = max_queue_size, - }) +FileWindowLogger::FileWindowLogger() + : m_file_logger(dynamic_cast(global_logger_raw())) { m_file_logger.add_listener(*this); } @@ -111,9 +96,9 @@ QString FileWindowLogger::to_window_str(const std::string& msg, Color color){ } -FileWindowLoggerWindow::FileWindowLoggerWindow(FileWindowLogger& logger, QWidget* parent) +FileWindowLoggerWindow::FileWindowLoggerWindow(QWidget* parent) : QMainWindow(parent) - , m_logger(logger) + , m_logger(global_file_window_logger()) { if (objectName().isEmpty()){ setObjectName(QString::fromUtf8("TextWindow")); diff --git a/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.h b/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.h index bd75a8bfbf..805195c714 100644 --- a/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.h +++ b/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.h @@ -19,6 +19,9 @@ namespace PokemonAutomation{ class FileWindowLoggerWindow; +class FileWindowLogger; + +FileWindowLogger& global_file_window_logger(); // A logger that writes to a file (via FileLogger) and can also display @@ -33,7 +36,7 @@ class FileWindowLogger : public Logger, private FileLogger::Listener{ // Construct a FileWindowLogger that writes to the given file path. // The max_queue_size parameter controls how many log messages can be // queued before the log() call blocks. - FileWindowLogger(const std::string& path, size_t max_queue_size); + FileWindowLogger(); // Add/remove Qt windows that will display log messages. void operator+=(FileWindowLoggerWindow& widget); @@ -53,7 +56,7 @@ class FileWindowLogger : public Logger, private FileLogger::Listener{ static QString to_window_str(const std::string& msg, Color color); private: - FileLogger m_file_logger; + FileLogger& m_file_logger; std::mutex m_window_lock; std::set m_windows; @@ -66,7 +69,7 @@ class FileWindowLoggerWindow : public QMainWindow, public ConfigOption::Listener Q_OBJECT public: - FileWindowLoggerWindow(FileWindowLogger& logger, QWidget* parent = nullptr); + FileWindowLoggerWindow(QWidget* parent = nullptr); virtual ~FileWindowLoggerWindow(); // Called by FileWindowLogger to display a log message. diff --git a/SerialPrograms/Source/CommonFramework/Logging/Logger.cpp b/SerialPrograms/Source/CommonFramework/Logging/Logger.cpp index bd20640b79..3284421ad1 100644 --- a/SerialPrograms/Source/CommonFramework/Logging/Logger.cpp +++ b/SerialPrograms/Source/CommonFramework/Logging/Logger.cpp @@ -6,6 +6,7 @@ #include #include "Common/Cpp/Logging/TaggedLogger.h" +#include "Common/Cpp/Logging/GlobalLogger.h" #include "Logger.h" namespace PokemonAutomation{ diff --git a/SerialPrograms/Source/CommonFramework/Logging/Logger.h b/SerialPrograms/Source/CommonFramework/Logging/Logger.h index 13fe92ecab..5b6a57adfc 100644 --- a/SerialPrograms/Source/CommonFramework/Logging/Logger.h +++ b/SerialPrograms/Source/CommonFramework/Logging/Logger.h @@ -10,16 +10,11 @@ #define PokemonAutomation_Logging_Logger_H #include "Common/Cpp/Logging/AbstractLogger.h" +#include "Common/Cpp/Logging/GlobalLogger.h" namespace PokemonAutomation{ -// The base logger for the application. Use this to build other loggers. -// Its implementation is defined in FileWindowLogger.cpp, writing each input -// log into a log file named "/.log". -// It prints each input log string as is with no tag or timestamp. -Logger& global_logger_raw(); - // This logger wraps around `global_logger_raw()` to print each log with a // timestamp and a default tag "Global". Use this logger directly in the // application codebase. diff --git a/SerialPrograms/Source/CommonFramework/Main.cpp b/SerialPrograms/Source/CommonFramework/Main.cpp index 3b48c7fd69..e319e97d9f 100644 --- a/SerialPrograms/Source/CommonFramework/Main.cpp +++ b/SerialPrograms/Source/CommonFramework/Main.cpp @@ -55,6 +55,10 @@ void set_working_directory(){ int run_program(int argc, char *argv[]){ QApplication application(argc, argv); + initialize_global_logger(FileLoggerConfig{ + .file_path = USER_FILE_PATH() + QCoreApplication::applicationName().toStdString() + ".log", + }); + GlobalOutputRedirector redirect_stdout(std::cout, "stdout", Color()); GlobalOutputRedirector redirect_stderr(std::cerr, "stderr", COLOR_RED); diff --git a/SerialPrograms/Source/CommonFramework/Windows/MainWindow.cpp b/SerialPrograms/Source/CommonFramework/Windows/MainWindow.cpp index 75a530645b..449b077ece 100644 --- a/SerialPrograms/Source/CommonFramework/Windows/MainWindow.cpp +++ b/SerialPrograms/Source/CommonFramework/Windows/MainWindow.cpp @@ -209,7 +209,7 @@ MainWindow::MainWindow(QWidget* parent) ); } { - m_output_window.reset(new FileWindowLoggerWindow((FileWindowLogger&)global_logger_raw())); + m_output_window.reset(new FileWindowLoggerWindow); QPushButton* output = new QPushButton("Output Window", support_box); buttons->addWidget(output); connect( diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index bdb91e44be..266bc69a33 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -98,6 +98,8 @@ file(GLOB LIBRARY_SOURCES ../Common/Cpp/Logging/AbstractLogger.h ../Common/Cpp/Logging/FileLogger.cpp ../Common/Cpp/Logging/FileLogger.h + ../Common/Cpp/Logging/GlobalLogger.cpp + ../Common/Cpp/Logging/GlobalLogger.h ../Common/Cpp/Logging/LastLogTracker.cpp ../Common/Cpp/Logging/LastLogTracker.h ../Common/Cpp/Logging/OutputRedirector.cpp From 191f0f230eabf5fb8d62a70b22fdc383264ea8e6 Mon Sep 17 00:00:00 2001 From: Gin <> Date: Mon, 19 Jan 2026 21:50:12 -0800 Subject: [PATCH 2/3] Remove FileWindowLogger --- .../Logging/FileWindowLogger.cpp | 55 +++--------------- .../Logging/FileWindowLogger.h | 57 ++++--------------- 2 files changed, 17 insertions(+), 95 deletions(-) diff --git a/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.cpp b/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.cpp index 43bcc0124b..ac4f96a296 100644 --- a/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.cpp +++ b/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.cpp @@ -7,6 +7,7 @@ #include #include #include +#include "Common/Cpp/Logging/GlobalLogger.h" #include "CommonFramework/Globals.h" #include "CommonFramework/GlobalSettingsPanel.h" #include "CommonFramework/Windows/DpiScaler.h" @@ -21,56 +22,14 @@ using std::endl; namespace PokemonAutomation{ -FileWindowLogger& global_file_window_logger(){ - static FileWindowLogger file_winodw_logger; - return file_winodw_logger; -} - -FileWindowLogger::~FileWindowLogger(){ - m_file_logger.remove_listener(*this); -} - -FileWindowLogger::FileWindowLogger() - : m_file_logger(dynamic_cast(global_logger_raw())) -{ - m_file_logger.add_listener(*this); -} - -void FileWindowLogger::operator+=(FileWindowLoggerWindow& widget){ - std::lock_guard lg(m_window_lock); - m_windows.insert(&widget); -} - -void FileWindowLogger::operator-=(FileWindowLoggerWindow& widget){ - std::lock_guard lg(m_window_lock); - m_windows.erase(&widget); -} - -void FileWindowLogger::log(const std::string& msg, Color color){ - m_file_logger.log(msg, color); -} - -void FileWindowLogger::log(std::string&& msg, Color color){ - m_file_logger.log(std::move(msg), color); -} -std::vector FileWindowLogger::get_last() const{ - return m_file_logger.get_last(); -} - -void FileWindowLogger::on_log(const std::string& msg, Color color){ +void FileWindowLoggerWindow::on_log(const std::string& msg, Color color){ // This is called from FileLogger's background thread. // Format the message for Qt display and send to all windows. - std::lock_guard lg(m_window_lock); - if (!m_windows.empty()){ - QString str = to_window_str(msg, color); - for (FileWindowLoggerWindow* window : m_windows){ - window->log(str); - } - } + emit signal_log(to_window_str(msg, color)); } -QString FileWindowLogger::to_window_str(const std::string& msg, Color color){ +QString FileWindowLoggerWindow::to_window_str(const std::string& msg, Color color){ // Convert message to HTML for display in QTextEdit. // Replace spaces with   and newlines with
. std::string str; @@ -98,8 +57,9 @@ QString FileWindowLogger::to_window_str(const std::string& msg, Color color){ FileWindowLoggerWindow::FileWindowLoggerWindow(QWidget* parent) : QMainWindow(parent) - , m_logger(global_file_window_logger()) + , m_logger(dynamic_cast(global_logger_raw())) { + m_logger.add_listener(*this); if (objectName().isEmpty()){ setObjectName(QString::fromUtf8("TextWindow")); } @@ -134,7 +94,6 @@ FileWindowLoggerWindow::FileWindowLoggerWindow(QWidget* parent) GlobalSettings::instance().LOG_WINDOW_SIZE->X_POS.add_listener(*this); GlobalSettings::instance().LOG_WINDOW_SIZE->Y_POS.add_listener(*this); - m_logger += *this; log("================================================================================"); log("Window Startup..."); log("Current path: " + QDir::currentPath()); @@ -146,7 +105,7 @@ FileWindowLoggerWindow::FileWindowLoggerWindow(QWidget* parent) FileWindowLoggerWindow::~FileWindowLoggerWindow(){ remove_window(*this); - m_logger -= *this; + m_logger.remove_listener(*this); GlobalSettings::instance().LOG_WINDOW_SIZE->WIDTH.remove_listener(*this); GlobalSettings::instance().LOG_WINDOW_SIZE->HEIGHT.remove_listener(*this); GlobalSettings::instance().LOG_WINDOW_SIZE->X_POS.remove_listener(*this); diff --git a/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.h b/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.h index 805195c714..d5ac9077a7 100644 --- a/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.h +++ b/SerialPrograms/Source/CommonFramework/Logging/FileWindowLogger.h @@ -18,54 +18,10 @@ namespace PokemonAutomation{ -class FileWindowLoggerWindow; -class FileWindowLogger; - -FileWindowLogger& global_file_window_logger(); - - -// A logger that writes to a file (via FileLogger) and can also display -// log messages in Qt GUI windows (FileWindowLoggerWindow). -// -// This class acts as a thin Qt wrapper around the Qt-free FileLogger, -// adding the ability to manage multiple Qt windows that display log output. -class FileWindowLogger : public Logger, private FileLogger::Listener{ -public: - ~FileWindowLogger(); - - // Construct a FileWindowLogger that writes to the given file path. - // The max_queue_size parameter controls how many log messages can be - // queued before the log() call blocks. - FileWindowLogger(); - - // Add/remove Qt windows that will display log messages. - void operator+=(FileWindowLoggerWindow& widget); - void operator-=(FileWindowLoggerWindow& widget); - - // Logger interface implementation - forwards to FileLogger. - virtual void log(const std::string& msg, Color color = Color()) override; - virtual void log(std::string&& msg, Color color = Color()) override; - virtual std::vector get_last() const override; - -private: - // FileLogger::Listener implementation - called when a message is logged. - // Formats the message for Qt display and sends to all registered windows. - virtual void on_log(const std::string& msg, Color color) override; - - // Convert a log message to HTML for display in QTextEdit. - static QString to_window_str(const std::string& msg, Color color); - -private: - FileLogger& m_file_logger; - - std::mutex m_window_lock; - std::set m_windows; -}; - // A Qt window that displays log output from a FileWindowLogger. // Uses Qt signals/slots for thread-safe updates from the logger's background thread. -class FileWindowLoggerWindow : public QMainWindow, public ConfigOption::Listener{ +class FileWindowLoggerWindow : public QMainWindow, public ConfigOption::Listener, public FileLogger::Listener{ Q_OBJECT public: @@ -73,9 +29,14 @@ class FileWindowLoggerWindow : public QMainWindow, public ConfigOption::Listener virtual ~FileWindowLoggerWindow(); // Called by FileWindowLogger to display a log message. - // Thread-safe: emits a signal that is handled on the UI thread. + void log(QString msg); + // Callback function registered to the global logger. + // The global logger's background thread call it to display a log to the window. + // Thread-safe: emits a signal that is handled on the UI thread. + void on_log(const std::string& msg, Color color) override; + virtual void resizeEvent(QResizeEvent* event) override; virtual void moveEvent(QMoveEvent* event) override; @@ -85,7 +46,9 @@ class FileWindowLoggerWindow : public QMainWindow, public ConfigOption::Listener private: virtual void on_config_value_changed(void* object) override; - FileWindowLogger& m_logger; + static QString to_window_str(const std::string& msg, Color color); + + FileLogger& m_logger; QMenuBar* m_menubar; QTextEdit* m_text; bool m_pending_resize = false; From 4ef80bc0c8cad1c910dd24655dad34dfdd1bdc63 Mon Sep 17 00:00:00 2001 From: Gin <> Date: Mon, 19 Jan 2026 22:23:40 -0800 Subject: [PATCH 3/3] fix file loger on command line --- Common/Cpp/Logging/FileLogger.cpp | 11 +++++++ Common/Cpp/Logging/FileLogger.h | 1 + Common/Cpp/Logging/GlobalLogger.cpp | 30 +++++++++++-------- Common/Cpp/Logging/GlobalLogger.h | 13 +++----- .../Source/CommandLine/CommandLine_Main.cpp | 14 +++++++++ .../Source/CommonFramework/Main.cpp | 20 ++++++++++--- 6 files changed, 63 insertions(+), 26 deletions(-) diff --git a/Common/Cpp/Logging/FileLogger.cpp b/Common/Cpp/Logging/FileLogger.cpp index a087453243..361d5609a8 100644 --- a/Common/Cpp/Logging/FileLogger.cpp +++ b/Common/Cpp/Logging/FileLogger.cpp @@ -133,6 +133,17 @@ void FileLogger::thread_loop(){ return m_stopping || !m_queue.empty(); }); if (m_stopping){ + if (m_config.flush_when_exit && m_file.is_open()){ + while (m_queue.size() > 0){ + std::string msg = std::move(m_queue.front().first); + // Write to file + std::string line = normalize_newlines(msg); + std::string file_str = to_file_str(line); + m_file.write(file_str.c_str(), file_str.size()); + m_queue.pop_front(); + } + m_file.flush(); + } break; } auto& item = m_queue.front(); diff --git a/Common/Cpp/Logging/FileLogger.h b/Common/Cpp/Logging/FileLogger.h index 33d123b1b6..ef71c63742 100644 --- a/Common/Cpp/Logging/FileLogger.h +++ b/Common/Cpp/Logging/FileLogger.h @@ -28,6 +28,7 @@ struct FileLoggerConfig{ size_t max_queue_size = 10000; // Max pending log entries before blocking size_t max_file_size_bytes = 50 * 1024 * 1024; // Max file size before rotation (50MB default) size_t last_log_max_lines = 10000; // Max lines to keep in memory for get_last() + bool flush_when_exit = true; // Whether to save remaining logs to file when program exists }; diff --git a/Common/Cpp/Logging/GlobalLogger.cpp b/Common/Cpp/Logging/GlobalLogger.cpp index b27f7b2ffe..f6d1886120 100644 --- a/Common/Cpp/Logging/GlobalLogger.cpp +++ b/Common/Cpp/Logging/GlobalLogger.cpp @@ -9,22 +9,26 @@ namespace PokemonAutomation{ -static FileLoggerConfig _global_logger_config; +// We should define this function at Main.cpp of each executable +// that uses the Logging/ library. +// +// This function is required by Common/Cpp/Logging/GlobalLogger.h:global_logger_raw() to initialize +// the global file logger. +// This function is called the first time `global_logger_raw()` is called to initialize the static +// local global file logger object. +// +// The advantage of such design is that: +// - This forces each executable's main.cpp to define how the logger is configured. +// - This ensures thread-safety on the global logger object. The static local `FileLogger` defined +// in `global_logger_raw()` is guaranteed by C++ to be thread-safe when constructed. +FileLoggerConfig make_global_config(); -void initialize_global_logger(FileLoggerConfig config){ - _global_logger_config = std::move(config); - // auto& logger = global_logger_raw(); - // logger.log("Initialized logger with path " + config.file_path); -} Logger& global_logger_raw(){ - auto get_config = [&](){ - if (_global_logger_config.file_path.size() == 0){ - _global_logger_config.file_path = "."; - } - return _global_logger_config; - }; - static FileLogger logger(get_config()); + // Call a function `make_global_config()` that is not defined in + // this Logging/ library! To use this global logger, you must + // define `make_global_config()` in the Main.cpp. + static FileLogger logger(make_global_config()); return logger; } diff --git a/Common/Cpp/Logging/GlobalLogger.h b/Common/Cpp/Logging/GlobalLogger.h index d7072db575..9fa2a0cd9a 100644 --- a/Common/Cpp/Logging/GlobalLogger.h +++ b/Common/Cpp/Logging/GlobalLogger.h @@ -14,17 +14,12 @@ namespace PokemonAutomation{ -// Call this function at very beginning of the main function to initialize the global file logger. -// Call `global_logger_raw()` to retrieve the global file logger afterwards. -// If not called, a default logger with default file path of "." will be created. -void initialize_global_logger(FileLoggerConfig config); - - // Return a global raw `FileLogger`. `FileLogger` is defined in FileLogger.h. // "raw" here means the logger does not add any timestamp or tags to the incoming log lines. -// Suggest calling `initialize_global_logger()` at very beginning of the main function to -// initialize the logger first. Otherwise a default logger with default file path of "." -// will be created. +// +// To initialize the global logger, implement `FileLoggerConfig make_global_config()` at +// Main.cpp to return the config for the global logger. If this function is not implemented, +// the program will not compile. Logger& global_logger_raw(); diff --git a/SerialPrograms/Source/CommandLine/CommandLine_Main.cpp b/SerialPrograms/Source/CommandLine/CommandLine_Main.cpp index 15e36cc01a..97ab7fd531 100644 --- a/SerialPrograms/Source/CommandLine/CommandLine_Main.cpp +++ b/SerialPrograms/Source/CommandLine/CommandLine_Main.cpp @@ -16,6 +16,20 @@ using namespace PokemonAutomation; using namespace PokemonAutomation::NintendoSwitch; +namespace PokemonAutomation{ + +// This function is required by Common/Cpp/Logging/GlobalLogger.h:global_logger_raw() to initialize +// the global file logger. +// This function is called the first time `global_logger_raw()` is called to initialize the static +// local global file logger object. +FileLoggerConfig make_global_config(){ + return FileLoggerConfig{ + .file_path = "./SerialProgramsCommandLine.log" + }; +} + +} + int main(int argc, char* argv[]){ // // Set up output redirection for logging // OutputRedirector redirect_stdout(std::cout, "stdout", Color()); diff --git a/SerialPrograms/Source/CommonFramework/Main.cpp b/SerialPrograms/Source/CommonFramework/Main.cpp index e319e97d9f..44c9a54d29 100644 --- a/SerialPrograms/Source/CommonFramework/Main.cpp +++ b/SerialPrograms/Source/CommonFramework/Main.cpp @@ -51,14 +51,26 @@ void set_working_directory(){ } } +namespace PokemonAutomation{ + +// This function is required by Common/Cpp/Logging/GlobalLogger.h:global_logger_raw() to initialize +// the global file logger. +// This function is called the first time `global_logger_raw()` is called to initialize the static +// local global file logger object. +// Note: in order to make sure `USER_FILE_PATH()` and `QCoreApplication::applicationName()` work +// correctly you need to define `QApplication` before `make_global_config()` is called. +FileLoggerConfig make_global_config(){ + return FileLoggerConfig{ + .file_path = USER_FILE_PATH() + QCoreApplication::applicationName().toStdString() + ".log", + }; +} + +} + int run_program(int argc, char *argv[]){ QApplication application(argc, argv); - initialize_global_logger(FileLoggerConfig{ - .file_path = USER_FILE_PATH() + QCoreApplication::applicationName().toStdString() + ".log", - }); - GlobalOutputRedirector redirect_stdout(std::cout, "stdout", Color()); GlobalOutputRedirector redirect_stderr(std::cerr, "stderr", COLOR_RED);