- Add ModelRender - Add Camera - Add TextRenderer - Add RTTI Object class - Add PhysicsCollider interface: getClassName method - Add AlignedMemoryStack class - fix Logger and LoggerSpdLog - fix Model2D method: getPhysics, remove const qualifier
355 lines
10 KiB
C++
355 lines
10 KiB
C++
#pragma once
|
|
#include <Logger.h>
|
|
//#include "../include/Logger.h"
|
|
//#include "../../../vcpkg_installed/x64-windows/include/spdlog/spdlog.h"
|
|
//#include "../../../vcpkg_installed/x64-windows/include/spdlog/sinks/sink.h"
|
|
//#include "../../../vcpkg_installed/x64-windows/include/spdlog/sinks/stdout_color_sinks.h"
|
|
#include <spdlog/spdlog.h>
|
|
#include <spdlog/sinks/stdout_color_sinks.h>
|
|
#include <spdlog/sinks/basic_file_sink.h>
|
|
#include <any>
|
|
|
|
class SpdLogUtils {
|
|
public:
|
|
enum class SpdLogLevel : int
|
|
{
|
|
trace = SPDLOG_LEVEL_TRACE,
|
|
debug = SPDLOG_LEVEL_DEBUG,
|
|
info = SPDLOG_LEVEL_INFO,
|
|
warning = SPDLOG_LEVEL_WARN,
|
|
error = SPDLOG_LEVEL_ERROR,
|
|
critical = SPDLOG_LEVEL_CRITICAL,
|
|
off = SPDLOG_LEVEL_OFF
|
|
};
|
|
static SpdLogLevel logLevelToSpdLogLevel(LogLevel level) {
|
|
SpdLogLevel spdLevel = SpdLogLevel::trace;
|
|
switch (level)
|
|
{
|
|
case LogLevel::trace:
|
|
spdLevel = SpdLogLevel::trace;
|
|
break;
|
|
case LogLevel::debug:
|
|
spdLevel = SpdLogLevel::debug;
|
|
break;
|
|
case LogLevel::info:
|
|
spdLevel = SpdLogLevel::info;
|
|
break;
|
|
case LogLevel::warning:
|
|
spdLevel = SpdLogLevel::warning;
|
|
break;
|
|
case LogLevel::error:
|
|
spdLevel = SpdLogLevel::error;
|
|
break;
|
|
case LogLevel::critical:
|
|
spdLevel = SpdLogLevel::critical;
|
|
break;
|
|
case LogLevel::off:
|
|
spdLevel = SpdLogLevel::off;
|
|
break;
|
|
default:
|
|
spdLevel = SpdLogLevel::trace;
|
|
break;
|
|
}
|
|
return spdLevel;
|
|
}
|
|
static LogLevel spdLogLevelToLogLevel(SpdLogLevel level) {
|
|
LogLevel l = LogLevel::trace;
|
|
switch (level)
|
|
{
|
|
case SpdLogUtils::SpdLogLevel::trace:
|
|
l = LogLevel::trace;
|
|
break;
|
|
case SpdLogUtils::SpdLogLevel::debug:
|
|
l = LogLevel::debug;
|
|
break;
|
|
case SpdLogUtils::SpdLogLevel::info:
|
|
l = LogLevel::info;
|
|
break;
|
|
case SpdLogUtils::SpdLogLevel::warning:
|
|
l = LogLevel::warning;
|
|
break;
|
|
case SpdLogUtils::SpdLogLevel::error:
|
|
l = LogLevel::error;
|
|
break;
|
|
case SpdLogUtils::SpdLogLevel::critical:
|
|
l = LogLevel::critical;
|
|
break;
|
|
case SpdLogUtils::SpdLogLevel::off:
|
|
l = LogLevel::off;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return l;
|
|
}
|
|
typedef spdlog::color_mode SpdLogColorMode;
|
|
static SpdLogColorMode logColorModeToSpdLogColorMode(LogColorMode colorMode) {
|
|
SpdLogColorMode cm = SpdLogColorMode::automatic;
|
|
switch (colorMode)
|
|
{
|
|
case LogColorMode::automatic:
|
|
cm = SpdLogColorMode::automatic;
|
|
break;
|
|
case LogColorMode::always:
|
|
cm = SpdLogColorMode::always;
|
|
break;
|
|
case LogColorMode::never:
|
|
cm = SpdLogColorMode::never;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return cm;
|
|
}
|
|
};
|
|
|
|
class ConsoleLoggerSink::Impl {
|
|
private:
|
|
public:
|
|
// spdlog sink
|
|
std::shared_ptr<spdlog::sinks::stdout_color_sink_mt> m_sink;
|
|
Impl(LogColorMode colorMode = LogColorMode::automatic)
|
|
: m_sink(std::make_shared<spdlog::sinks::stdout_color_sink_mt>()) {
|
|
SpdLogUtils::SpdLogColorMode cm = SpdLogUtils::logColorModeToSpdLogColorMode(colorMode);
|
|
m_sink->set_color_mode(cm);
|
|
}
|
|
operator spdlog::sinks::sink& () {
|
|
return *m_sink;
|
|
}
|
|
};
|
|
|
|
ConsoleLoggerSink::ConsoleLoggerSink(const std::string& name, LogColorMode colorMode)
|
|
: pImpl(std::make_unique<Impl>(colorMode)), m_colorMode(colorMode) {}
|
|
std::any ConsoleLoggerSink::getBaseSink()
|
|
{
|
|
return std::any(pImpl->m_sink);
|
|
}
|
|
void ConsoleLoggerSink::flush() noexcept(false) {
|
|
pImpl->m_sink->flush();
|
|
}
|
|
void ConsoleLoggerSink::setPattern(const std::string& pattern) {
|
|
|
|
if (pImpl->m_sink)
|
|
{
|
|
try {
|
|
pImpl->m_sink->set_pattern(pattern);
|
|
m_pattern = pattern;
|
|
}
|
|
catch (const spdlog::spdlog_ex& ex)
|
|
{
|
|
throw LoggerException(LoggerErrorCode::PatternSetFailed, "Failed to set log pattern: " + std::string(ex.what()));
|
|
}
|
|
}
|
|
else
|
|
throw LoggerException(LoggerErrorCode::SinkNotInitialized, "Sink is not initialized.");
|
|
}
|
|
std::string ConsoleLoggerSink::pattern() const {
|
|
return m_pattern;
|
|
}
|
|
void ConsoleLoggerSink::setLevel(LogLevel level) {
|
|
if (pImpl->m_sink)
|
|
{
|
|
pImpl->m_sink->set_level(static_cast<spdlog::level::level_enum>(SpdLogUtils::logLevelToSpdLogLevel(level)));
|
|
m_level = level;
|
|
}
|
|
else
|
|
throw LoggerException(LoggerErrorCode::SinkNotInitialized, "Sink is not initialized.");
|
|
}
|
|
LogLevel ConsoleLoggerSink::level() const {
|
|
return m_level;
|
|
}
|
|
void ConsoleLoggerSink::setColorMode(LogColorMode colorMode) {
|
|
m_colorMode = colorMode;
|
|
}
|
|
void ConsoleLoggerSink::setColor(LogLevel level, LogColor colorCode) {
|
|
// 设置不同日志级别的颜色代码
|
|
if (pImpl->m_sink)
|
|
{
|
|
pImpl->m_sink->set_color(static_cast<spdlog::level::level_enum>(SpdLogUtils::logLevelToSpdLogLevel(level)), colorCode);
|
|
m_color = colorCode;
|
|
}
|
|
else
|
|
throw LoggerException(LoggerErrorCode::SinkNotInitialized, "Sink is not initialized.");
|
|
}
|
|
|
|
|
|
class FileLoggerSink::Impl {
|
|
private:
|
|
public:
|
|
// spdlog sink
|
|
std::shared_ptr<spdlog::sinks::basic_file_sink_mt> m_sink;
|
|
Impl(const std::string& filePath, bool truncate, FileEventHandler evh) {
|
|
spdlog::file_event_handlers feh;
|
|
feh.before_open = evh.beforeOpen;
|
|
feh.after_open = evh.afterOpen;
|
|
feh.before_close = evh.beforeClose;
|
|
feh.after_close = evh.afterClose;
|
|
m_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(filePath, truncate, feh);
|
|
}
|
|
operator spdlog::sinks::sink&() {
|
|
return *m_sink;
|
|
}
|
|
};
|
|
FileLoggerSink::FileLoggerSink(const std::string& name, bool truncate, FileEventHandler eventHandler)
|
|
: pImpl(std::make_unique<Impl>(name, truncate, eventHandler)) {}
|
|
std::any FileLoggerSink::getBaseSink()
|
|
{
|
|
return std::any(pImpl->m_sink);
|
|
}
|
|
void FileLoggerSink::flush() noexcept(false) {
|
|
pImpl->m_sink->flush();
|
|
}
|
|
void FileLoggerSink::setPattern(const std::string& pattern) {
|
|
if (pImpl->m_sink)
|
|
{
|
|
try {
|
|
pImpl->m_sink->set_pattern(pattern);
|
|
m_pattern = pattern;
|
|
}
|
|
catch (const spdlog::spdlog_ex& ex)
|
|
{
|
|
throw LoggerException(LoggerErrorCode::PatternSetFailed, "Failed to set log pattern: " + std::string(ex.what()));
|
|
}
|
|
}
|
|
else
|
|
throw LoggerException(LoggerErrorCode::SinkNotInitialized, "Sink is not initialized.");
|
|
}
|
|
std::string FileLoggerSink::pattern() const {
|
|
return m_pattern;
|
|
}
|
|
void FileLoggerSink::setLevel(LogLevel level) {
|
|
if (pImpl->m_sink)
|
|
{
|
|
pImpl->m_sink->set_level(static_cast<spdlog::level::level_enum>(SpdLogUtils::logLevelToSpdLogLevel(level)));
|
|
m_level = level;
|
|
}
|
|
else
|
|
throw LoggerException(LoggerErrorCode::SinkNotInitialized, "Sink is not initialized.");
|
|
}
|
|
LogLevel FileLoggerSink::level() const {
|
|
return m_level;
|
|
}
|
|
|
|
|
|
class Logger::LoggerImpl {
|
|
private:
|
|
public:
|
|
std::shared_ptr<spdlog::logger> logger;
|
|
LoggerImpl(const std::string& name) {
|
|
logger = spdlog::get(name);
|
|
if (!logger)
|
|
{
|
|
logger = spdlog::stdout_color_mt(name);
|
|
}
|
|
}
|
|
template <typename SinksIterator>
|
|
LoggerImpl(const std::string& name, SinksIterator&& begin, SinksIterator&& end) {
|
|
std::vector< std::shared_ptr<spdlog::sinks::sink>> sinks;
|
|
for (auto it = begin; it != end; ++it) {
|
|
auto sinkSharedPtr = (*it)->getBaseSink();
|
|
sinks.push_back(std::any_cast<std::shared_ptr<spdlog::sinks::sink>> (sinkSharedPtr));
|
|
}
|
|
logger = std::make_shared<spdlog::logger>(name, sinks.begin(), sinks.end());
|
|
if (logger)
|
|
spdlog::register_logger(logger);
|
|
}
|
|
~LoggerImpl() {
|
|
try {
|
|
logger->flush();
|
|
}
|
|
catch (...) {}
|
|
try {
|
|
spdlog::drop(logger->name());
|
|
}
|
|
catch (...) {}
|
|
}
|
|
|
|
};
|
|
|
|
Logger::Logger(const std::string &name) : pImpl(std::make_unique<Logger::LoggerImpl>(name))
|
|
{
|
|
}
|
|
template <typename SinksIterator>
|
|
Logger::Logger(const std::string& name, SinksIterator&& sinksBegin, SinksIterator&& sinksEnd)
|
|
: pImpl(std::make_unique<Logger::LoggerImpl>(name, std::forward<SinksIterator>(sinksBegin), std::forward<SinksIterator>(sinksEnd)))
|
|
{
|
|
|
|
}
|
|
|
|
Logger::~Logger()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
void Logger::setGlobalLevel(LogLevel level) noexcept(false)
|
|
{
|
|
SpdLogUtils::SpdLogLevel l = SpdLogUtils::logLevelToSpdLogLevel(level);
|
|
spdlog::set_level(static_cast<spdlog::level::level_enum>(l));
|
|
}
|
|
|
|
void Logger::setLevel(LogLevel level) noexcept(false)
|
|
{
|
|
if (pImpl->logger)
|
|
{
|
|
SpdLogUtils::SpdLogLevel l = SpdLogUtils::logLevelToSpdLogLevel(level);
|
|
pImpl->logger->set_level(static_cast<spdlog::level::level_enum>(l));
|
|
}
|
|
}
|
|
|
|
LogLevel Logger::level() const noexcept
|
|
{
|
|
//level::level_enum logger::level()
|
|
return SpdLogUtils::spdLogLevelToLogLevel(static_cast<SpdLogUtils::SpdLogLevel>(pImpl->logger->level()));
|
|
}
|
|
|
|
// 带参数日志打印
|
|
void Logger::trace(const std::string &msg) noexcept
|
|
{
|
|
if (pImpl->logger)
|
|
{
|
|
pImpl->logger->trace(msg);
|
|
}
|
|
}
|
|
|
|
void Logger::debug(const std::string &msg) noexcept
|
|
{
|
|
if (pImpl->logger)
|
|
{
|
|
pImpl->logger->debug(msg);
|
|
}
|
|
}
|
|
|
|
void Logger::info(const std::string &msg) noexcept
|
|
{
|
|
if (pImpl->logger)
|
|
{
|
|
pImpl->logger->info(msg);
|
|
}
|
|
}
|
|
|
|
void Logger::warning(const std::string &msg) noexcept
|
|
{
|
|
if (pImpl->logger)
|
|
{
|
|
pImpl->logger->warn(msg);
|
|
}
|
|
}
|
|
|
|
void Logger::error(const std::string &msg) noexcept
|
|
{
|
|
if (pImpl->logger)
|
|
{
|
|
pImpl->logger->error(msg);
|
|
}
|
|
}
|
|
|
|
void Logger::critical(const std::string &msg) noexcept
|
|
{
|
|
if (pImpl->logger)
|
|
{
|
|
pImpl->logger->critical(msg);
|
|
}
|
|
}
|
|
|