Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[submodule "Base"]
path = Base
url = git@github.com:atalantestudio/ModuleBase
url = https://github.com/atalantestudio/ModuleBase
branch = main
2 changes: 1 addition & 1 deletion Base
11 changes: 4 additions & 7 deletions scroll/ConsoleLogger/ConsoleLogger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

#pragma once

#include "ConsoleEscapeCode.hpp"
#include "Logger/Logger.hpp"
#include "LogLevel.hpp"
#include "scroll/ConsoleEscapeCode.hpp"
#include "scroll/Logger/Logger.hpp"
#include "scroll/LogLevel.hpp"

namespace scroll {
class ConsoleLogger : public Logger {
Expand All @@ -24,9 +24,6 @@ namespace scroll {
template<typename Argument>
ConsoleLogger& operator<<(Argument&& argument);

template<>
ConsoleLogger& operator<<(ConsoleEscapeCode&& argument);

ConsoleLogger& padLeft(uint64 padding);

ConsoleLogger& padRight(uint64 padding);
Expand Down Expand Up @@ -67,4 +64,4 @@ namespace scroll {
};
}

#include "ConsoleLogger.ipp"
#include "scroll/ConsoleLogger/ConsoleLogger.ipp"
22 changes: 15 additions & 7 deletions scroll/ConsoleLogger/ConsoleLogger.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ namespace scroll {
}

inline ConsoleLogger::ConsoleLogger(std::ostream& stream, LogLevel minimumLogLevel, view<char8> source) :
Logger(minimumLogLevel, source),
stream(&stream)
{}
Logger(minimumLogLevel, source)
{
setOutputStream(stream);
}

inline ConsoleLogger::~ConsoleLogger() {
if (writingEscapeCodes) {
Expand All @@ -30,6 +31,13 @@ namespace scroll {

inline void ConsoleLogger::setOutputStream(std::ostream& stream) {
this->stream = &stream;

#if ATL_OPERATING_SYSTEM == ATL_OPERATING_SYSTEM_WINDOWS
const HANDLE hConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);

ATL_ASSERT(hConsoleHandle != NULL && hConsoleHandle != INVALID_HANDLE_VALUE);
ATL_ASSERT(SetConsoleMode(hConsoleHandle, ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING) > 0);
#endif
}

template<typename Argument>
Expand Down Expand Up @@ -82,7 +90,7 @@ namespace scroll {
std::ostream& stream = std::cerr;

writeLogHeader(stream, source, "TRACE", ConsoleEscapeCode::BACKGROUND_COLOR_WHITE, ConsoleEscapeCode::FOREGROUND_COLOR_BLACK);
writeIndented(stream, format("[]\nat []:[]", format(std::forward<Argument>(argument)), file, line), getLogIndentation() - 2);
writeIndented(stream, format("[] (at []:[])", format(std::forward<Argument>(argument)), file, line), getLogIndentation() - 2);

stream << '\n';
}
Expand All @@ -96,7 +104,7 @@ namespace scroll {
std::ostream& stream = std::cerr;

writeLogHeader(stream, source, "TRACE", ConsoleEscapeCode::BACKGROUND_COLOR_WHITE, ConsoleEscapeCode::FOREGROUND_COLOR_BLACK);
writeIndented(stream, format("[]\nat []:[]", format(pattern, std::forward<Argument>(arguments)...), file, line), getLogIndentation() - 2);
writeIndented(stream, format("[] (at []:[])", format(pattern, std::forward<Argument>(arguments)...), file, line), getLogIndentation() - 2);

stream << '\n';
}
Expand Down Expand Up @@ -195,7 +203,7 @@ namespace scroll {

writeLogHeader(stream, source, "ERROR", ConsoleEscapeCode::BACKGROUND_COLOR_LIGHT_RED, ConsoleEscapeCode::FOREGROUND_COLOR_WHITE);
stream << "\033[" << ConsoleEscapeCode::FOREGROUND_COLOR_LIGHT_RED << 'm';
writeIndented(stream, format("[]\nat [] ([]:[])", format(std::forward<Argument>(argument)), function, file, line), getLogIndentation() - 2);
writeIndented(stream, format("[] (in [], at []:[])", format(std::forward<Argument>(argument)), function, file, line), getLogIndentation() - 2);
stream << "\033[" << ConsoleEscapeCode::RESET_FOREGROUND_COLOR << "m\n";
}

Expand All @@ -209,7 +217,7 @@ namespace scroll {

writeLogHeader(stream, source, "ERROR", ConsoleEscapeCode::BACKGROUND_COLOR_LIGHT_RED, ConsoleEscapeCode::FOREGROUND_COLOR_WHITE);
stream << "\033[" << ConsoleEscapeCode::FOREGROUND_COLOR_LIGHT_RED << 'm';
writeIndented(stream, format("[]\nat [] ([]:[])", format(pattern, std::forward<Argument>(arguments)...), function, file, line), getLogIndentation() - 2);
writeIndented(stream, format("[] (in [], at []:[])", format(pattern, std::forward<Argument>(arguments)...), function, file, line), getLogIndentation() - 2);
stream << "\033[" << ConsoleEscapeCode::RESET_FOREGROUND_COLOR << "m\n";
}
}
4 changes: 2 additions & 2 deletions scroll/Conversions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

#pragma once

#include "ConsoleEscapeCode.hpp"
#include "scroll/ConsoleEscapeCode.hpp"

namespace scroll {
std::ostream& operator<<(std::ostream& stream, view<char8> view);
std::ostream& operator<<(std::ostream& stream, ConsoleEscapeCode code);
}

#include "Conversions.ipp"
#include "scroll/Conversions.ipp"
6 changes: 3 additions & 3 deletions scroll/FileLogger/FileLogger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

#pragma once

#include "Logger/Logger.hpp"
#include "LogLevel.hpp"
#include "scroll/Logger/Logger.hpp"
#include "scroll/LogLevel.hpp"

namespace scroll {
class FileLogger : public Logger {
Expand Down Expand Up @@ -49,4 +49,4 @@ namespace scroll {
};
}

#include "FileLogger.ipp"
#include "scroll/FileLogger/FileLogger.ipp"
10 changes: 5 additions & 5 deletions scroll/FileLogger/FileLogger.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace scroll {
Logger(minLogLevel, source),
stream(stream)
{
ASSERT(stream.is_open());
ATL_ASSERT(stream.is_open());
}

template<typename Argument>
Expand All @@ -16,7 +16,7 @@ namespace scroll {
}

writeLogHeader("TRACE");
writeIndented(stream, format("[]\nat []:[]", format(std::forward<Argument>(argument)), file, line), getLogIndentation() - 4);
writeIndented(stream, format("[] (at []:[])", format(std::forward<Argument>(argument)), file, line), getLogIndentation() - 4);

stream << '\n';
}
Expand All @@ -28,7 +28,7 @@ namespace scroll {
}

writeLogHeader("TRACE");
writeIndented(stream, format("[]\nat []:[]", format(pattern, std::forward<Argument>(arguments)...), file, line), getLogIndentation() - 4);
writeIndented(stream, format("[] (at []:[])", format(pattern, std::forward<Argument>(arguments)...), file, line), getLogIndentation() - 4);

stream << '\n';
}
Expand Down Expand Up @@ -112,7 +112,7 @@ namespace scroll {
}

writeLogHeader("ERROR");
writeIndented(stream, format("[]\nat [] ([]:[])", format(std::forward<Argument>(argument)), function, file, line), getLogIndentation() - 4);
writeIndented(stream, format("[] (in [], at []:[])", format(std::forward<Argument>(argument)), function, file, line), getLogIndentation() - 4);

stream << '\n';
}
Expand All @@ -124,7 +124,7 @@ namespace scroll {
}

writeLogHeader("ERROR");
writeIndented(stream, format("[]\nat [] ([]:[])", format(pattern, std::forward<Argument>(arguments)...), function, file, line), getLogIndentation() - 4);
writeIndented(stream, format("[] (in [], at []:[])", format(pattern, std::forward<Argument>(arguments)...), function, file, line), getLogIndentation() - 4);

stream << '\n';
}
Expand Down
15 changes: 9 additions & 6 deletions scroll/Logger/Logger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@

#pragma once

#include "LogLevel.hpp"
#include "scroll/LogLevel.hpp"

namespace scroll {
class Logger {
template<typename T = void>
struct ArgumentInjectionPattern {
static sequence<char8> argumentInjectionPattern;
};

class Logger : public ArgumentInjectionPattern<> {
public:
// Returns the current argument injection pattern.
static view<char8> getArgumentInjectionPattern();
Expand All @@ -27,9 +32,7 @@ namespace scroll {
static void writeIndented(std::ostream& stream, view<char8> text, uint64 indentation);

private:
static sequence<char8> argumentInjectionPattern;

static constexpr uint64 TIMESTAMP_SIZE = 14;
static constexpr uint64 TIMESTAMP_SIZE = 15;
static constexpr uint64 MAX_LOG_LEVEL_NAME_SIZE = 7;

public:
Expand All @@ -48,4 +51,4 @@ namespace scroll {
};
}

#include "Logger.ipp"
#include "scroll/Logger/Logger.ipp"
56 changes: 39 additions & 17 deletions scroll/Logger/Logger.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@
// Licensed under MIT.

namespace scroll {
template<typename T>
sequence<char8> ArgumentInjectionPattern<T>::argumentInjectionPattern = "[]";

template<typename Argument>
sequence<char8> Logger::format(Argument&& argument) {
std::ostringstream stream;
static std::ostringstream stream;

stream << argument;

return stream.str().c_str();
const sequence<char8> formattedArgument = stream.str().c_str();

stream.str({});

return formattedArgument;
}

template<typename HeadArgument, typename... Argument>
Expand All @@ -23,46 +30,61 @@ namespace scroll {

sequence<char8> updatedPattern(pattern.count() - argumentInjectionPattern.count() + formattedArgument.count());

std::copy_n(&pattern[0], argumentInjectionPatternOffset, &updatedPattern[0]);
std::copy(formattedArgument.begin(), formattedArgument.end(), &updatedPattern[argumentInjectionPatternOffset]);
copy(&pattern[0], &pattern[argumentInjectionPatternOffset], &updatedPattern[0]);
copy(formattedArgument.begin(), formattedArgument.end(), &updatedPattern[argumentInjectionPatternOffset]);

if (argumentInjectionPatternOffset + argumentInjectionPattern.count() < pattern.count()) {
std::copy(&pattern[argumentInjectionPatternOffset + argumentInjectionPattern.count()], pattern.end(), &updatedPattern[argumentInjectionPatternOffset + formattedArgument.count()]);
copy(&pattern[argumentInjectionPatternOffset + argumentInjectionPattern.count()], pattern.end(), &updatedPattern[argumentInjectionPatternOffset + formattedArgument.count()]);
}

return format(updatedPattern, std::forward<Argument>(arguments)...);
}

inline sequence<char8> Logger::argumentInjectionPattern = "[]";

inline view<char8> Logger::getArgumentInjectionPattern() {
return argumentInjectionPattern;
}

inline void Logger::setArgumentInjectionPattern(view<char8> pattern) {
ASSERT(pattern.count() > 0);
ATL_ASSERT(pattern.count() > 0);

argumentInjectionPattern = &pattern[0];
}

inline sequence<char8> Logger::timestamp() {
static std::ostringstream usStream;

const std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
const uint64 ms = std::chrono::duration_cast<std::chrono::milliseconds>(now - std::chrono::time_point_cast<std::chrono::seconds>(now)).count();
const uint64 us = std::chrono::duration_cast<std::chrono::microseconds>(now - std::chrono::time_point_cast<std::chrono::seconds>(now)).count();
const std::time_t time = std::chrono::system_clock::to_time_t(now);

std::tm dateTime;
std::tm* dateTime;

#ifdef _MSC_VER
std::tm _dateTime{};

localtime_s(&dateTime, &time);
const errno_t error = localtime_s(&_dateTime, &time);

// NOTE: std::strftime writes the null-terminating character.
ATL_ASSERT(error == 0);

dateTime = &_dateTime;
#else
dateTime = std::localtime(&time);
#endif

// Include null-terminating character.
sequence<char8> hmsString(9);

ASSERT(std::strftime(&hmsString[0], hmsString.count(), "%T", &dateTime) > 0);
const uint64 hmsCharacterCount = std::strftime(&hmsString[0], hmsString.count(), "%H:%M:%S", dateTime);

ATL_ASSERT(hmsCharacterCount > 0);

usStream << std::setw(6) << std::setfill('0') << us;

const sequence<char8> timestamp = format("[].[]", hmsString, usStream.str());

std::ostringstream msStream;
msStream << std::setw(3) << std::setfill('0') << ms;
usStream.str({});

return format("[].[]", hmsString, msStream.str());
return timestamp;
}

inline LogLevel Logger::getMinLogLevel() const {
Expand All @@ -79,7 +101,7 @@ namespace scroll {
{}

inline uint16 Logger::getLogIndentation() const {
uint16 indentation = static_cast<uint16>(TIMESTAMP_SIZE + MAX_LOG_LEVEL_NAME_SIZE + 4);
uint16 indentation = static_cast<uint16>(TIMESTAMP_SIZE + MAX_LOG_LEVEL_NAME_SIZE + 6);

if (source.count() > 0) {
indentation += static_cast<uint16>(source.count()) + 1;
Expand Down
12 changes: 12 additions & 0 deletions scroll/base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,25 @@
#pragma once

#include <chrono>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <ios>
#include <iostream>
#include <sstream>

#ifndef ATL_MODULE_BASE
#include "Base/Base/Base.hpp"
#endif

#if ATL_OPERATING_SYSTEM == ATL_OPERATING_SYSTEM_WINDOWS
#include <Windows.h>

#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif
#endif

namespace scroll {
using atl::uint8;
using atl::uint16;
Expand All @@ -23,4 +33,6 @@ namespace scroll {

using atl::sequence;
using atl::view;

using atl::copy;
}
10 changes: 4 additions & 6 deletions scroll/scroll.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@

#pragma once

#include "base.hpp"

#include "Conversions.hpp"

#include "ConsoleLogger/ConsoleLogger.hpp"
#include "FileLogger/FileLogger.hpp"
#include "scroll/base.hpp"
#include "scroll/Conversions.hpp"
#include "scroll/ConsoleLogger/ConsoleLogger.hpp"
#include "scroll/FileLogger/FileLogger.hpp"