diff --git a/PreCompiledHeaders.cmake b/PreCompiledHeaders.cmake index c51028527b7e92bd387a1a01600ad0585cc49ff3..dce8f03b4c87f3ac598c970fe04e5e173e476c6e 100644 --- a/PreCompiledHeaders.cmake +++ b/PreCompiledHeaders.cmake @@ -8,6 +8,7 @@ set(STL_INC <stdexcept> <sstream> <map> + <utility> <locale> <functional> <initializer_list> diff --git a/src/Lib/Log.cc b/src/Lib/Log.cc index 020add3daab267b6516fc8573a52ea62ae478629..461c69459f58ab4e495081547f3d81defd809194 100644 --- a/src/Lib/Log.cc +++ b/src/Lib/Log.cc @@ -5,6 +5,39 @@ using namespace Vivy; LogSink::~LogSink() noexcept {} LogMessage::~LogMessage() noexcept { parentLogger->sendLogMessage(*this); } +const chrono::milliseconds +LogMessage::getTimeStamp() const noexcept +{ + return timeStamp; +} + +LogMessage::Header const & +LogMessage::getHeader() const noexcept +{ + return messageHeader; +} + +const std::string_view +LogMessage::getTextBuffer() const noexcept +{ + const char *txt = textBuffer.data(); + return std::string_view{ txt, strlen(txt) }; +} + +void +Logger::sendLogMessage(const LogMessage &msg) const noexcept +{ + parentLogSink->recieveLogMessage(this, msg); +} + +// Get the log message from the logger and add it to the sink's queue. +void +LogSink::recieveLogMessage(const Logger *const logger, LogMessage const &msg) noexcept +{ + const std::lock_guard<std::mutex> messageQueueLockGuard(messageQueueLock); + messageQueue.emplace_back(msg); +} + std::shared_ptr<LogSink> LogSink::newSink() noexcept { @@ -45,11 +78,6 @@ Logger::logEvent(const char *fileName, const char *functionName, const int lineN .lineNumberInFile = lineNumber }); } -void -Logger::sendLogMessage(const LogMessage &msg) const noexcept { - TODO(Write the code to send the event...) -} - LogMessage::LogMessage(Logger *const logger, const LogMessage::Header hdr) noexcept : messageHeader(hdr) , parentLogger(logger) @@ -57,19 +85,37 @@ LogMessage::LogMessage(Logger *const logger, const LogMessage::Header hdr) noexc } LogMessage & -LogMessage::operator<<(const std::string &) noexcept +LogMessage::operator<<(const std::string &msg) noexcept { - return *this; + return (*this << msg.c_str()); } LogMessage & -LogMessage::operator<<(const int) noexcept +LogMessage::operator<<(const QString &msg) noexcept { - return *this; + return (*this << msg.toStdString()); +} + +LogMessage & +LogMessage::operator<<(const int i) noexcept +{ + return (*this << static_cast<long>(i)); +} + +LogMessage & +LogMessage::operator<<(const long i) noexcept +{ + return (*this << std::to_string(i)); } LogMessage & -LogMessage::operator<<(const long) noexcept +LogMessage::operator<<(const char *str) noexcept { + const std::size_t length = strlen(str); + for (std::size_t i = 0; (i < length) && (indexInArray < messageBufferLength - 1); + ++i, ++indexInArray) { + textBuffer[indexInArray] = str[i]; + } + textBuffer[indexInArray] = '\0'; return *this; } diff --git a/src/Lib/Log.hh b/src/Lib/Log.hh index b5a4e6f4770fd7989c489e534bca50c48bee82df..227389ea5a7938f68633ecd4cc0213e4f17ab6a3 100644 --- a/src/Lib/Log.hh +++ b/src/Lib/Log.hh @@ -25,6 +25,7 @@ namespace Vivy { class VivyApplication; class VivyCli; +class LogSinkDispatcher; class LogSink; class Logger; class LogMessage; @@ -41,7 +42,8 @@ enum class LogLevel : int { }; // LogSink is the parent logger. It will recieve messages and display them to a -// console or to std::cerr or to a file, etc. +// console or to std::cerr or to a file, etc. The save to over file, etc will +// be donne by the LogSinkDispatcher. class LogSink { VIVY_UNMOVABLE_OBJECT(LogSink) @@ -55,15 +57,17 @@ public: void closeLoggerClient(Logger *const) noexcept; void closeLoggerClient(const std::shared_ptr<Logger> &) noexcept; + void recieveLogMessage(const Logger *const, LogMessage const &) noexcept; + private: + std::mutex messageQueueLock{}; std::vector<LogMessage> messageQueue; std::vector<std::shared_ptr<Logger>> clientLoggers; }; // Message to be logged, constructed by a logger then send class LogMessage final { - friend class Logger; - +public: struct Header final { const char *fileName; const char *functionName; @@ -72,7 +76,19 @@ class LogMessage final { }; LogMessage(Logger *const, const Header) noexcept; + ~LogMessage() noexcept; // The message will be send on destruction + + Header const &getHeader() const noexcept; + const std::string_view getTextBuffer() const noexcept; + const chrono::milliseconds getTimeStamp() const noexcept; + + LogMessage &operator<<(const std::string &) noexcept; + LogMessage &operator<<(const QString &) noexcept; + LogMessage &operator<<(const char *) noexcept; + LogMessage &operator<<(const int) noexcept; + LogMessage &operator<<(const long) noexcept; +private: const Header messageHeader; const chrono::milliseconds timeStamp{ duration_cast<chrono::milliseconds>( chrono::system_clock::now().time_since_epoch()) }; @@ -81,14 +97,6 @@ class LogMessage final { std::array<char, messageBufferLength> textBuffer{}; std::size_t indexInArray{ 0 }; Logger *const parentLogger; - -public: - // The message will be send on destruction - ~LogMessage() noexcept; - - LogMessage &operator<<(const std::string &) noexcept; - LogMessage &operator<<(const int) noexcept; - LogMessage &operator<<(const long) noexcept; }; // A logger class, a client to LogSink. Will generate and send instances of diff --git a/src/VivyApplication.cc b/src/VivyApplication.cc index efb10c01c29927a412fa85c03a65975524f00250..b312b27c2a41d628d74795ac1c971e20a9efa12c 100644 --- a/src/VivyApplication.cc +++ b/src/VivyApplication.cc @@ -11,19 +11,22 @@ VivyApplication::VivyApplication(int &argc, char **argv) void VivyApplication::setTheme(Theme theme) noexcept { - if (theme == Theme::System) + if (theme == Theme::System) { + logInfo() << "Set theme to system theme"; return; + } const QString sheet = theme == Theme::Dark ? QStringLiteral(":qdarkstyle/dark/style.qss") : QStringLiteral(":qdarkstyle/light/style.qss"); QFile stylesheet(sheet); if (!stylesheet.exists()) { - qFatal("Missing stylesheet"); + logFatal() << "Missing stylesheet!"; } else { stylesheet.open(QFile::ReadOnly | QFile::Text); QTextStream stylesheetStream(&stylesheet); setStyleSheet(stylesheetStream.readAll()); + logInfo() << "Theme set using " << sheet; } } @@ -56,6 +59,8 @@ VivyApplication::exec() noexcept mainWindowPtr = std::make_unique<MainWindow>(); mainWindowPtr->show(); + logInfo() << "Entering the main event loop"; + // Main loop return QApplication::exec(); }