// MassBuilderSaveTool // Copyright (C) 2021-2022 Guillaume Jacquemin // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifdef SAVETOOL_DEBUG_BUILD #include #else #include #endif #include #include #include #include #include "Logger.h" using Containers::Array; using Utility::Debug; using Utility::Warning; using Utility::Error; using namespace Magnum; namespace MassBuilderSaveTool { namespace Logger { #ifndef SAVETOOL_DEBUG_BUILD static std::ofstream log_file{"SaveToolLog.txt", std::ios::trunc}; #endif static UnsignedInt _indentLevel = 0; static std::mutex _logMutex; static Array _entries; inline Debug& operator<<(Debug& out, const LogEntry& entry) { using namespace Containers::Literals; out << "["_s << Debug::nospace << entry.timestamp << Debug::nospace << "]"_s; #ifdef SAVETOOL_DEBUG_BUILD #define COLOUR(col) << Debug::color(Debug::Color::col) #else #define COLOUR(col) #endif switch(entry.type) { case EntryType::Info: out << "[INFO]"_s COLOUR(Default); break; case EntryType::Success: out << "[SUCCESS]"_s COLOUR(Green); break; case EntryType::Warning: out << "[WARNING]"_s COLOUR(Yellow); break; case EntryType::Error: out << "[ERROR]"_s COLOUR(Red); break; } #undef DEBUG_COLOUR for(UnsignedInt i = 0; i < _indentLevel; i++) { out << Debug::nospace << " "_s << Debug::nospace; } out << entry.message << Debug::resetColor; return out; } void initialise() { arrayReserve(_entries, 100); } void indent() { _indentLevel++; } void unindent() { if(_indentLevel > 0) { _indentLevel--; } } void addEntry(EntryType type, StringView message) { auto time = std::time(nullptr); static char formatted_time[20] = {'\0'}; std::strftime(&formatted_time[0], sizeof(formatted_time)/sizeof(formatted_time[0]), "%Y-%m-%d %H:%M:%S", // Because MSVCRT (which is the CRT I target by default) is not C99-compliant, // I can't use "%F %T" as the format string. std::localtime(&time)); LogEntry entry{ formatted_time, type, (message.back() == '\n') ? String{message.exceptSuffix(1)} : String{message} }; Debug{ #ifndef SAVETOOL_DEBUG_BUILD &log_file #else &std::cout #endif } << entry; arrayAppend(_entries, std::move(entry)); } ArrayView entries() { return _entries; } void lockMutex() { _logMutex.lock(); } void unlockMutex() { _logMutex.unlock(); } bool tryLockMutex() { return _logMutex.try_lock(); } } // Logger } // MassBuilderSaveTool