MassBuilderSaveTool/src/Logger/Logger.cpp

154 lines
3.4 KiB
C++

// 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 <https://www.gnu.org/licenses/>.
#ifdef SAVETOOL_DEBUG_BUILD
#include <iostream>
#else
#include <fstream>
#endif
#include <mutex>
#include <Corrade/Containers/GrowableArray.h>
#include <Corrade/Utility/Debug.h>
#include <Magnum/Types.h>
#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<LogEntry> _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<const LogEntry>
entries() {
return _entries;
}
void
lockMutex() {
_logMutex.lock();
}
void
unlockMutex() {
_logMutex.unlock();
}
bool
tryLockMutex() {
return _logMutex.try_lock();
}
} // Logger
} // MassBuilderSaveTool