1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

- Fixed indentation for various files, sorry...

This commit is contained in:
beegee1 2013-04-14 19:24:31 +00:00
parent c10266ed97
commit 44bde4a1d3
10 changed files with 717 additions and 717 deletions

View File

@ -4,126 +4,126 @@
#include "../CConfigHandler.h"
CBasicLogConfigurator::CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console) : filePath(filePath),
console(console), appendToLogFile(false)
console(console), appendToLogFile(false)
{
}
void CBasicLogConfigurator::configureDefault()
{
CLogger::getGlobalLogger()->addTarget(make_unique<CLogConsoleTarget>(console));
CLogger::getGlobalLogger()->addTarget(make_unique<CLogFileTarget>(filePath, appendToLogFile));
appendToLogFile = true;
CLogger::getGlobalLogger()->addTarget(make_unique<CLogConsoleTarget>(console));
CLogger::getGlobalLogger()->addTarget(make_unique<CLogFileTarget>(filePath, appendToLogFile));
appendToLogFile = true;
}
void CBasicLogConfigurator::configure()
{
try
{
const JsonNode & loggingNode = settings["logging"];
if(loggingNode.isNull()) throw std::runtime_error("Settings haven't been loaded.");
try
{
const JsonNode & loggingNode = settings["logging"];
if(loggingNode.isNull()) throw std::runtime_error("Settings haven't been loaded.");
// Configure loggers
const JsonNode & loggers = loggingNode["loggers"];
if(!loggers.isNull())
{
BOOST_FOREACH(auto & loggerNode, loggers.Vector())
{
// Get logger
std::string name = loggerNode["domain"].String();
CLogger * logger = CLogger::getLogger(CLoggerDomain(name));
// Configure loggers
const JsonNode & loggers = loggingNode["loggers"];
if(!loggers.isNull())
{
BOOST_FOREACH(auto & loggerNode, loggers.Vector())
{
// Get logger
std::string name = loggerNode["domain"].String();
CLogger * logger = CLogger::getLogger(CLoggerDomain(name));
// Set log level
logger->setLevel(getLogLevel(loggerNode["level"].String()));
}
}
CLogger::getGlobalLogger()->clearTargets();
// Set log level
logger->setLevel(getLogLevel(loggerNode["level"].String()));
}
}
CLogger::getGlobalLogger()->clearTargets();
// Add console target
auto consoleTarget = make_unique<CLogConsoleTarget>(console);
const JsonNode & consoleNode = loggingNode["console"];
if(!consoleNode.isNull())
{
const JsonNode & consoleFormatNode = consoleNode["format"];
if(!consoleFormatNode.isNull()) consoleTarget->setFormatter(CLogFormatter(consoleFormatNode.String()));
const JsonNode & consoleThresholdNode = consoleNode["threshold"];
if(!consoleThresholdNode.isNull()) consoleTarget->setThreshold(getLogLevel(consoleThresholdNode.String()));
const JsonNode & coloredConsoleEnabledNode = consoleNode["coloredOutputEnabled"];
consoleTarget->setColoredOutputEnabled(coloredConsoleEnabledNode.Bool());
// Add console target
auto consoleTarget = make_unique<CLogConsoleTarget>(console);
const JsonNode & consoleNode = loggingNode["console"];
if(!consoleNode.isNull())
{
const JsonNode & consoleFormatNode = consoleNode["format"];
if(!consoleFormatNode.isNull()) consoleTarget->setFormatter(CLogFormatter(consoleFormatNode.String()));
const JsonNode & consoleThresholdNode = consoleNode["threshold"];
if(!consoleThresholdNode.isNull()) consoleTarget->setThreshold(getLogLevel(consoleThresholdNode.String()));
const JsonNode & coloredConsoleEnabledNode = consoleNode["coloredOutputEnabled"];
consoleTarget->setColoredOutputEnabled(coloredConsoleEnabledNode.Bool());
CColorMapping colorMapping;
const JsonNode & colorMappingNode = consoleNode["colorMapping"];
if(!colorMappingNode.isNull())
{
BOOST_FOREACH(const JsonNode & mappingNode, colorMappingNode.Vector())
{
std::string domain = mappingNode["domain"].String();
std::string level = mappingNode["level"].String();
std::string color = mappingNode["color"].String();
colorMapping.setColorFor(CLoggerDomain(domain), getLogLevel(level), getConsoleColor(color));
}
}
consoleTarget->setColorMapping(colorMapping);
}
CLogger::getGlobalLogger()->addTarget(std::move(consoleTarget));
CColorMapping colorMapping;
const JsonNode & colorMappingNode = consoleNode["colorMapping"];
if(!colorMappingNode.isNull())
{
BOOST_FOREACH(const JsonNode & mappingNode, colorMappingNode.Vector())
{
std::string domain = mappingNode["domain"].String();
std::string level = mappingNode["level"].String();
std::string color = mappingNode["color"].String();
colorMapping.setColorFor(CLoggerDomain(domain), getLogLevel(level), getConsoleColor(color));
}
}
consoleTarget->setColorMapping(colorMapping);
}
CLogger::getGlobalLogger()->addTarget(std::move(consoleTarget));
// Add file target
auto fileTarget = make_unique<CLogFileTarget>(filePath, appendToLogFile);
const JsonNode & fileNode = loggingNode["file"];
if(!fileNode.isNull())
{
const JsonNode & fileFormatNode = fileNode["format"];
if(!fileFormatNode.isNull()) fileTarget->setFormatter(CLogFormatter(fileFormatNode.String()));
}
CLogger::getGlobalLogger()->addTarget(std::move(fileTarget));
appendToLogFile = true;
}
catch(const std::exception & e)
{
logGlobal->errorStream() << "Could not initialize the logging system due to configuration error/s."
<< "The logging system can be in a corrupted state. " << e.what();
}
// Add file target
auto fileTarget = make_unique<CLogFileTarget>(filePath, appendToLogFile);
const JsonNode & fileNode = loggingNode["file"];
if(!fileNode.isNull())
{
const JsonNode & fileFormatNode = fileNode["format"];
if(!fileFormatNode.isNull()) fileTarget->setFormatter(CLogFormatter(fileFormatNode.String()));
}
CLogger::getGlobalLogger()->addTarget(std::move(fileTarget));
appendToLogFile = true;
}
catch(const std::exception & e)
{
logGlobal->errorStream() << "Could not initialize the logging system due to configuration error/s."
<< "The logging system can be in a corrupted state. " << e.what();
}
logGlobal->infoStream() << "Initialized logging system based on settings successfully.";
logGlobal->infoStream() << "Initialized logging system based on settings successfully.";
}
ELogLevel::ELogLevel CBasicLogConfigurator::getLogLevel(const std::string & level) const
{
static const std::map<std::string, ELogLevel::ELogLevel> levelMap = boost::assign::map_list_of
("trace", ELogLevel::TRACE)
("debug", ELogLevel::DEBUG)
("info", ELogLevel::INFO)
("warn", ELogLevel::WARN)
("error", ELogLevel::ERROR);
const auto & levelPair = levelMap.find(level);
if(levelPair != levelMap.end())
{
return levelPair->second;
}
else
{
throw std::runtime_error("Log level " + level + " unknown.");
}
static const std::map<std::string, ELogLevel::ELogLevel> levelMap = boost::assign::map_list_of
("trace", ELogLevel::TRACE)
("debug", ELogLevel::DEBUG)
("info", ELogLevel::INFO)
("warn", ELogLevel::WARN)
("error", ELogLevel::ERROR);
const auto & levelPair = levelMap.find(level);
if(levelPair != levelMap.end())
{
return levelPair->second;
}
else
{
throw std::runtime_error("Log level " + level + " unknown.");
}
}
EConsoleTextColor::EConsoleTextColor CBasicLogConfigurator::getConsoleColor(const std::string & colorName) const
{
static const std::map<std::string, EConsoleTextColor::EConsoleTextColor> colorMap = boost::assign::map_list_of
("default", EConsoleTextColor::DEFAULT)
("green", EConsoleTextColor::GREEN)
("red", EConsoleTextColor::RED)
("magenta", EConsoleTextColor::MAGENTA)
("yellow", EConsoleTextColor::YELLOW)
("white", EConsoleTextColor::WHITE)
("gray", EConsoleTextColor::GRAY)
("teal", EConsoleTextColor::TEAL);
const auto & colorPair = colorMap.find(colorName);
if(colorPair != colorMap.end())
{
return colorPair->second;
}
else
{
throw std::runtime_error("Color " + colorName + " unknown.");
}
static const std::map<std::string, EConsoleTextColor::EConsoleTextColor> colorMap = boost::assign::map_list_of
("default", EConsoleTextColor::DEFAULT)
("green", EConsoleTextColor::GREEN)
("red", EConsoleTextColor::RED)
("magenta", EConsoleTextColor::MAGENTA)
("yellow", EConsoleTextColor::YELLOW)
("white", EConsoleTextColor::WHITE)
("gray", EConsoleTextColor::GRAY)
("teal", EConsoleTextColor::TEAL);
const auto & colorPair = colorMap.find(colorName);
if(colorPair != colorMap.end())
{
return colorPair->second;
}
else
{
throw std::runtime_error("Color " + colorName + " unknown.");
}
}

View File

@ -22,20 +22,20 @@ class JsonNode;
class DLL_LINKAGE CBasicLogConfigurator
{
public:
CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console);
CBasicLogConfigurator(const std::string & filePath, CConsoleHandler * console);
/// Configures the logging system by parsing the logging settings. It adds the console target and the file target to the global logger.
/// Doesn't throw, but logs on success or fault.
void configure();
/// Configures the logging system by parsing the logging settings. It adds the console target and the file target to the global logger.
/// Doesn't throw, but logs on success or fault.
void configure();
/// Configures a default logging system by adding the console target and the file target to the global logger.
void configureDefault();
/// Configures a default logging system by adding the console target and the file target to the global logger.
void configureDefault();
private:
ELogLevel::ELogLevel getLogLevel(const std::string & level) const;
EConsoleTextColor::EConsoleTextColor getConsoleColor(const std::string & colorName) const;
ELogLevel::ELogLevel getLogLevel(const std::string & level) const;
EConsoleTextColor::EConsoleTextColor getConsoleColor(const std::string & colorName) const;
std::string filePath;
CConsoleHandler * console;
bool appendToLogFile;
std::string filePath;
CConsoleHandler * console;
bool appendToLogFile;
};

View File

@ -5,32 +5,32 @@ 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::getParent() const
{
if(isGlobalDomain()) return *this;
if(isGlobalDomain()) return *this;
size_t pos = name.find_last_of(".");
if(pos != std::string::npos)
{
return CLoggerDomain(name.substr(0, pos));
}
else
{
return CLoggerDomain(DOMAIN_GLOBAL);
}
size_t pos = name.find_last_of(".");
if(pos != std::string::npos)
{
return CLoggerDomain(name.substr(0, pos));
}
else
{
return CLoggerDomain(DOMAIN_GLOBAL);
}
}
bool CLoggerDomain::isGlobalDomain() const
{
return name == DOMAIN_GLOBAL;
return name == DOMAIN_GLOBAL;
}
std::string CLoggerDomain::getName() const
{
return name;
return name;
}
CLoggerStream::CLoggerStream(const CLogger & logger, ELogLevel::ELogLevel level) : logger(logger), level(level), sbuffer(nullptr)
@ -40,12 +40,12 @@ CLoggerStream::CLoggerStream(const CLogger & logger, ELogLevel::ELogLevel level)
CLoggerStream::~CLoggerStream()
{
if(sbuffer)
{
logger.log(level, sbuffer->str());
delete sbuffer;
sbuffer = nullptr;
}
if(sbuffer)
{
logger.log(level, sbuffer->str());
delete sbuffer;
sbuffer = nullptr;
}
}
boost::recursive_mutex CLogger::smx;
@ -60,172 +60,172 @@ DLL_LINKAGE CLogger * logAi = CLogger::getLogger(CLoggerDomain("ai"));
CLogger * CLogger::getLogger(const CLoggerDomain & domain)
{
boost::lock_guard<boost::recursive_mutex> _(smx);
boost::lock_guard<boost::recursive_mutex> _(smx);
CLogger * logger = CLogManager::get().getLogger(domain);
if(logger)
{
return logger;
}
else
{
if(logger)
{
return logger;
}
else
{
logger = new CLogger(domain);
if(domain.isGlobalDomain())
{
logger->setLevel(ELogLevel::INFO);
}
CLogManager::get().addLogger(logger);
return logger;
}
if(domain.isGlobalDomain())
{
logger->setLevel(ELogLevel::INFO);
}
CLogManager::get().addLogger(logger);
return logger;
}
}
CLogger * CLogger::getGlobalLogger()
{
return getLogger(CLoggerDomain(CLoggerDomain::DOMAIN_GLOBAL));
return getLogger(CLoggerDomain(CLoggerDomain::DOMAIN_GLOBAL));
}
CLogger::CLogger(const CLoggerDomain & domain) : domain(domain)
{
if(domain.isGlobalDomain())
{
level = ELogLevel::INFO;
parent = nullptr;
}
else
{
level = ELogLevel::NOT_SET;
parent = getLogger(domain.getParent());
}
if(domain.isGlobalDomain())
{
level = ELogLevel::INFO;
parent = nullptr;
}
else
{
level = ELogLevel::NOT_SET;
parent = getLogger(domain.getParent());
}
}
void CLogger::trace(const std::string & message) const
{
log(ELogLevel::TRACE, message);
log(ELogLevel::TRACE, message);
}
CLoggerStream CLogger::traceStream() const
{
return CLoggerStream(*this, ELogLevel::TRACE);
return CLoggerStream(*this, ELogLevel::TRACE);
}
void CLogger::debug(const std::string & message) const
{
log(ELogLevel::DEBUG, message);
log(ELogLevel::DEBUG, message);
}
CLoggerStream CLogger::debugStream() const
{
return CLoggerStream(*this, ELogLevel::DEBUG);
return CLoggerStream(*this, ELogLevel::DEBUG);
}
void CLogger::info(const std::string & message) const
{
log(ELogLevel::INFO, message);
log(ELogLevel::INFO, message);
}
CLoggerStream CLogger::infoStream() const
{
return CLoggerStream(*this, ELogLevel::INFO);
return CLoggerStream(*this, ELogLevel::INFO);
}
void CLogger::warn(const std::string & message) const
{
log(ELogLevel::WARN, message);
log(ELogLevel::WARN, message);
}
CLoggerStream CLogger::warnStream() const
{
return CLoggerStream(*this, ELogLevel::WARN);
return CLoggerStream(*this, ELogLevel::WARN);
}
void CLogger::error(const std::string & message) const
{
log(ELogLevel::ERROR, message);
log(ELogLevel::ERROR, message);
}
CLoggerStream CLogger::errorStream() const
{
return CLoggerStream(*this, ELogLevel::ERROR);
return CLoggerStream(*this, ELogLevel::ERROR);
}
void CLogger::log(ELogLevel::ELogLevel level, const std::string & message) const
{
if(getEffectiveLevel() <= level)
{
callTargets(LogRecord(domain, level, message));
}
if(getEffectiveLevel() <= level)
{
callTargets(LogRecord(domain, level, message));
}
}
ELogLevel::ELogLevel CLogger::getLevel() const
{
TLockGuard _(mx);
return level;
TLockGuard _(mx);
return level;
}
void CLogger::setLevel(ELogLevel::ELogLevel level)
{
TLockGuard _(mx);
if(domain.isGlobalDomain() && level == ELogLevel::NOT_SET) return;
this->level = level;
TLockGuard _(mx);
if(domain.isGlobalDomain() && level == ELogLevel::NOT_SET) return;
this->level = level;
}
const CLoggerDomain & CLogger::getDomain() const
{
return domain;
return domain;
}
void CLogger::addTarget(unique_ptr<ILogTarget> && target)
{
TLockGuard _(mx);
targets.push_back(std::move(target));
TLockGuard _(mx);
targets.push_back(std::move(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;
// This shouldn't be reached, as the root logger must have set a log level
return ELogLevel::INFO;
}
void CLogger::callTargets(const LogRecord & record) const
{
TLockGuard _(mx);
TLockGuard _(mx);
for(const CLogger * logger = this; logger != nullptr; logger = logger->parent)
{
BOOST_FOREACH(auto & target, logger->targets)
{
target->write(record);
}
}
{
BOOST_FOREACH(auto & target, logger->targets)
{
target->write(record);
}
}
}
void CLogger::clearTargets()
{
TLockGuard _(mx);
targets.clear();
TLockGuard _(mx);
targets.clear();
}
bool CLogger::isDebugEnabled() const
{
return getEffectiveLevel() <= ELogLevel::DEBUG;
return getEffectiveLevel() <= ELogLevel::DEBUG;
}
bool CLogger::isTraceEnabled() const
{
return getEffectiveLevel() <= ELogLevel::TRACE;
return getEffectiveLevel() <= ELogLevel::TRACE;
}
boost::recursive_mutex CLogManager::smx;
CLogManager & CLogManager::get()
{
TLockGuardRec _(smx);
static CLogManager instance;
return instance;
TLockGuardRec _(smx);
static CLogManager instance;
return instance;
}
CLogManager::CLogManager()
@ -235,30 +235,30 @@ CLogManager::CLogManager()
CLogManager::~CLogManager()
{
BOOST_FOREACH(auto & i, loggers)
{
delete i.second;
}
BOOST_FOREACH(auto & i, loggers)
{
delete i.second;
}
}
void CLogManager::addLogger(CLogger * logger)
{
TLockGuard _(mx);
loggers[logger->getDomain().getName()] = logger;
TLockGuard _(mx);
loggers[logger->getDomain().getName()] = logger;
}
CLogger * CLogManager::getLogger(const CLoggerDomain & domain)
{
TLockGuard _(mx);
auto it = loggers.find(domain.getName());
if(it != loggers.end())
{
return it->second;
}
else
{
return nullptr;
}
TLockGuard _(mx);
auto it = loggers.find(domain.getName());
if(it != loggers.end())
{
return it->second;
}
else
{
return nullptr;
}
}
CLogFormatter::CLogFormatter() : pattern("%m")
@ -273,99 +273,99 @@ CLogFormatter::CLogFormatter(const std::string & pattern)
std::string CLogFormatter::format(const LogRecord & record) const
{
std::string message = pattern;
std::string message = pattern;
// Format date
std::stringstream dateStream;
boost::posix_time::time_facet * facet = new boost::posix_time::time_facet("%H:%M:%S");
dateStream.imbue(std::locale(dateStream.getloc(), facet));
dateStream << record.timeStamp;
boost::algorithm::replace_all(message, "%d", dateStream.str());
// Format date
std::stringstream dateStream;
boost::posix_time::time_facet * facet = new boost::posix_time::time_facet("%H:%M:%S");
dateStream.imbue(std::locale(dateStream.getloc(), facet));
dateStream << record.timeStamp;
boost::algorithm::replace_all(message, "%d", dateStream.str());
// Format log level
std::string level;
switch(record.level)
{
case ELogLevel::TRACE:
level = "TRACE";
break;
case ELogLevel::DEBUG:
level = "DEBUG";
break;
case ELogLevel::INFO:
level = "INFO";
break;
case ELogLevel::WARN:
level = "WARN";
break;
case ELogLevel::ERROR:
level = "ERROR";
break;
}
boost::algorithm::replace_all(message, "%l", level);
// Format log level
std::string level;
switch(record.level)
{
case ELogLevel::TRACE:
level = "TRACE";
break;
case ELogLevel::DEBUG:
level = "DEBUG";
break;
case ELogLevel::INFO:
level = "INFO";
break;
case ELogLevel::WARN:
level = "WARN";
break;
case ELogLevel::ERROR:
level = "ERROR";
break;
}
boost::algorithm::replace_all(message, "%l", level);
// Format name, thread id and message
boost::algorithm::replace_all(message, "%n", record.domain.getName());
boost::algorithm::replace_all(message, "%t", boost::lexical_cast<std::string>(record.threadId));
boost::algorithm::replace_all(message, "%m", record.message);
// Format name, thread id and message
boost::algorithm::replace_all(message, "%n", record.domain.getName());
boost::algorithm::replace_all(message, "%t", boost::lexical_cast<std::string>(record.threadId));
boost::algorithm::replace_all(message, "%m", record.message);
return message;
return message;
}
void CLogFormatter::setPattern(const std::string & pattern)
{
this->pattern = pattern;
this->pattern = pattern;
}
const std::string & CLogFormatter::getPattern() const
{
return pattern;
return pattern;
}
CColorMapping::CColorMapping()
{
// Set default mappings
auto & levelMap = map[CLoggerDomain::DOMAIN_GLOBAL];
levelMap[ELogLevel::TRACE] = EConsoleTextColor::GRAY;
levelMap[ELogLevel::DEBUG] = EConsoleTextColor::WHITE;
levelMap[ELogLevel::INFO] = EConsoleTextColor::GREEN;
levelMap[ELogLevel::WARN] = EConsoleTextColor::YELLOW;
levelMap[ELogLevel::ERROR] = EConsoleTextColor::RED;
// Set default mappings
auto & levelMap = map[CLoggerDomain::DOMAIN_GLOBAL];
levelMap[ELogLevel::TRACE] = EConsoleTextColor::GRAY;
levelMap[ELogLevel::DEBUG] = EConsoleTextColor::WHITE;
levelMap[ELogLevel::INFO] = EConsoleTextColor::GREEN;
levelMap[ELogLevel::WARN] = EConsoleTextColor::YELLOW;
levelMap[ELogLevel::ERROR] = EConsoleTextColor::RED;
}
void CColorMapping::setColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level, EConsoleTextColor::EConsoleTextColor color)
{
if(level == ELogLevel::NOT_SET) throw std::runtime_error("Log level NOT_SET not allowed for configuring the color mapping.");
map[domain.getName()][level] = color;
if(level == ELogLevel::NOT_SET) throw std::runtime_error("Log level NOT_SET not allowed for configuring the color mapping.");
map[domain.getName()][level] = color;
}
EConsoleTextColor::EConsoleTextColor CColorMapping::getColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level) const
{
std::string name = domain.getName();
while(true)
{
const auto & loggerPair = map.find(name);
if(loggerPair != map.end())
{
const auto & levelMap = loggerPair->second;
const auto & levelPair = levelMap.find(level);
if(levelPair != levelMap.end())
{
return levelPair->second;
}
}
std::string name = domain.getName();
while(true)
{
const auto & loggerPair = map.find(name);
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
{
break;
}
}
throw std::runtime_error("No color mapping found. Should not happen.");
CLoggerDomain currentDomain(name);
if(!currentDomain.isGlobalDomain())
{
name = currentDomain.getParent().getName();
}
else
{
break;
}
}
throw std::runtime_error("No color mapping found. Should not happen.");
}
CLogConsoleTarget::CLogConsoleTarget(CConsoleHandler * console) : console(console), threshold(ELogLevel::INFO), coloredOutputEnabled(true)
@ -375,98 +375,98 @@ CLogConsoleTarget::CLogConsoleTarget(CConsoleHandler * console) : console(consol
void CLogConsoleTarget::write(const LogRecord & record)
{
if(threshold > record.level) return;
if(threshold > record.level) return;
std::string message = formatter.format(record);
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);
}
}
else
{
TLockGuard _(mx);
if(printToStdErr)
{
std::cerr << message << std::endl;
}
else
{
std::cout << message << std::endl;
}
}
std::string message = formatter.format(record);
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);
}
}
else
{
TLockGuard _(mx);
if(printToStdErr)
{
std::cerr << message << std::endl;
}
else
{
std::cout << message << std::endl;
}
}
}
bool CLogConsoleTarget::isColoredOutputEnabled() const
{
return coloredOutputEnabled;
return coloredOutputEnabled;
}
void CLogConsoleTarget::setColoredOutputEnabled(bool coloredOutputEnabled)
{
this->coloredOutputEnabled = coloredOutputEnabled;
this->coloredOutputEnabled = coloredOutputEnabled;
}
ELogLevel::ELogLevel CLogConsoleTarget::getThreshold() const
{
return threshold;
return threshold;
}
void CLogConsoleTarget::setThreshold(ELogLevel::ELogLevel threshold)
{
this->threshold = threshold;
this->threshold = threshold;
}
const CLogFormatter & CLogConsoleTarget::getFormatter() const
{
return formatter;
return formatter;
}
void CLogConsoleTarget::setFormatter(const CLogFormatter & formatter)
{
this->formatter = formatter;
this->formatter = formatter;
}
const CColorMapping & CLogConsoleTarget::getColorMapping() const
{
return colorMapping;
return colorMapping;
}
void CLogConsoleTarget::setColorMapping(const CColorMapping & colorMapping)
{
this->colorMapping = colorMapping;
this->colorMapping = colorMapping;
}
CLogFileTarget::CLogFileTarget(const std::string & filePath, bool append /*= true*/)
: file(filePath, append ? std::ios_base::app : std::ios_base::out)
: file(filePath, append ? std::ios_base::app : std::ios_base::out)
{
formatter.setPattern("%d %l %n [%t] - %m");
formatter.setPattern("%d %l %n [%t] - %m");
}
CLogFileTarget::~CLogFileTarget()
{
file.close();
file.close();
}
void CLogFileTarget::write(const LogRecord & record)
{
TLockGuard _(mx);
file << formatter.format(record) << std::endl;
TLockGuard _(mx);
file << formatter.format(record) << std::endl;
}
const CLogFormatter & CLogFileTarget::getFormatter() const
{
return formatter;
return formatter;
}
void CLogFileTarget::setFormatter(const CLogFormatter & formatter)
{
this->formatter = formatter;
this->formatter = formatter;
}

View File

@ -19,106 +19,106 @@ class ILogTarget;
namespace ELogLevel
{
enum ELogLevel
{
NOT_SET = 0,
TRACE,
DEBUG,
INFO,
WARN,
ERROR
};
enum ELogLevel
{
NOT_SET = 0,
TRACE,
DEBUG,
INFO,
WARN,
ERROR
};
}
/// The class CLoggerDomain provides convenient access to super domains from a sub domain.
class DLL_LINKAGE CLoggerDomain
{
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);
/// 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);
std::string getName() const;
CLoggerDomain getParent() const;
bool isGlobalDomain() const;
std::string getName() const;
CLoggerDomain getParent() const;
bool isGlobalDomain() const;
static const std::string DOMAIN_GLOBAL;
static const std::string DOMAIN_GLOBAL;
private:
std::string name;
std::string name;
};
/// The class CLoggerStream provides a stream-like way of logging messages.
class DLL_LINKAGE CLoggerStream
{
public:
CLoggerStream(const CLogger & logger, ELogLevel::ELogLevel level);
~CLoggerStream();
CLoggerStream(const CLogger & logger, ELogLevel::ELogLevel level);
~CLoggerStream();
template<typename T>
CLoggerStream & operator<<(const T & data)
{
if(!sbuffer) sbuffer = new std::stringstream();
(*sbuffer) << data;
return *this;
}
template<typename T>
CLoggerStream & operator<<(const T & data)
{
if(!sbuffer) sbuffer = new std::stringstream();
(*sbuffer) << data;
return *this;
}
private:
const CLogger & logger;
ELogLevel::ELogLevel level;
std::stringstream * sbuffer;
const CLogger & logger;
ELogLevel::ELogLevel level;
std::stringstream * sbuffer;
};
/// The class CLogger is used to log messages to certain targets of a specific domain/name.
class DLL_LINKAGE CLogger
{
public:
inline ELogLevel::ELogLevel getLevel() const;
void setLevel(ELogLevel::ELogLevel level);
const CLoggerDomain & getDomain() const;
inline ELogLevel::ELogLevel getLevel() const;
void setLevel(ELogLevel::ELogLevel level);
const CLoggerDomain & getDomain() const;
/// Logger access methods
static CLogger * getLogger(const CLoggerDomain & domain);
static CLogger * getGlobalLogger();
/// Logger access methods
static CLogger * getLogger(const CLoggerDomain & domain);
static CLogger * getGlobalLogger();
/// Log methods for various log levels
void trace(const std::string & message) const;
CLoggerStream traceStream() const;
/// 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 debug(const std::string & message) const;
CLoggerStream debugStream() const;
void info(const std::string & message) const;
CLoggerStream infoStream() const;
void info(const std::string & message) const;
CLoggerStream infoStream() const;
void warn(const std::string & message) const;
CLoggerStream warnStream() const;
void warn(const std::string & message) const;
CLoggerStream warnStream() const;
void error(const std::string & message) const;
CLoggerStream errorStream() const;
void error(const std::string & message) const;
CLoggerStream errorStream() const;
inline void log(ELogLevel::ELogLevel level, const std::string & message) const;
inline void log(ELogLevel::ELogLevel level, const std::string & message) const;
void addTarget(unique_ptr<ILogTarget> && target);
void clearTargets();
void addTarget(unique_ptr<ILogTarget> && target);
void clearTargets();
/// Returns true if a debug/trace log message will be logged, false if not.
/// Useful if performance is important and concatenating the log message is a expensive task.
bool isDebugEnabled() const;
bool isTraceEnabled() const;
/// Returns true if a debug/trace log message will be logged, false if not.
/// Useful if performance is important and concatenating the log message is a expensive task.
bool isDebugEnabled() const;
bool isTraceEnabled() const;
private:
explicit CLogger(const CLoggerDomain & domain);
CLogger * getParent() const;
inline ELogLevel::ELogLevel getEffectiveLevel() const; /// Returns the log level applied on this logger whether directly or indirectly.
inline void callTargets(const LogRecord & record) const;
explicit CLogger(const CLoggerDomain & domain);
CLogger * getParent() const;
inline ELogLevel::ELogLevel getEffectiveLevel() const; /// Returns the log level applied on this logger whether directly or indirectly.
inline void callTargets(const LogRecord & record) const;
CLoggerDomain domain;
CLogger * parent;
ELogLevel::ELogLevel level;
std::list<unique_ptr<ILogTarget> > targets;
mutable boost::mutex mx;
static boost::recursive_mutex smx;
CLoggerDomain domain;
CLogger * parent;
ELogLevel::ELogLevel level;
std::list<unique_ptr<ILogTarget> > targets;
mutable boost::mutex mx;
static boost::recursive_mutex smx;
};
extern DLL_LINKAGE CLogger * logGlobal;
@ -131,10 +131,10 @@ extern DLL_LINKAGE CLogger * logAi;
/// Logging traces via this macro have almost no impact when the trace is disabled.
#define TRACE_BEGIN(logger) logger->traceStream() << boost::format("Entering %s.") % BOOST_CURRENT_FUNCTION;
#define TRACE_BEGIN_PARAMS(logger, formatStr, params) if(logger->isTraceEnabled()) logger->traceStream() << \
boost::format("Entering %s: " + std::string(formatStr) + ".") % BOOST_CURRENT_FUNCTION % params;
boost::format("Entering %s: " + std::string(formatStr) + ".") % BOOST_CURRENT_FUNCTION % params;
#define TRACE_END(logger) logger->traceStream() << boost::format("Leaving %s.") % BOOST_CURRENT_FUNCTION;
#define TRACE_END_PARAMS(logger, formatStr, params) if(logger->isTraceEnabled()) logger->traceStream() << \
boost::format("Leaving %s: " + std::string(formatStr) + ".") % BOOST_CURRENT_FUNCTION % params;
boost::format("Leaving %s: " + std::string(formatStr) + ".") % BOOST_CURRENT_FUNCTION % params;
/* ---------------------------------------------------------------------------- */
/* Implementation/Detail classes, Private API */
@ -144,35 +144,35 @@ extern DLL_LINKAGE CLogger * logAi;
class DLL_LINKAGE CLogManager : public boost::noncopyable
{
public:
static CLogManager & get();
static CLogManager & get();
void addLogger(CLogger * logger);
CLogger * getLogger(const CLoggerDomain & domain); /// Returns a logger or nullptr if no one is registered for the given domain.
void addLogger(CLogger * logger);
CLogger * getLogger(const CLoggerDomain & domain); /// Returns a logger or nullptr if no one is registered for the given domain.
private:
CLogManager();
~CLogManager();
CLogManager();
~CLogManager();
std::map<std::string, CLogger *> loggers;
mutable boost::mutex mx;
static boost::recursive_mutex smx;
std::map<std::string, CLogger *> loggers;
mutable boost::mutex mx;
static boost::recursive_mutex smx;
};
/// The struct LogRecord holds the log message and additional logging information.
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())
{
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())
{
}
}
CLoggerDomain domain;
ELogLevel::ELogLevel level;
std::string message;
boost::posix_time::ptime timeStamp;
boost::thread::id threadId;
CLoggerDomain domain;
ELogLevel::ELogLevel level;
std::string message;
boost::posix_time::ptime timeStamp;
boost::thread::id threadId;
};
/// The class CLogFormatter formats log records.
@ -186,16 +186,16 @@ struct DLL_LINKAGE LogRecord
class DLL_LINKAGE CLogFormatter
{
public:
CLogFormatter();
CLogFormatter(const std::string & pattern);
CLogFormatter();
CLogFormatter(const std::string & pattern);
void setPattern(const std::string & pattern);
const std::string & getPattern() const;
void setPattern(const std::string & pattern);
const std::string & getPattern() const;
std::string format(const LogRecord & record) const;
std::string format(const LogRecord & record) const;
private:
std::string pattern;
std::string pattern;
};
/// The interface ILogTarget is used by all log target implementations. It holds
@ -203,68 +203,68 @@ private:
class DLL_LINKAGE ILogTarget : public boost::noncopyable
{
public:
virtual ~ILogTarget() { };
virtual void write(const LogRecord & record) = 0;
virtual ~ILogTarget() { };
virtual void write(const LogRecord & record) = 0;
};
/// The class CColorMapping maps a logger name and a level to a specific color. Supports domain inheritance.
class DLL_LINKAGE CColorMapping
{
public:
CColorMapping();
CColorMapping();
void setColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level, EConsoleTextColor::EConsoleTextColor color);
EConsoleTextColor::EConsoleTextColor getColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level) const;
void setColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level, EConsoleTextColor::EConsoleTextColor color);
EConsoleTextColor::EConsoleTextColor getColorFor(const CLoggerDomain & domain, ELogLevel::ELogLevel level) const;
private:
std::map<std::string, std::map<ELogLevel::ELogLevel, EConsoleTextColor::EConsoleTextColor> > map;
std::map<std::string, std::map<ELogLevel::ELogLevel, EConsoleTextColor::EConsoleTextColor> > map;
};
/// The class CLogConsoleTarget is a logging target which writes message to the console.
class DLL_LINKAGE CLogConsoleTarget : public ILogTarget
{
public:
explicit CLogConsoleTarget(CConsoleHandler * console);
explicit CLogConsoleTarget(CConsoleHandler * console);
bool isColoredOutputEnabled() const;
void setColoredOutputEnabled(bool coloredOutputEnabled);
bool isColoredOutputEnabled() const;
void setColoredOutputEnabled(bool coloredOutputEnabled);
ELogLevel::ELogLevel getThreshold() const;
void setThreshold(ELogLevel::ELogLevel threshold);
ELogLevel::ELogLevel getThreshold() const;
void setThreshold(ELogLevel::ELogLevel threshold);
const CLogFormatter & getFormatter() const;
void setFormatter(const CLogFormatter & formatter);
const CLogFormatter & getFormatter() const;
void setFormatter(const CLogFormatter & formatter);
const CColorMapping & getColorMapping() const;
void setColorMapping(const CColorMapping & colorMapping);
const CColorMapping & getColorMapping() const;
void setColorMapping(const CColorMapping & colorMapping);
void write(const LogRecord & record);
void write(const LogRecord & record);
private:
CConsoleHandler * console;
ELogLevel::ELogLevel threshold;
bool coloredOutputEnabled;
CLogFormatter formatter;
CColorMapping colorMapping;
mutable boost::mutex mx;
CConsoleHandler * console;
ELogLevel::ELogLevel threshold;
bool coloredOutputEnabled;
CLogFormatter formatter;
CColorMapping colorMapping;
mutable boost::mutex mx;
};
/// The class CLogFileTarget is a logging target which writes messages to a log file.
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
/// 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);
~CLogFileTarget();
/// Constructs a CLogFileTarget and opens the file designated by filePath. 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);
~CLogFileTarget();
const CLogFormatter & getFormatter() const;
void setFormatter(const CLogFormatter & formatter);
const CLogFormatter & getFormatter() const;
void setFormatter(const CLogFormatter & formatter);
void write(const LogRecord & record);
void write(const LogRecord & record);
private:
std::ofstream file;
CLogFormatter formatter;
mutable boost::mutex mx;
std::ofstream file;
CLogFormatter formatter;
mutable boost::mutex mx;
};

View File

@ -47,7 +47,7 @@ si8 PlayerInfo::defaultHero() const
bool PlayerInfo::canAnyonePlay() const
{
return canHumanPlay || canComputerPlay;
return canHumanPlay || canComputerPlay;
}
LossCondition::LossCondition() : typeOfLossCon(ELossConditionType::LOSSSTANDARD),
@ -104,7 +104,7 @@ bool TerrainTile::entrableTerrain(const TerrainTile * from /*= NULL*/) const
bool TerrainTile::entrableTerrain(bool allowLand, bool allowSea) const
{
return terType != ETerrainType::ROCK
&& ((allowSea && terType == ETerrainType::WATER) || (allowLand && terType != ETerrainType::WATER));
&& ((allowSea && terType == ETerrainType::WATER) || (allowLand && terType != ETerrainType::WATER));
}
bool TerrainTile::isClear(const TerrainTile *from /*= NULL*/) const

View File

@ -57,14 +57,14 @@ struct DLL_LINKAGE SHeroName
namespace EAiTactic
{
enum EAiTactic
{
NONE = -1,
RANDOM,
WARRIOR,
BUILDER,
EXPLORER
};
enum EAiTactic
{
NONE = -1,
RANDOM,
WARRIOR,
BUILDER,
EXPLORER
};
}
/**
@ -92,7 +92,7 @@ struct DLL_LINKAGE PlayerInfo
*/
si8 defaultHero() const;
bool canAnyonePlay() const;
bool canAnyonePlay() const;
/** True if the player can be played by a human. */
bool canHumanPlay;
@ -156,8 +156,8 @@ struct DLL_LINKAGE PlayerInfo
void serialize(Handler & h, const int version)
{
h & p7 & hasHero & customHeroID & canHumanPlay & canComputerPlay & aiTactic & allowedFactions & isFactionRandom &
mainHeroPortrait & mainHeroName & heroesNames & hasMainTown & generateHeroAtMainTown &
posOfMainTown & team & generateHero;
mainHeroPortrait & mainHeroName & heroesNames & hasMainTown & generateHeroAtMainTown &
posOfMainTown & team & generateHero;
}
};
@ -347,7 +347,7 @@ public:
void serialize(Handler & h, const int version)
{
h & name & message & resources
& players & humanAffected & computerAffected & firstOccurence & nextOccurence;
& players & humanAffected & computerAffected & firstOccurence & nextOccurence;
}
};
@ -384,18 +384,18 @@ public:
namespace ERiverType
{
enum ERiverType
{
NO_RIVER, CLEAR_RIVER, ICY_RIVER, MUDDY_RIVER, LAVA_RIVER
};
enum ERiverType
{
NO_RIVER, CLEAR_RIVER, ICY_RIVER, MUDDY_RIVER, LAVA_RIVER
};
}
namespace ERoadType
{
enum ERoadType
{
NO_ROAD, DIRT_ROAD, GRAVEL_ROAD, COBBLESTONE_ROAD
};
enum ERoadType
{
NO_ROAD, DIRT_ROAD, GRAVEL_ROAD, COBBLESTONE_ROAD
};
}
/**
@ -516,10 +516,10 @@ struct DLL_LINKAGE TerrainTile
namespace EMapFormat
{
enum EMapFormat
{
INVALID, WOG=0x33, AB=0x15, ROE=0x0e, SOD=0x1c
};
enum EMapFormat
{
INVALID, WOG=0x33, AB=0x15, ROE=0x0e, SOD=0x1c
};
}
/**
@ -840,12 +840,12 @@ public:
switch (objects[i]->ID)
{
case Obj::HERO:
heroes.push_back (static_cast<CGHeroInstance*>(+objects[i]));
break;
case Obj::TOWN:
towns.push_back (static_cast<CGTownInstance*>(+objects[i]));
break;
case Obj::HERO:
heroes.push_back (static_cast<CGHeroInstance*>(+objects[i]));
break;
case Obj::TOWN:
towns.push_back (static_cast<CGTownInstance*>(+objects[i]));
break;
}
// recreate blockvis map

View File

@ -67,12 +67,12 @@ void CMapGenOptions::setPlayersCnt(si8 value)
if((value >= 1 && value <= PlayerColor::PLAYER_LIMIT_I) || value == RANDOM_SIZE)
{
playersCnt = value;
resetPlayersMap();
resetPlayersMap();
}
else
{
throw std::runtime_error("Players count of RMG options should be between 1 and " +
boost::lexical_cast<std::string>(PlayerColor::PLAYER_LIMIT) + " or CMapGenOptions::RANDOM_SIZE for random.");
boost::lexical_cast<std::string>(PlayerColor::PLAYER_LIMIT) + " or CMapGenOptions::RANDOM_SIZE for random.");
}
}
@ -90,7 +90,7 @@ void CMapGenOptions::setTeamsCnt(si8 value)
else
{
throw std::runtime_error("Teams count of RMG options should be between 0 and <" +
boost::lexical_cast<std::string>(playersCnt) + "(players count) - 1> or CMapGenOptions::RANDOM_SIZE for random.");
boost::lexical_cast<std::string>(playersCnt) + "(players count) - 1> or CMapGenOptions::RANDOM_SIZE for random.");
}
}
@ -104,13 +104,13 @@ void CMapGenOptions::setCompOnlyPlayersCnt(si8 value)
if(value == RANDOM_SIZE || (value >= 0 && value <= PlayerColor::PLAYER_LIMIT_I - playersCnt))
{
compOnlyPlayersCnt = value;
resetPlayersMap();
resetPlayersMap();
}
else
{
throw std::runtime_error(std::string("Computer only players count of RMG options should be ") +
"between 0 and <PlayerColor::PLAYER_LIMIT - " + boost::lexical_cast<std::string>(playersCnt) +
"(playersCount)> or CMapGenOptions::RANDOM_SIZE for random.");
"between 0 and <PlayerColor::PLAYER_LIMIT - " + boost::lexical_cast<std::string>(playersCnt) +
"(playersCount)> or CMapGenOptions::RANDOM_SIZE for random.");
}
}
@ -128,8 +128,8 @@ void CMapGenOptions::setCompOnlyTeamsCnt(si8 value)
else
{
throw std::runtime_error(std::string("Computer only teams count of RMG options should be ") +
"between 0 and <" + boost::lexical_cast<std::string>(compOnlyPlayersCnt) +
"(compOnlyPlayersCnt) - 1> or CMapGenOptions::RANDOM_SIZE for random.");
"between 0 and <" + boost::lexical_cast<std::string>(compOnlyPlayersCnt) +
"(compOnlyPlayersCnt) - 1> or CMapGenOptions::RANDOM_SIZE for random.");
}
}
@ -155,153 +155,153 @@ void CMapGenOptions::setMonsterStrength(EMonsterStrength::EMonsterStrength value
void CMapGenOptions::resetPlayersMap()
{
players.clear();
int realPlayersCnt = playersCnt == RANDOM_SIZE ? PlayerColor::PLAYER_LIMIT_I : playersCnt;
int realCompOnlyPlayersCnt = compOnlyPlayersCnt == RANDOM_SIZE ? (PlayerColor::PLAYER_LIMIT_I - realPlayersCnt) : compOnlyPlayersCnt;
for(int color = 0; color < (realPlayersCnt + realCompOnlyPlayersCnt); ++color)
{
CPlayerSettings player;
player.setColor(PlayerColor(color));
player.setPlayerType((color >= playersCnt) ? EPlayerType::COMP_ONLY : EPlayerType::AI);
players[PlayerColor(color)] = player;
}
players.clear();
int realPlayersCnt = playersCnt == RANDOM_SIZE ? PlayerColor::PLAYER_LIMIT_I : playersCnt;
int realCompOnlyPlayersCnt = compOnlyPlayersCnt == RANDOM_SIZE ? (PlayerColor::PLAYER_LIMIT_I - realPlayersCnt) : compOnlyPlayersCnt;
for(int color = 0; color < (realPlayersCnt + realCompOnlyPlayersCnt); ++color)
{
CPlayerSettings player;
player.setColor(PlayerColor(color));
player.setPlayerType((color >= playersCnt) ? EPlayerType::COMP_ONLY : EPlayerType::AI);
players[PlayerColor(color)] = player;
}
}
const std::map<PlayerColor, CMapGenOptions::CPlayerSettings> & CMapGenOptions::getPlayersSettings() const
{
return players;
return players;
}
void CMapGenOptions::setStartingTownForPlayer(PlayerColor color, si32 town)
{
auto it = players.find(color);
if(it == players.end()) throw std::runtime_error(boost::str(boost::format("Cannot set starting town for the player with the color '%i'.") % color));
it->second.setStartingTown(town);
auto it = players.find(color);
if(it == players.end()) throw std::runtime_error(boost::str(boost::format("Cannot set starting town for the player with the color '%i'.") % color));
it->second.setStartingTown(town);
}
void CMapGenOptions::setPlayerTypeForStandardPlayer(PlayerColor color, EPlayerType::EPlayerType playerType)
{
auto it = players.find(color);
if(it == players.end()) throw std::runtime_error(boost::str(boost::format("Cannot set player type for the player with the color '%i'.") % color));
if(playerType == EPlayerType::COMP_ONLY) throw std::runtime_error("Cannot set player type computer only to a standard player.");
it->second.setPlayerType(playerType);
auto it = players.find(color);
if(it == players.end()) throw std::runtime_error(boost::str(boost::format("Cannot set player type for the player with the color '%i'.") % color));
if(playerType == EPlayerType::COMP_ONLY) throw std::runtime_error("Cannot set player type computer only to a standard player.");
it->second.setPlayerType(playerType);
}
void CMapGenOptions::finalize()
{
CRandomGenerator gen;
finalize(gen);
CRandomGenerator gen;
finalize(gen);
}
void CMapGenOptions::finalize(CRandomGenerator & gen)
{
if(playersCnt == RANDOM_SIZE)
{
// 1 human is required at least
auto humanPlayers = countHumanPlayers();
if(humanPlayers == 0) humanPlayers = 1;
playersCnt = gen.getInteger(humanPlayers, PlayerColor::PLAYER_LIMIT_I);
if(playersCnt == RANDOM_SIZE)
{
// 1 human is required at least
auto humanPlayers = countHumanPlayers();
if(humanPlayers == 0) humanPlayers = 1;
playersCnt = gen.getInteger(humanPlayers, PlayerColor::PLAYER_LIMIT_I);
// Remove AI players only from the end of the players map if necessary
for(auto itrev = players.end(); itrev != players.begin();)
{
auto it = itrev;
--it;
if(players.size() == playersCnt) break;
if(it->second.getPlayerType() == EPlayerType::AI)
{
players.erase(it);
}
else
{
--itrev;
}
}
}
if(teamsCnt == RANDOM_SIZE)
{
teamsCnt = gen.getInteger(0, playersCnt - 1);
}
if(compOnlyPlayersCnt == RANDOM_SIZE)
{
compOnlyPlayersCnt = gen.getInteger(0, 8 - playersCnt);
auto totalPlayersCnt = playersCnt + compOnlyPlayersCnt;
// Remove AI players only from the end of the players map if necessary
for(auto itrev = players.end(); itrev != players.begin();)
{
auto it = itrev;
--it;
if(players.size() == playersCnt) break;
if(it->second.getPlayerType() == EPlayerType::AI)
{
players.erase(it);
}
else
{
--itrev;
}
}
}
if(teamsCnt == RANDOM_SIZE)
{
teamsCnt = gen.getInteger(0, playersCnt - 1);
}
if(compOnlyPlayersCnt == RANDOM_SIZE)
{
compOnlyPlayersCnt = gen.getInteger(0, 8 - playersCnt);
auto totalPlayersCnt = playersCnt + compOnlyPlayersCnt;
// Remove comp only players only from the end of the players map if necessary
for(auto itrev = players.end(); itrev != players.begin();)
{
auto it = itrev;
--it;
if(players.size() <= totalPlayersCnt) break;
if(it->second.getPlayerType() == EPlayerType::COMP_ONLY)
{
players.erase(it);
}
else
{
--itrev;
}
}
// Remove comp only players only from the end of the players map if necessary
for(auto itrev = players.end(); itrev != players.begin();)
{
auto it = itrev;
--it;
if(players.size() <= totalPlayersCnt) break;
if(it->second.getPlayerType() == EPlayerType::COMP_ONLY)
{
players.erase(it);
}
else
{
--itrev;
}
}
// Add some comp only players if necessary
auto compOnlyPlayersToAdd = totalPlayersCnt - players.size();
for(int i = 0; i < compOnlyPlayersToAdd; ++i)
{
CPlayerSettings pSettings;
pSettings.setPlayerType(EPlayerType::COMP_ONLY);
pSettings.setColor(getNextPlayerColor());
players[pSettings.getColor()] = pSettings;
}
}
if(compOnlyTeamsCnt == RANDOM_SIZE)
{
compOnlyTeamsCnt = gen.getInteger(0, std::max(compOnlyPlayersCnt - 1, 0));
}
// Add some comp only players if necessary
auto compOnlyPlayersToAdd = totalPlayersCnt - players.size();
for(int i = 0; i < compOnlyPlayersToAdd; ++i)
{
CPlayerSettings pSettings;
pSettings.setPlayerType(EPlayerType::COMP_ONLY);
pSettings.setColor(getNextPlayerColor());
players[pSettings.getColor()] = pSettings;
}
}
if(compOnlyTeamsCnt == RANDOM_SIZE)
{
compOnlyTeamsCnt = gen.getInteger(0, std::max(compOnlyPlayersCnt - 1, 0));
}
// There should be at least 2 players (1-player-maps aren't allowed)
if(playersCnt + compOnlyPlayersCnt < 2)
{
CPlayerSettings pSettings;
pSettings.setPlayerType(EPlayerType::AI);
pSettings.setColor(getNextPlayerColor());
players[pSettings.getColor()] = pSettings;
playersCnt = 2;
}
// There should be at least 2 players (1-player-maps aren't allowed)
if(playersCnt + compOnlyPlayersCnt < 2)
{
CPlayerSettings pSettings;
pSettings.setPlayerType(EPlayerType::AI);
pSettings.setColor(getNextPlayerColor());
players[pSettings.getColor()] = pSettings;
playersCnt = 2;
}
// 1 team isn't allowed
if(teamsCnt == 1 && compOnlyPlayersCnt == 0)
{
teamsCnt = 0;
}
// 1 team isn't allowed
if(teamsCnt == 1 && compOnlyPlayersCnt == 0)
{
teamsCnt = 0;
}
if(waterContent == EWaterContent::RANDOM)
{
waterContent = static_cast<EWaterContent::EWaterContent>(gen.getInteger(0, 2));
}
if(monsterStrength == EMonsterStrength::RANDOM)
{
monsterStrength = static_cast<EMonsterStrength::EMonsterStrength>(gen.getInteger(0, 2));
}
if(waterContent == EWaterContent::RANDOM)
{
waterContent = static_cast<EWaterContent::EWaterContent>(gen.getInteger(0, 2));
}
if(monsterStrength == EMonsterStrength::RANDOM)
{
monsterStrength = static_cast<EMonsterStrength::EMonsterStrength>(gen.getInteger(0, 2));
}
}
int CMapGenOptions::countHumanPlayers() const
{
return static_cast<int>(boost::count_if(players, [](const std::pair<PlayerColor, CPlayerSettings> & pair)
{
return pair.second.getPlayerType() == EPlayerType::HUMAN;
}));
return static_cast<int>(boost::count_if(players, [](const std::pair<PlayerColor, CPlayerSettings> & pair)
{
return pair.second.getPlayerType() == EPlayerType::HUMAN;
}));
}
PlayerColor CMapGenOptions::getNextPlayerColor() const
{
for(PlayerColor i = PlayerColor(0); i < PlayerColor::PLAYER_LIMIT; i.advance(1))
{
if(!players.count(i))
{
return i;
}
}
throw std::runtime_error("Shouldn't happen. No free player color exists.");
for(PlayerColor i = PlayerColor(0); i < PlayerColor::PLAYER_LIMIT; i.advance(1))
{
if(!players.count(i))
{
return i;
}
}
throw std::runtime_error("Shouldn't happen. No free player color exists.");
}
CMapGenOptions::CPlayerSettings::CPlayerSettings() : color(0), startingTown(RANDOM_TOWN), playerType(EPlayerType::AI)
@ -311,44 +311,44 @@ CMapGenOptions::CPlayerSettings::CPlayerSettings() : color(0), startingTown(RAND
PlayerColor CMapGenOptions::CPlayerSettings::getColor() const
{
return color;
return color;
}
void CMapGenOptions::CPlayerSettings::setColor(PlayerColor value)
{
if(value >= PlayerColor(0) && value < PlayerColor::PLAYER_LIMIT)
{
color = value;
}
else
{
throw std::runtime_error("The color of the player is not in a valid range.");
}
if(value >= PlayerColor(0) && value < PlayerColor::PLAYER_LIMIT)
{
color = value;
}
else
{
throw std::runtime_error("The color of the player is not in a valid range.");
}
}
si32 CMapGenOptions::CPlayerSettings::getStartingTown() const
{
return startingTown;
return startingTown;
}
void CMapGenOptions::CPlayerSettings::setStartingTown(si32 value)
{
if(value >= -1 && value < static_cast<int>(VLC->townh->towns.size()))
{
startingTown = value;
}
else
{
throw std::runtime_error("The starting town of the player is not in a valid range.");
}
if(value >= -1 && value < static_cast<int>(VLC->townh->towns.size()))
{
startingTown = value;
}
else
{
throw std::runtime_error("The starting town of the player is not in a valid range.");
}
}
EPlayerType::EPlayerType CMapGenOptions::CPlayerSettings::getPlayerType() const
{
return playerType;
return playerType;
}
void CMapGenOptions::CPlayerSettings::setPlayerType(EPlayerType::EPlayerType value)
{
playerType = value;
playerType = value;
}

View File

@ -17,34 +17,34 @@ class CRandomGenerator;
namespace EWaterContent
{
enum EWaterContent
{
RANDOM = -1,
NONE,
NORMAL,
ISLANDS
};
enum EWaterContent
{
RANDOM = -1,
NONE,
NORMAL,
ISLANDS
};
}
namespace EMonsterStrength
{
enum EMonsterStrength
{
RANDOM = -1,
WEAK,
NORMAL,
STRONG
};
enum EMonsterStrength
{
RANDOM = -1,
WEAK,
NORMAL,
STRONG
};
}
namespace EPlayerType
{
enum EPlayerType
{
HUMAN,
AI,
COMP_ONLY
};
enum EPlayerType
{
HUMAN,
AI,
COMP_ONLY
};
}
/// The map gen options class holds values about general map generation settings
@ -52,41 +52,41 @@ namespace EPlayerType
class DLL_LINKAGE CMapGenOptions
{
public:
/// The player settings class maps the player color, starting town and human player flag.
class CPlayerSettings
{
public:
CPlayerSettings();
/// The player settings class maps the player color, starting town and human player flag.
class CPlayerSettings
{
public:
CPlayerSettings();
/// The color of the player ranging from 0 to PlayerColor::PLAYER_LIMIT - 1.
/// The default value is 0.
PlayerColor getColor() const;
void setColor(PlayerColor value);
/// The color of the player ranging from 0 to PlayerColor::PLAYER_LIMIT - 1.
/// The default value is 0.
PlayerColor getColor() const;
void setColor(PlayerColor value);
/// The starting town of the player ranging from 0 to town max count or RANDOM_TOWN.
/// The default value is RANDOM_TOWN.
si32 getStartingTown() const;
void setStartingTown(si32 value);
/// The starting town of the player ranging from 0 to town max count or RANDOM_TOWN.
/// The default value is RANDOM_TOWN.
si32 getStartingTown() const;
void setStartingTown(si32 value);
/// The default value is EPlayerType::AI.
EPlayerType::EPlayerType getPlayerType() const;
void setPlayerType(EPlayerType::EPlayerType value);
/// The default value is EPlayerType::AI.
EPlayerType::EPlayerType getPlayerType() const;
void setPlayerType(EPlayerType::EPlayerType value);
/// Constant for a random town selection.
static const si32 RANDOM_TOWN = -1;
/// Constant for a random town selection.
static const si32 RANDOM_TOWN = -1;
private:
PlayerColor color;
si32 startingTown;
EPlayerType::EPlayerType playerType;
private:
PlayerColor color;
si32 startingTown;
EPlayerType::EPlayerType playerType;
public:
template <typename Handler>
void serialize(Handler & h, const int version)
{
h & color & startingTown & playerType;
}
};
public:
template <typename Handler>
void serialize(Handler & h, const int version)
{
h & color & startingTown & playerType;
}
};
CMapGenOptions();
@ -99,21 +99,21 @@ public:
bool getHasTwoLevels() const;
void setHasTwoLevels(bool value);
/// The count of the players ranging from 1 to PlayerColor::PLAYER_LIMIT or RANDOM_SIZE for random. If you call
/// this method, all player settings are reset to default settings.
/// The count of the players ranging from 1 to PlayerColor::PLAYER_LIMIT or RANDOM_SIZE for random. If you call
/// this method, all player settings are reset to default settings.
si8 getPlayersCnt() const;
void setPlayersCnt(si8 value);
/// The count of the teams ranging from 0 to <players count - 1> or RANDOM_SIZE for random.
/// The count of the teams ranging from 0 to <players count - 1> or RANDOM_SIZE for random.
si8 getTeamsCnt() const;
void setTeamsCnt(si8 value);
/// The count of the computer only players ranging from 0 to <PlayerColor::PLAYER_LIMIT - players count> or RANDOM_SIZE for random.
/// If you call this method, all player settings are reset to default settings.
/// The count of the computer only players ranging from 0 to <PlayerColor::PLAYER_LIMIT - players count> or RANDOM_SIZE for random.
/// If you call this method, all player settings are reset to default settings.
si8 getCompOnlyPlayersCnt() const;
void setCompOnlyPlayersCnt(si8 value);
/// The count of the computer only teams ranging from 0 to <comp only players - 1> or RANDOM_SIZE for random.
/// The count of the computer only teams ranging from 0 to <comp only players - 1> or RANDOM_SIZE for random.
si8 getCompOnlyTeamsCnt() const;
void setCompOnlyTeamsCnt(si8 value);
@ -123,33 +123,33 @@ public:
EMonsterStrength::EMonsterStrength getMonsterStrength() const;
void setMonsterStrength(EMonsterStrength::EMonsterStrength value);
/// The first player colors belong to standard players and the last player colors belong to comp only players.
/// All standard players are by default of type EPlayerType::AI.
const std::map<PlayerColor, CPlayerSettings> & getPlayersSettings() const;
void setStartingTownForPlayer(PlayerColor color, si32 town);
/// Sets a player type for a standard player. A standard player is the opposite of a computer only player. The
/// values which can be chosen for the player type are EPlayerType::AI or EPlayerType::HUMAN. Calling this method
/// has no effect for the map itself, but it adds some informational text for the map description.
void setPlayerTypeForStandardPlayer(PlayerColor color, EPlayerType::EPlayerType playerType);
/// The first player colors belong to standard players and the last player colors belong to comp only players.
/// All standard players are by default of type EPlayerType::AI.
const std::map<PlayerColor, CPlayerSettings> & getPlayersSettings() const;
void setStartingTownForPlayer(PlayerColor color, si32 town);
/// Sets a player type for a standard player. A standard player is the opposite of a computer only player. The
/// values which can be chosen for the player type are EPlayerType::AI or EPlayerType::HUMAN. Calling this method
/// has no effect for the map itself, but it adds some informational text for the map description.
void setPlayerTypeForStandardPlayer(PlayerColor color, EPlayerType::EPlayerType playerType);
/// Finalizes the options. All random sizes for various properties will be overwritten by numbers from
/// a random number generator by keeping the options in a valid state.
void finalize();
void finalize(CRandomGenerator & gen);
/// Finalizes the options. All random sizes for various properties will be overwritten by numbers from
/// a random number generator by keeping the options in a valid state.
void finalize();
void finalize(CRandomGenerator & gen);
static const si8 RANDOM_SIZE = -1;
private:
void resetPlayersMap();
int countHumanPlayers() const;
PlayerColor getNextPlayerColor() const;
void resetPlayersMap();
int countHumanPlayers() const;
PlayerColor getNextPlayerColor() const;
si32 width, height;
si32 width, height;
bool hasTwoLevels;
si8 playersCnt, teamsCnt, compOnlyPlayersCnt, compOnlyTeamsCnt;
si8 playersCnt, teamsCnt, compOnlyPlayersCnt, compOnlyTeamsCnt;
EWaterContent::EWaterContent waterContent;
EMonsterStrength::EMonsterStrength monsterStrength;
std::map<PlayerColor, CPlayerSettings> players;
std::map<PlayerColor, CPlayerSettings> players;
public:
template <typename Handler>
@ -158,6 +158,6 @@ public:
//FIXME: Enum is not a fixed with data type. Add enum class to both enums
// later. For now it is ok.
h & width & height & hasTwoLevels & playersCnt & teamsCnt & compOnlyPlayersCnt;
h & compOnlyTeamsCnt & waterContent & monsterStrength & players;
h & compOnlyTeamsCnt & waterContent & monsterStrength & players;
}
};

View File

@ -12,9 +12,9 @@
#include "../StringConstants.h"
CMapGenerator::CMapGenerator(const CMapGenOptions & mapGenOptions, int randomSeed) :
mapGenOptions(mapGenOptions), randomSeed(randomSeed)
mapGenOptions(mapGenOptions), randomSeed(randomSeed)
{
gen.seed(randomSeed);
gen.seed(randomSeed);
}
CMapGenerator::~CMapGenerator()
@ -24,7 +24,7 @@ CMapGenerator::~CMapGenerator()
std::unique_ptr<CMap> CMapGenerator::generate()
{
mapGenOptions.finalize(gen);
mapGenOptions.finalize(gen);
//TODO select a template based on the map gen options or adapt it if necessary
@ -52,17 +52,17 @@ std::string CMapGenerator::getMapDescription() const
ss << static_cast<int>(mapGenOptions.getCompOnlyPlayersCnt()) << ", water " << waterContentStr[mapGenOptions.getWaterContent()];
ss << ", monster " << monsterStrengthStr[mapGenOptions.getMonsterStrength()] << ", second expansion map";
BOOST_FOREACH(const auto & pair, mapGenOptions.getPlayersSettings())
BOOST_FOREACH(const auto & pair, mapGenOptions.getPlayersSettings())
{
const auto & pSettings = pair.second;
if(pSettings.getPlayerType() == EPlayerType::HUMAN)
const auto & pSettings = pair.second;
if(pSettings.getPlayerType() == EPlayerType::HUMAN)
{
ss << ", " << GameConstants::PLAYER_COLOR_NAMES[pSettings.getColor().getNum()] << " is human";
}
if(pSettings.getStartingTown() != CMapGenOptions::CPlayerSettings::RANDOM_TOWN)
if(pSettings.getStartingTown() != CMapGenOptions::CPlayerSettings::RANDOM_TOWN)
{
ss << ", " << GameConstants::PLAYER_COLOR_NAMES[pSettings.getColor().getNum()]
<< " town choice is " << ETownType::names[pSettings.getStartingTown()];
<< " town choice is " << ETownType::names[pSettings.getStartingTown()];
}
}
@ -105,12 +105,12 @@ void CMapGenerator::addPlayerInfo()
}
// Team numbers are assigned randomly to every player
BOOST_FOREACH(const auto & pair, mapGenOptions.getPlayersSettings())
BOOST_FOREACH(const auto & pair, mapGenOptions.getPlayersSettings())
{
const auto & pSettings = pair.second;
const auto & pSettings = pair.second;
PlayerInfo player;
player.canComputerPlay = true;
int j = pSettings.getPlayerType() == EPlayerType::COMP_ONLY ? 1 : 0;
int j = pSettings.getPlayerType() == EPlayerType::COMP_ONLY ? 1 : 0;
if(j == 0)
{
player.canHumanPlay = true;
@ -136,15 +136,15 @@ void CMapGenerator::genTowns()
{
//FIXME mock gen
const int3 townPos[2] = { int3(17, 13, 0), int3(25,13, 0) };
const int townTypes[2] = { ETownType::CASTLE, ETownType::DUNGEON };
const int townTypes[2] = { ETownType::CASTLE, ETownType::DUNGEON };
for(size_t i = 0; i < map->players.size(); ++i)
for(size_t i = 0; i < map->players.size(); ++i)
{
auto & playerInfo = map->players[i];
if(!playerInfo.canAnyonePlay()) break;
auto & playerInfo = map->players[i];
if(!playerInfo.canAnyonePlay()) break;
PlayerColor owner(i);
int side = i % 2;
PlayerColor owner(i);
int side = i % 2;
CGTownInstance * town = new CGTownInstance();
town->ID = Obj::TOWN;
town->subID = townTypes[side];
@ -152,14 +152,14 @@ void CMapGenerator::genTowns()
town->defInfo = VLC->dobjinfo->gobjs[town->ID][town->subID];
town->builtBuildings.insert(BuildingID::FORT);
town->builtBuildings.insert(BuildingID::DEFAULT);
mapMgr->insertObject(town, townPos[side].x, townPos[side].y + (i / 2) * 5, false);
mapMgr->insertObject(town, townPos[side].x, townPos[side].y + (i / 2) * 5, false);
// Update player info
playerInfo.allowedFactions.clear();
playerInfo.allowedFactions.insert(townTypes[side]);
playerInfo.hasMainTown = true;
playerInfo.posOfMainTown = town->pos - int3(2, 0, 0);
playerInfo.generateHeroAtMainTown = true;
playerInfo.allowedFactions.clear();
playerInfo.allowedFactions.insert(townTypes[side]);
playerInfo.hasMainTown = true;
playerInfo.posOfMainTown = town->pos - int3(2, 0, 0);
playerInfo.generateHeroAtMainTown = true;
}
}

View File

@ -23,16 +23,16 @@ class CMapEditManager;
class DLL_LINKAGE CMapGenerator
{
public:
CMapGenerator(const CMapGenOptions & mapGenOptions, int randomSeed);
~CMapGenerator(); // required due to unique_ptr
CMapGenerator(const CMapGenOptions & mapGenOptions, int randomSeed);
~CMapGenerator(); // required due to unique_ptr
std::unique_ptr<CMap> generate();
private:
/// Generation methods
std::string getMapDescription() const;
void addPlayerInfo();
void addHeaderInfo();
/// Generation methods
std::string getMapDescription() const;
void addPlayerInfo();
void addHeaderInfo();
void genTerrain();
void genTowns();
@ -41,5 +41,5 @@ private:
CRandomGenerator gen;
int randomSeed;
std::unique_ptr<CTerrainViewPatternConfig> terViewPatternConfig;
std::unique_ptr<CMapEditManager> mapMgr;
std::unique_ptr<CMapEditManager> mapMgr;
};