diff --git a/lib/CConsoleHandler.cpp b/lib/CConsoleHandler.cpp index 6648386ba..245032849 100644 --- a/lib/CConsoleHandler.cpp +++ b/lib/CConsoleHandler.cpp @@ -17,7 +17,7 @@ boost::mutex CConsoleHandler::smx; DLL_LINKAGE CConsoleHandler * console = nullptr; -#ifndef _WIN32 +#ifndef VCMI_WINDOWS typedef std::string TColor; #define CONSOLE_GREEN "\x1b[1;32m" #define CONSOLE_RED "\x1b[1;31m" @@ -36,6 +36,7 @@ DLL_LINKAGE CConsoleHandler * console = nullptr; typedef WORD TColor; HANDLE handleIn; HANDLE handleOut; + HANDLE handleErr; #define CONSOLE_GREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY #define CONSOLE_RED FOREGROUND_RED | FOREGROUND_INTENSITY #define CONSOLE_MAGENTA FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY @@ -43,6 +44,8 @@ DLL_LINKAGE CConsoleHandler * console = nullptr; #define CONSOLE_WHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY #define CONSOLE_GRAY FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE #define CONSOLE_TEAL FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY + + static TColor defErrColor; #endif static TColor defColor; @@ -178,8 +181,11 @@ void CConsoleHandler::setColor(EConsoleTextColor::EConsoleTextColor color) colorCode = defColor; break; } -#ifdef _WIN32 +#ifdef VCMI_WINDOWS SetConsoleTextAttribute(handleOut, colorCode); + if (color == EConsoleTextColor::DEFAULT) + colorCode = defErrColor; + SetConsoleTextAttribute(handleErr, colorCode); #else std::cout << colorCode; #endif @@ -219,9 +225,14 @@ CConsoleHandler::CConsoleHandler() : thread(nullptr) #ifdef _WIN32 handleIn = GetStdHandle(STD_INPUT_HANDLE); handleOut = GetStdHandle(STD_OUTPUT_HANDLE); + handleErr = GetStdHandle(STD_ERROR_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo(handleOut,&csbi); defColor = csbi.wAttributes; + + GetConsoleScreenBufferInfo(handleErr, &csbi); + defErrColor = csbi.wAttributes; #ifndef _DEBUG SetUnhandledExceptionFilter(onUnhandledException); #endif diff --git a/lib/logging/CBasicLogConfigurator.cpp b/lib/logging/CBasicLogConfigurator.cpp index 1d42c180d..df9c8df9d 100644 --- a/lib/logging/CBasicLogConfigurator.cpp +++ b/lib/logging/CBasicLogConfigurator.cpp @@ -12,8 +12,7 @@ CBasicLogConfigurator::CBasicLogConfigurator(boost::filesystem::path && file_pat void CBasicLogConfigurator::configureDefault() { CLogger::getGlobalLogger()->addTarget(make_unique(console)); - // TODO: CLogFileTarget should take boost::filesystem::path as an argument - CLogger::getGlobalLogger()->addTarget(make_unique(file_path.string(), appendToLogFile)); + CLogger::getGlobalLogger()->addTarget(make_unique(file_path, appendToLogFile)); appendToLogFile = true; } @@ -69,9 +68,8 @@ void CBasicLogConfigurator::configure() } CLogger::getGlobalLogger()->addTarget(std::move(consoleTarget)); - // TODO: CLogFileTarget should take boost::filesystem::path as an argument // Add file target - auto fileTarget = make_unique(file_path.string(), appendToLogFile); + auto fileTarget = make_unique(file_path, appendToLogFile); const JsonNode & fileNode = loggingNode["file"]; if(!fileNode.isNull()) { diff --git a/lib/logging/CLogger.cpp b/lib/logging/CLogger.cpp index 6832defa7..3478120e2 100644 --- a/lib/logging/CLogger.cpp +++ b/lib/logging/CLogger.cpp @@ -1,7 +1,3 @@ -#ifdef __ANDROID__ -#include -#endif - #include "StdInc.h" #include "CLogger.h" @@ -9,38 +5,31 @@ const std::string CLoggerDomain::DOMAIN_GLOBAL = "global"; CLoggerDomain::CLoggerDomain(const std::string & name) : name(name) { - if(name.empty()) throw std::runtime_error("Logger domain cannot be empty."); + if(name.empty()) + throw std::runtime_error("Logger domain cannot be empty."); +} +CLoggerDomain::CLoggerDomain(std::string && name) : name(std::move(name)) +{ + if (this->name.empty()) + throw std::runtime_error("Logger domain cannot be empty."); } CLoggerDomain CLoggerDomain::getParent() const { - if(isGlobalDomain()) return *this; + if(isGlobalDomain()) + return *this; - size_t pos = name.find_last_of("."); + const size_t pos = name.find_last_of("."); if(pos != std::string::npos) - { return CLoggerDomain(name.substr(0, pos)); - } - else - { - return CLoggerDomain(DOMAIN_GLOBAL); - } + return CLoggerDomain(DOMAIN_GLOBAL); } -bool CLoggerDomain::isGlobalDomain() const -{ - return name == DOMAIN_GLOBAL; -} +bool CLoggerDomain::isGlobalDomain() const { return name == DOMAIN_GLOBAL; } -std::string CLoggerDomain::getName() const -{ - return name; -} +const std::string& CLoggerDomain::getName() const { return name; } -CLoggerStream::CLoggerStream(const CLogger & logger, ELogLevel::ELogLevel level) : logger(logger), level(level), sbuffer(nullptr) -{ - -} +CLoggerStream::CLoggerStream(const CLogger & logger, ELogLevel::ELogLevel level) : logger(logger), level(level), sbuffer(nullptr) {} CLoggerStream::~CLoggerStream() { @@ -67,20 +56,14 @@ CLogger * CLogger::getLogger(const CLoggerDomain & domain) TLockGuardRec _(smx); CLogger * logger = CLogManager::get().getLogger(domain); - if(logger) - { - return logger; - } - else + if(!logger) // Create new logger { logger = new CLogger(domain); if(domain.isGlobalDomain()) - { logger->setLevel(ELogLevel::TRACE); - } CLogManager::get().addLogger(logger); - return logger; } + return logger; } CLogger * CLogger::getGlobalLogger() @@ -102,62 +85,22 @@ CLogger::CLogger(const CLoggerDomain & domain) : domain(domain) } } -void CLogger::trace(const std::string & message) const -{ - log(ELogLevel::TRACE, message); -} +void CLogger::trace(const std::string & message) const { log(ELogLevel::TRACE, message); } +void CLogger::debug(const std::string & message) const { log(ELogLevel::DEBUG, message); } +void CLogger::info(const std::string & message) const { log(ELogLevel::INFO, message); } +void CLogger::warn(const std::string & message) const { log(ELogLevel::WARN, message); } +void CLogger::error(const std::string & message) const { log(ELogLevel::ERROR, message); } -CLoggerStream CLogger::traceStream() const -{ - return CLoggerStream(*this, ELogLevel::TRACE); -} - -void CLogger::debug(const std::string & message) const -{ - log(ELogLevel::DEBUG, message); -} - -CLoggerStream CLogger::debugStream() const -{ - return CLoggerStream(*this, ELogLevel::DEBUG); -} - -void CLogger::info(const std::string & message) const -{ - log(ELogLevel::INFO, message); -} - -CLoggerStream CLogger::infoStream() const -{ - return CLoggerStream(*this, ELogLevel::INFO); -} - -void CLogger::warn(const std::string & message) const -{ - log(ELogLevel::WARN, message); -} - -CLoggerStream CLogger::warnStream() const -{ - return CLoggerStream(*this, ELogLevel::WARN); -} - -void CLogger::error(const std::string & message) const -{ - log(ELogLevel::ERROR, message); -} - -CLoggerStream CLogger::errorStream() const -{ - return CLoggerStream(*this, ELogLevel::ERROR); -} +CLoggerStream CLogger::traceStream() const { return CLoggerStream(*this, ELogLevel::TRACE); } +CLoggerStream CLogger::debugStream() const { return CLoggerStream(*this, ELogLevel::DEBUG); } +CLoggerStream CLogger::infoStream() const { return CLoggerStream(*this, ELogLevel::INFO); } +CLoggerStream CLogger::warnStream() const { return CLoggerStream(*this, ELogLevel::WARN); } +CLoggerStream CLogger::errorStream() const { return CLoggerStream(*this, ELogLevel::ERROR); } void CLogger::log(ELogLevel::ELogLevel level, const std::string & message) const { if(getEffectiveLevel() <= level) - { callTargets(LogRecord(domain, level, message)); - } } ELogLevel::ELogLevel CLogger::getLevel() const @@ -169,14 +112,11 @@ ELogLevel::ELogLevel CLogger::getLevel() const void CLogger::setLevel(ELogLevel::ELogLevel level) { TLockGuard _(mx); - if(domain.isGlobalDomain() && level == ELogLevel::NOT_SET) return; - this->level = level; + if (!domain.isGlobalDomain() || level != ELogLevel::NOT_SET) + this->level = level; } -const CLoggerDomain & CLogger::getDomain() const -{ - return domain; -} +const CLoggerDomain & CLogger::getDomain() const { return domain; } void CLogger::addTarget(unique_ptr && target) { @@ -187,9 +127,8 @@ void CLogger::addTarget(unique_ptr && target) ELogLevel::ELogLevel CLogger::getEffectiveLevel() const { for(const CLogger * logger = this; logger != nullptr; logger = logger->parent) - { - if(logger->getLevel() != ELogLevel::NOT_SET) return logger->getLevel(); - } + if(logger->getLevel() != ELogLevel::NOT_SET) + return logger->getLevel(); // This shouldn't be reached, as the root logger must have set a log level return ELogLevel::INFO; @@ -199,12 +138,8 @@ void CLogger::callTargets(const LogRecord & record) const { TLockGuard _(mx); for(const CLogger * logger = this; logger != nullptr; logger = logger->parent) - { for(auto & target : logger->targets) - { target->write(record); - } - } } void CLogger::clearTargets() @@ -213,26 +148,15 @@ void CLogger::clearTargets() targets.clear(); } -bool CLogger::isDebugEnabled() const -{ - return getEffectiveLevel() <= ELogLevel::DEBUG; -} - -bool CLogger::isTraceEnabled() const -{ - return getEffectiveLevel() <= ELogLevel::TRACE; -} +bool CLogger::isDebugEnabled() const { return getEffectiveLevel() <= ELogLevel::DEBUG; } +bool CLogger::isTraceEnabled() const { return getEffectiveLevel() <= ELogLevel::TRACE; } CTraceLogger::CTraceLogger(const CLogger * logger, const std::string & beginMessage, const std::string & endMessage) : logger(logger), endMessage(endMessage) { - logger->traceStream() << beginMessage; -} - -CTraceLogger::~CTraceLogger() -{ - logger->traceStream() << endMessage; + logger->trace(beginMessage); } +CTraceLogger::~CTraceLogger() { logger->trace(std::move(endMessage)); } CLogManager & CLogManager::get() { @@ -241,17 +165,11 @@ CLogManager & CLogManager::get() return instance; } -CLogManager::CLogManager() -{ - -} - +CLogManager::CLogManager() { } CLogManager::~CLogManager() { for(auto & i : loggers) - { delete i.second; - } } void CLogManager::addLogger(CLogger * logger) @@ -265,34 +183,30 @@ CLogger * CLogManager::getLogger(const CLoggerDomain & domain) TLockGuard _(mx); auto it = loggers.find(domain.getName()); if(it != loggers.end()) - { return it->second; - } else - { return nullptr; - } } -CLogFormatter::CLogFormatter() : pattern("%m") +CLogFormatter::CLogFormatter() : CLogFormatter("%m") { } + +CLogFormatter::CLogFormatter(const std::string & pattern) : pattern(pattern) { boost::posix_time::time_facet * facet = new boost::posix_time::time_facet("%H:%M:%S"); dateStream.imbue(std::locale(dateStream.getloc(), facet)); } -CLogFormatter::CLogFormatter(const std::string & pattern) -{ - setPattern(pattern); -} +CLogFormatter::CLogFormatter(const CLogFormatter & c) : pattern(c.pattern) { } +CLogFormatter::CLogFormatter(CLogFormatter && m) : pattern(std::move(m.pattern)) { } -CLogFormatter::CLogFormatter(const CLogFormatter & other) +CLogFormatter & CLogFormatter::operator=(const CLogFormatter & c) { - *this = other; + pattern = c.pattern; + return *this; } - -CLogFormatter & CLogFormatter::operator=(const CLogFormatter & other) +CLogFormatter & CLogFormatter::operator=(CLogFormatter && m) { - pattern = other.pattern; + pattern = std::move(m.pattern); return *this; } @@ -336,15 +250,10 @@ std::string CLogFormatter::format(const LogRecord & record) const return message; } -void CLogFormatter::setPattern(const std::string & pattern) -{ - this->pattern = pattern; -} +void CLogFormatter::setPattern(const std::string & pattern) { this->pattern = pattern; } +void CLogFormatter::setPattern(std::string && pattern) { this->pattern = std::move(pattern); } -const std::string & CLogFormatter::getPattern() const -{ - return pattern; -} +const std::string & CLogFormatter::getPattern() const { return pattern; } CColorMapping::CColorMapping() { @@ -365,30 +274,24 @@ void CColorMapping::setColorFor(const CLoggerDomain & domain, ELogLevel::ELogLev EConsoleTextColor::EConsoleTextColor CColorMapping::getColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level) const { - std::string name = domain.getName(); + CLoggerDomain currentDomain = domain; while(true) { - const auto & loggerPair = map.find(name); + const auto & loggerPair = map.find(currentDomain.getName()); if(loggerPair != map.end()) { const auto & levelMap = loggerPair->second; const auto & levelPair = levelMap.find(level); if(levelPair != levelMap.end()) - { return levelPair->second; - } } - CLoggerDomain currentDomain(name); - if(!currentDomain.isGlobalDomain()) - { - name = currentDomain.getParent().getName(); - } - else - { + if (currentDomain.isGlobalDomain()) break; - } + + currentDomain = currentDomain.getParent(); } + throw std::runtime_error("failed to find color for requested domain/level pair"); } @@ -403,78 +306,47 @@ void CLogConsoleTarget::write(const LogRecord & record) std::string message = formatter.format(record); -#ifdef __ANDROID__ +#ifdef VCMI_ANDROID __android_log_print(ANDROID_LOG_INFO, "VCMI", "%s", message.c_str()); #endif bool printToStdErr = record.level >= ELogLevel::WARN; if(console) { - if(coloredOutputEnabled) - { - console->print(message, true, colorMapping.getColorFor(record.domain, record.level)); - } - else - { - console->print(message, true, EConsoleTextColor::DEFAULT, printToStdErr); - } + const EConsoleTextColor::EConsoleTextColor textColor = + coloredOutputEnabled ? colorMapping.getColorFor(record.domain, record.level) : EConsoleTextColor::DEFAULT; + + console->print(message, true, textColor, printToStdErr); } else { TLockGuard _(mx); if(printToStdErr) - { std::cerr << message << std::endl; - } else - { std::cout << message << std::endl; - } } } -bool CLogConsoleTarget::isColoredOutputEnabled() const -{ - return coloredOutputEnabled; -} +bool CLogConsoleTarget::isColoredOutputEnabled() const { return coloredOutputEnabled; } +void CLogConsoleTarget::setColoredOutputEnabled(bool coloredOutputEnabled) { this->coloredOutputEnabled = coloredOutputEnabled; } -void CLogConsoleTarget::setColoredOutputEnabled(bool coloredOutputEnabled) -{ - this->coloredOutputEnabled = coloredOutputEnabled; -} +ELogLevel::ELogLevel CLogConsoleTarget::getThreshold() const { return threshold; } +void CLogConsoleTarget::setThreshold(ELogLevel::ELogLevel threshold) { this->threshold = threshold; } -ELogLevel::ELogLevel CLogConsoleTarget::getThreshold() const -{ - return threshold; -} +const CLogFormatter & CLogConsoleTarget::getFormatter() const { return formatter; } +void CLogConsoleTarget::setFormatter(const CLogFormatter & formatter) { this->formatter = formatter; } -void CLogConsoleTarget::setThreshold(ELogLevel::ELogLevel threshold) -{ - this->threshold = threshold; -} +const CColorMapping & CLogConsoleTarget::getColorMapping() const { return colorMapping; } +void CLogConsoleTarget::setColorMapping(const CColorMapping & colorMapping) { this->colorMapping = colorMapping; } -const CLogFormatter & CLogConsoleTarget::getFormatter() const +CLogFileTarget::CLogFileTarget(const boost::filesystem::path & file_path, bool append /*= true*/) + : file(file_path, append ? std::ios_base::app : std::ios_base::out) { - return formatter; + formatter.setPattern("%d %l %n [%t] - %m"); } - -void CLogConsoleTarget::setFormatter(const CLogFormatter & formatter) -{ - this->formatter = formatter; -} - -const CColorMapping & CLogConsoleTarget::getColorMapping() const -{ - return colorMapping; -} - -void CLogConsoleTarget::setColorMapping(const CColorMapping & colorMapping) -{ - this->colorMapping = colorMapping; -} - -CLogFileTarget::CLogFileTarget(const std::string & filePath, bool append /*= true*/) - : file(filePath, append ? std::ios_base::app : std::ios_base::out) +CLogFileTarget::CLogFileTarget(boost::filesystem::path && file_path, bool append /*= true*/) + : file(std::move(file_path), append ? std::ios_base::app : std::ios_base::out) { formatter.setPattern("%d %l %n [%t] - %m"); } @@ -490,12 +362,5 @@ void CLogFileTarget::write(const LogRecord & record) file << formatter.format(record) << std::endl; } -const CLogFormatter & CLogFileTarget::getFormatter() const -{ - return formatter; -} - -void CLogFileTarget::setFormatter(const CLogFormatter & formatter) -{ - this->formatter = formatter; -} +const CLogFormatter & CLogFileTarget::getFormatter() const { return formatter; } +void CLogFileTarget::setFormatter(const CLogFormatter & formatter) { this->formatter = formatter; } \ No newline at end of file diff --git a/lib/logging/CLogger.h b/lib/logging/CLogger.h index 9e5afe2db..77943e5b9 100644 --- a/lib/logging/CLogger.h +++ b/lib/logging/CLogger.h @@ -37,8 +37,9 @@ public: /// Constructs a CLoggerDomain with the domain designated by name. /// Sub-domains can be specified by separating domains by a dot, e.g. "ai.battle". The global domain is named "global". explicit CLoggerDomain(const std::string & name); + explicit CLoggerDomain(std::string && name); - std::string getName() const; + const std::string& getName() const; CLoggerDomain getParent() const; bool isGlobalDomain() const; @@ -58,8 +59,11 @@ public: template CLoggerStream & operator<<(const T & data) { - if(!sbuffer) sbuffer = new std::stringstream(); + if(!sbuffer) + sbuffer = new std::stringstream(std::ios_base::out); + (*sbuffer) << data; + return *this; } @@ -84,18 +88,16 @@ public: /// Log methods for various log levels void trace(const std::string & message) const; - CLoggerStream traceStream() const; - void debug(const std::string & message) const; - CLoggerStream debugStream() const; - void info(const std::string & message) const; - CLoggerStream infoStream() const; - void warn(const std::string & message) const; - CLoggerStream warnStream() const; - void error(const std::string & message) const; + + /// Log streams for various log levels + CLoggerStream traceStream() const; + CLoggerStream debugStream() const; + CLoggerStream infoStream() const; + CLoggerStream warnStream() const; CLoggerStream errorStream() const; inline void log(ELogLevel::ELogLevel level, const std::string & message) const; @@ -184,10 +186,7 @@ struct DLL_LINKAGE LogRecord { LogRecord(const CLoggerDomain & domain, ELogLevel::ELogLevel level, const std::string & message) : domain(domain), level(level), message(message), timeStamp(boost::posix_time::second_clock::local_time()), - threadId(boost::this_thread::get_id()) - { - - } + threadId(boost::this_thread::get_id()) { } CLoggerDomain domain; ELogLevel::ELogLevel level; @@ -208,12 +207,17 @@ class DLL_LINKAGE CLogFormatter { public: CLogFormatter(); - CLogFormatter(const std::string & pattern); + CLogFormatter(const CLogFormatter & copy); + CLogFormatter(CLogFormatter && move); - CLogFormatter(const CLogFormatter & other); - CLogFormatter & operator=(const CLogFormatter & other); + CLogFormatter(const std::string & pattern); + + CLogFormatter & operator=(const CLogFormatter & copy); + CLogFormatter & operator=(CLogFormatter && move); void setPattern(const std::string & pattern); + void setPattern(std::string && pattern); + const std::string & getPattern() const; std::string format(const LogRecord & record) const; @@ -282,9 +286,10 @@ private: class DLL_LINKAGE CLogFileTarget : public ILogTarget { public: - /// Constructs a CLogFileTarget and opens the file designated by filePath. If the append parameter is true, the file + /// Constructs a CLogFileTarget and opens the file designated by file_path. If the append parameter is true, the file /// will be appended to. Otherwise the file designated by filePath will be truncated before being opened. - explicit CLogFileTarget(const std::string & filePath, bool append = true); + explicit CLogFileTarget(const boost::filesystem::path & file_path, bool append = true); + explicit CLogFileTarget(boost::filesystem::path && file_path, bool append = true); ~CLogFileTarget(); const CLogFormatter & getFormatter() const; @@ -293,7 +298,7 @@ public: void write(const LogRecord & record) override; private: - std::ofstream file; + boost::filesystem::ofstream file; CLogFormatter formatter; mutable boost::mutex mx; }; diff --git a/lib/mapObjects/CArmedInstance.h b/lib/mapObjects/CArmedInstance.h index 9b58332ca..0ebe2abc1 100644 --- a/lib/mapObjects/CArmedInstance.h +++ b/lib/mapObjects/CArmedInstance.h @@ -13,7 +13,7 @@ * */ -class BattleInfo; +struct BattleInfo; class CGameState; class DLL_LINKAGE CArmedInstance: public CGObjectInstance, public CBonusSystemNode, public CCreatureSet diff --git a/lib/mapObjects/CBank.h b/lib/mapObjects/CBank.h index cfecdf20c..59b954116 100644 --- a/lib/mapObjects/CBank.h +++ b/lib/mapObjects/CBank.h @@ -13,7 +13,7 @@ * */ -class BankConfig; +struct BankConfig; class CBankInstanceConstructor; class DLL_LINKAGE CBank : public CArmedInstance diff --git a/lib/mapObjects/CGHeroInstance.h b/lib/mapObjects/CGHeroInstance.h index 9f811c4b2..69c65cd06 100644 --- a/lib/mapObjects/CGHeroInstance.h +++ b/lib/mapObjects/CGHeroInstance.h @@ -19,7 +19,7 @@ class CHero; class CGBoat; class CGTownInstance; -class TerrainTile; +struct TerrainTile; class CGHeroPlaceholder : public CGObjectInstance { diff --git a/lib/mapObjects/CGPandoraBox.h b/lib/mapObjects/CGPandoraBox.h index c2ad87dde..974351b83 100644 --- a/lib/mapObjects/CGPandoraBox.h +++ b/lib/mapObjects/CGPandoraBox.h @@ -14,7 +14,7 @@ * */ -class InfoWindow; +struct InfoWindow; class DLL_LINKAGE CGPandoraBox : public CArmedInstance { diff --git a/lib/mapObjects/CObjectHandler.h b/lib/mapObjects/CObjectHandler.h index 0b27d759e..adc71b3d1 100644 --- a/lib/mapObjects/CObjectHandler.h +++ b/lib/mapObjects/CObjectHandler.h @@ -19,7 +19,7 @@ class CGHeroInstance; class IGameCallback; class CGObjectInstance; -class MetaString; +struct MetaString; struct BattleResult; class DLL_LINKAGE IObjectInterface