add basic c++ project setup
This commit is contained in:
21
src/lib/utility/CMakeLists.txt
Normal file
21
src/lib/utility/CMakeLists.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
add_subdirectory(logging)
|
||||
add_subdirectory(random)
|
||||
|
||||
|
||||
SET(HDRS
|
||||
${HDRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/utilityRandom.h
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
SET(SRCS
|
||||
${SRCS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/utilityRandom.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
SET(LIB_INCLUDE_PATH
|
||||
${LIB_INCLUDE_PATH}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
25
src/lib/utility/logging/CMakeLists.txt
Normal file
25
src/lib/utility/logging/CMakeLists.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
SET(HDRS
|
||||
${HDRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ConsoleLogger.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Logger.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/logging.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/LogManager.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/LogManagerImplementation.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/LogMessage.h
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
SET(SRCS
|
||||
${SRCS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ConsoleLogger.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Logger.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/LogManager.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/LogManagerImplementation.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
set(LIB_INCLUDE_PATH
|
||||
${LIB_INCLUDE_PATH}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
39
src/lib/utility/logging/ConsoleLogger.cpp
Normal file
39
src/lib/utility/logging/ConsoleLogger.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "ConsoleLogger.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
ConsoleLogger::ConsoleLogger()
|
||||
: Logger("ConsoleLogger")
|
||||
{
|
||||
}
|
||||
|
||||
ConsoleLogger::~ConsoleLogger()
|
||||
{
|
||||
}
|
||||
|
||||
void ConsoleLogger::logInfo(const LogMessage& message)
|
||||
{
|
||||
logMessage("INFO", message);
|
||||
}
|
||||
|
||||
void ConsoleLogger::logWarning(const LogMessage& message)
|
||||
{
|
||||
logMessage("WARNING", message);
|
||||
}
|
||||
|
||||
void ConsoleLogger::logError(const LogMessage& message)
|
||||
{
|
||||
logMessage("ERROR", message);
|
||||
}
|
||||
|
||||
void ConsoleLogger::logMessage(const std::string& type, const LogMessage& message)
|
||||
{
|
||||
std::cout << message.getTimeString("%H:%M:%S") << " | ";
|
||||
|
||||
if (message.filePath.size())
|
||||
{
|
||||
std::cout << message.getFileName() << ':' << message.line << ' ' << message.functionName << "() | ";
|
||||
}
|
||||
|
||||
std::cout << type << ": " << message.message << std::endl;
|
||||
}
|
||||
21
src/lib/utility/logging/ConsoleLogger.h
Normal file
21
src/lib/utility/logging/ConsoleLogger.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef CONSOLE_LOGGER_H
|
||||
#define CONSOLE_LOGGER_H
|
||||
|
||||
#include "Logger.h"
|
||||
#include "LogMessage.h"
|
||||
|
||||
class ConsoleLogger: public Logger
|
||||
{
|
||||
public:
|
||||
ConsoleLogger();
|
||||
~ConsoleLogger();
|
||||
|
||||
private:
|
||||
virtual void logInfo(const LogMessage& message);
|
||||
virtual void logWarning(const LogMessage& message);
|
||||
virtual void logError(const LogMessage& message);
|
||||
|
||||
void logMessage(const std::string& type, const LogMessage& message);
|
||||
};
|
||||
|
||||
#endif // CONSOLE_LOGGER_H
|
||||
110
src/lib/utility/logging/LogManager.cpp
Normal file
110
src/lib/utility/logging/LogManager.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#include "LogManager.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "LogMessage.h"
|
||||
#include "logging.h"
|
||||
|
||||
std::shared_ptr<LogManager> LogManager::getInstance()
|
||||
{
|
||||
if (s_instance.use_count() == 0)
|
||||
{
|
||||
s_instance = std::shared_ptr<LogManager>(new LogManager());
|
||||
}
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void LogManager::destroyInstance()
|
||||
{
|
||||
s_instance.reset();
|
||||
}
|
||||
|
||||
LogManager::~LogManager()
|
||||
{
|
||||
}
|
||||
|
||||
void LogManager::setLoggingEnabled(bool enabled)
|
||||
{
|
||||
m_loggingEnabled = enabled;
|
||||
}
|
||||
|
||||
void LogManager::addLogger(std::shared_ptr<Logger> logger)
|
||||
{
|
||||
m_logManagerImplementation.addLogger(logger);
|
||||
}
|
||||
|
||||
void LogManager::removeLogger(std::shared_ptr<Logger> logger)
|
||||
{
|
||||
m_logManagerImplementation.removeLogger(logger);
|
||||
}
|
||||
|
||||
void LogManager::removeLoggersByType(const std::string& type)
|
||||
{
|
||||
m_logManagerImplementation.removeLoggersByType(type);
|
||||
}
|
||||
|
||||
Logger* LogManager::getLogger(std::shared_ptr<Logger> logger)
|
||||
{
|
||||
return m_logManagerImplementation.getLogger(logger);
|
||||
}
|
||||
|
||||
Logger* LogManager::getLoggerByType(const std::string& type)
|
||||
{
|
||||
return m_logManagerImplementation.getLoggerByType(type);
|
||||
}
|
||||
|
||||
void LogManager::clearLoggers()
|
||||
{
|
||||
m_logManagerImplementation.clearLoggers();
|
||||
}
|
||||
|
||||
int LogManager::getLoggerCount() const
|
||||
{
|
||||
return m_logManagerImplementation.getLoggerCount();
|
||||
}
|
||||
|
||||
void LogManager::logInfo(
|
||||
const std::string& message,
|
||||
const std::string& file,
|
||||
const std::string& function,
|
||||
const unsigned int line
|
||||
)
|
||||
{
|
||||
if (m_loggingEnabled)
|
||||
{
|
||||
m_logManagerImplementation.logInfo(message, file, function, line);
|
||||
}
|
||||
}
|
||||
|
||||
void LogManager::logWarning(
|
||||
const std::string& message,
|
||||
const std::string& file,
|
||||
const std::string& function,
|
||||
const unsigned int line
|
||||
)
|
||||
{
|
||||
if (m_loggingEnabled)
|
||||
{
|
||||
m_logManagerImplementation.logWarning(message, file, function, line);
|
||||
}
|
||||
}
|
||||
|
||||
void LogManager::logError(
|
||||
const std::string& message,
|
||||
const std::string& file,
|
||||
const std::string& function,
|
||||
const unsigned int line
|
||||
)
|
||||
{
|
||||
if (m_loggingEnabled)
|
||||
{
|
||||
m_logManagerImplementation.logError(message, file, function, line);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<LogManager> LogManager::s_instance;
|
||||
|
||||
LogManager::LogManager()
|
||||
: m_loggingEnabled(false)
|
||||
{
|
||||
}
|
||||
57
src/lib/utility/logging/LogManager.h
Normal file
57
src/lib/utility/logging/LogManager.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#ifndef LOG_MANAGER_H
|
||||
#define LOG_MANAGER_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "Logger.h"
|
||||
#include "LogManagerImplementation.h"
|
||||
|
||||
class LogManager
|
||||
{
|
||||
public:
|
||||
static std::shared_ptr<LogManager> getInstance();
|
||||
static void destroyInstance();
|
||||
|
||||
~LogManager();
|
||||
|
||||
void setLoggingEnabled(bool enabled);
|
||||
|
||||
void addLogger(std::shared_ptr<Logger> logger);
|
||||
void removeLogger(std::shared_ptr<Logger> logger);
|
||||
void removeLoggersByType(const std::string& type);
|
||||
void clearLoggers();
|
||||
int getLoggerCount() const;
|
||||
Logger* getLoggerByType(const std::string& type);
|
||||
Logger* getLogger(std::shared_ptr<Logger> logger);
|
||||
|
||||
void logInfo(
|
||||
const std::string& message,
|
||||
const std::string& file,
|
||||
const std::string& function,
|
||||
const unsigned int line
|
||||
);
|
||||
void logWarning(
|
||||
const std::string& message,
|
||||
const std::string& file,
|
||||
const std::string& function,
|
||||
const unsigned int line
|
||||
);
|
||||
void logError(
|
||||
const std::string& message,
|
||||
const std::string& file,
|
||||
const std::string& function,
|
||||
const unsigned int line
|
||||
);
|
||||
|
||||
private:
|
||||
static std::shared_ptr<LogManager> s_instance;
|
||||
|
||||
LogManager();
|
||||
LogManager(const LogManager&);
|
||||
void operator=(const LogManager&);
|
||||
|
||||
LogManagerImplementation m_logManagerImplementation;
|
||||
bool m_loggingEnabled;
|
||||
};
|
||||
|
||||
#endif // LOG_MANAGER_H
|
||||
136
src/lib/utility/logging/LogManagerImplementation.cpp
Normal file
136
src/lib/utility/logging/LogManagerImplementation.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#include "LogManagerImplementation.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
LogManagerImplementation::LogManagerImplementation()
|
||||
{
|
||||
}
|
||||
|
||||
LogManagerImplementation::LogManagerImplementation(const LogManagerImplementation& other)
|
||||
{
|
||||
m_loggers = other.m_loggers;
|
||||
}
|
||||
|
||||
void LogManagerImplementation::operator=(const LogManagerImplementation& other)
|
||||
{
|
||||
m_loggers = other.m_loggers;
|
||||
}
|
||||
|
||||
LogManagerImplementation::~LogManagerImplementation()
|
||||
{
|
||||
}
|
||||
|
||||
void LogManagerImplementation::addLogger(std::shared_ptr<Logger> logger)
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuard(m_loggerMutex);
|
||||
m_loggers.push_back(logger);
|
||||
}
|
||||
|
||||
void LogManagerImplementation::removeLogger(std::shared_ptr<Logger> logger)
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuard(m_loggerMutex);
|
||||
std::vector<std::shared_ptr<Logger>>::iterator it = std::find(m_loggers.begin(), m_loggers.end(), logger);
|
||||
if (it != m_loggers.end())
|
||||
{
|
||||
m_loggers.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void LogManagerImplementation::removeLoggersByType(const std::string& type)
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuard(m_loggerMutex);
|
||||
for (unsigned int i = 0; i < m_loggers.size(); i++)
|
||||
{
|
||||
if (m_loggers[i]->getType() == type)
|
||||
{
|
||||
m_loggers.erase(m_loggers.begin() + i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Logger* LogManagerImplementation::getLogger(std::shared_ptr<Logger> logger)
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuard(m_loggerMutex);
|
||||
std::vector<std::shared_ptr<Logger>>::iterator it = std::find(m_loggers.begin(), m_loggers.end(), logger);
|
||||
if (it != m_loggers.end())
|
||||
{
|
||||
return (*it).get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Logger* LogManagerImplementation::getLoggerByType(const std::string& type)
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuard(m_loggerMutex);
|
||||
for (unsigned int i = 0; i < m_loggers.size(); i++)
|
||||
{
|
||||
if (m_loggers[i]->getType() == type)
|
||||
{
|
||||
|
||||
return m_loggers[i].get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void LogManagerImplementation::clearLoggers()
|
||||
{
|
||||
m_loggers.clear();
|
||||
}
|
||||
|
||||
int LogManagerImplementation::getLoggerCount() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuard(m_loggerMutex);
|
||||
return m_loggers.size();
|
||||
}
|
||||
|
||||
void LogManagerImplementation::logInfo(
|
||||
const std::string& message,
|
||||
const std::string& file,
|
||||
const std::string& function,
|
||||
const unsigned int line
|
||||
)
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuardLogger(m_loggerMutex);
|
||||
for (unsigned int i = 0; i < m_loggers.size(); i++)
|
||||
{
|
||||
m_loggers[i]->onInfo(LogMessage(message, file, function, line, getTime(), std::this_thread::get_id()));
|
||||
}
|
||||
}
|
||||
|
||||
void LogManagerImplementation::logWarning(
|
||||
const std::string& message,
|
||||
const std::string& file,
|
||||
const std::string& function,
|
||||
const unsigned int line
|
||||
)
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuardLogger(m_loggerMutex);
|
||||
for (unsigned int i = 0; i < m_loggers.size(); i++)
|
||||
{
|
||||
m_loggers[i]->onWarning(LogMessage(message, file, function, line, getTime(), std::this_thread::get_id()));
|
||||
}
|
||||
}
|
||||
|
||||
void LogManagerImplementation::logError(
|
||||
const std::string& message,
|
||||
const std::string& file,
|
||||
const std::string& function,
|
||||
const unsigned int line
|
||||
)
|
||||
{
|
||||
std::lock_guard<std::mutex> lockGuardLogger(m_loggerMutex);
|
||||
for (unsigned int i = 0; i < m_loggers.size(); i++)
|
||||
{
|
||||
m_loggers[i]->onError(LogMessage(message, file, function, line, getTime(), std::this_thread::get_id()));
|
||||
}
|
||||
}
|
||||
|
||||
tm LogManagerImplementation::getTime()
|
||||
{
|
||||
time_t time;
|
||||
std::time(&time);
|
||||
tm result = *std::localtime(&time); // this is done because localtime returns a pointer to a statically allocated object
|
||||
return result;
|
||||
}
|
||||
59
src/lib/utility/logging/LogManagerImplementation.h
Normal file
59
src/lib/utility/logging/LogManagerImplementation.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef LOG_MANAGER_IMPLEMENTATION_H
|
||||
#define LOG_MANAGER_IMPLEMENTATION_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#include "Logger.h"
|
||||
|
||||
class LogManagerImplementation
|
||||
{
|
||||
public:
|
||||
LogManagerImplementation();
|
||||
|
||||
// Must be implemented because std::mutex is non-copyable, see
|
||||
// http://stackoverflow.com/questions/14263836/why-does-stdmutex-create-a-c2248-when-used-in-a-struct-with-windows-socket
|
||||
// for more details
|
||||
LogManagerImplementation(const LogManagerImplementation& other);
|
||||
void operator=(const LogManagerImplementation& other);
|
||||
|
||||
~LogManagerImplementation();
|
||||
|
||||
void addLogger(std::shared_ptr<Logger> logger);
|
||||
void removeLogger(std::shared_ptr<Logger> logger);
|
||||
void removeLoggersByType(const std::string& type);
|
||||
void clearLoggers();
|
||||
int getLoggerCount() const;
|
||||
Logger* getLogger(std::shared_ptr<Logger> logger);
|
||||
Logger* getLoggerByType(const std::string& type);
|
||||
|
||||
void logInfo(
|
||||
const std::string& message,
|
||||
const std::string& file,
|
||||
const std::string& function,
|
||||
const unsigned int line
|
||||
);
|
||||
void logWarning(
|
||||
const std::string& message,
|
||||
const std::string& file,
|
||||
const std::string& function,
|
||||
const unsigned int line
|
||||
);
|
||||
void logError(
|
||||
const std::string& message,
|
||||
const std::string& file,
|
||||
const std::string& function,
|
||||
const unsigned int line
|
||||
);
|
||||
|
||||
private:
|
||||
tm getTime();
|
||||
|
||||
std::vector<std::shared_ptr<Logger> > m_loggers;
|
||||
|
||||
mutable std::mutex m_loggerMutex;
|
||||
};
|
||||
|
||||
#endif // LOG_MANAGER_IMPLEMENTATION_H
|
||||
48
src/lib/utility/logging/LogMessage.h
Normal file
48
src/lib/utility/logging/LogMessage.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef LOG_MESSAGE_H
|
||||
#define LOG_MESSAGE_H
|
||||
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
struct LogMessage
|
||||
{
|
||||
public:
|
||||
LogMessage(
|
||||
const std::string& message,
|
||||
const std::string& filePath,
|
||||
const std::string& functionName,
|
||||
const unsigned int line,
|
||||
const std::tm& time,
|
||||
const std::thread::id& threadId
|
||||
)
|
||||
: message(message)
|
||||
, filePath(filePath)
|
||||
, functionName(functionName)
|
||||
, line(line)
|
||||
, time(time)
|
||||
, threadId(threadId)
|
||||
{}
|
||||
|
||||
std::string getTimeString(const std::string& format) const
|
||||
{
|
||||
char timeString[50];
|
||||
strftime(timeString, 50, format.c_str(), &time);
|
||||
std::string temp(timeString);
|
||||
return std::string(temp.begin(), temp.end());
|
||||
}
|
||||
|
||||
std::string getFileName() const
|
||||
{
|
||||
return filePath.substr(filePath.find_last_of("/\\") + 1);
|
||||
}
|
||||
|
||||
const std::string message;
|
||||
const std::string filePath;
|
||||
const std::string functionName;
|
||||
const unsigned int line;
|
||||
const std::tm time;
|
||||
const std::thread::id threadId;
|
||||
};
|
||||
|
||||
#endif // LOG_MESSAGE_H
|
||||
55
src/lib/utility/logging/Logger.cpp
Normal file
55
src/lib/utility/logging/Logger.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#include "Logger.h"
|
||||
|
||||
Logger::Logger(const std::string& type)
|
||||
: m_type(type)
|
||||
, m_levelMask(LOG_ALL)
|
||||
{
|
||||
}
|
||||
|
||||
Logger::~Logger()
|
||||
{
|
||||
}
|
||||
|
||||
std::string Logger::getType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
Logger::LogLevelMask Logger::getLogLevel() const
|
||||
{
|
||||
return m_levelMask;
|
||||
}
|
||||
|
||||
void Logger::setLogLevel(LogLevelMask mask)
|
||||
{
|
||||
m_levelMask = mask;
|
||||
}
|
||||
|
||||
bool Logger::isLogLevel(LogLevelMask mask)
|
||||
{
|
||||
return (m_levelMask & mask) > 0;
|
||||
}
|
||||
|
||||
void Logger::onInfo(const LogMessage& message)
|
||||
{
|
||||
if (isLogLevel(LOG_INFOS))
|
||||
{
|
||||
logInfo(message);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::onWarning(const LogMessage& message)
|
||||
{
|
||||
if (isLogLevel(LOG_WARNINGS))
|
||||
{
|
||||
logWarning(message);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::onError(const LogMessage& message)
|
||||
{
|
||||
if (isLogLevel(LOG_ERRORS))
|
||||
{
|
||||
logError(message);
|
||||
}
|
||||
}
|
||||
43
src/lib/utility/logging/Logger.h
Normal file
43
src/lib/utility/logging/Logger.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "LogMessage.h"
|
||||
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
typedef int LogLevelMask;
|
||||
enum LogLevel : int
|
||||
{
|
||||
LOG_INFOS = 0x1,
|
||||
LOG_WARNINGS = 0x2,
|
||||
LOG_ERRORS = 0x4,
|
||||
LOG_ALL = 0x7
|
||||
};
|
||||
|
||||
Logger(const std::string& type);
|
||||
virtual ~Logger();
|
||||
|
||||
std::string getType() const;
|
||||
|
||||
LogLevelMask getLogLevel() const;
|
||||
void setLogLevel(LogLevelMask mask);
|
||||
bool isLogLevel(LogLevelMask mask);
|
||||
|
||||
void onInfo(const LogMessage& message);
|
||||
void onWarning(const LogMessage& message);
|
||||
void onError(const LogMessage& message);
|
||||
|
||||
private:
|
||||
virtual void logInfo(const LogMessage& message) = 0;
|
||||
virtual void logWarning(const LogMessage& message) = 0;
|
||||
virtual void logError(const LogMessage& message) = 0;
|
||||
|
||||
const std::string m_type;
|
||||
LogLevelMask m_levelMask;
|
||||
};
|
||||
|
||||
#endif // LOGGER_H
|
||||
86
src/lib/utility/logging/logging.h
Normal file
86
src/lib/utility/logging/logging.h
Normal file
@@ -0,0 +1,86 @@
|
||||
#ifndef LOGGING_H
|
||||
#define LOGGING_H
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "LogManager.h"
|
||||
|
||||
/**
|
||||
* @brief Makros to simplify usage of the log manager
|
||||
*/
|
||||
#define LOG_INFO(__str__) \
|
||||
do \
|
||||
{ \
|
||||
LogManager::getInstance()->logInfo(__str__, __FILE__, __FUNCTION__, __LINE__); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define LOG_WARNING(__str__) \
|
||||
do \
|
||||
{ \
|
||||
LogManager::getInstance()->logWarning(__str__, __FILE__, __FUNCTION__, __LINE__); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define LOG_ERROR(__str__) \
|
||||
do \
|
||||
{ \
|
||||
LogManager::getInstance()->logError(__str__, __FILE__, __FUNCTION__, __LINE__); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define LOG_INFO_STREAM(__s__) \
|
||||
do \
|
||||
{ \
|
||||
std::stringstream __ss__; \
|
||||
__ss__ __s__; \
|
||||
LogManager::getInstance()->logInfo(__ss__.str(), __FILE__, __FUNCTION__, __LINE__); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define LOG_WARNING_STREAM(__s__) \
|
||||
do \
|
||||
{ \
|
||||
std::stringstream __ss__; \
|
||||
__ss__ __s__; \
|
||||
LogManager::getInstance()->logWarning(__ss__.str(), __FILE__, __FUNCTION__, __LINE__); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define LOG_ERROR_STREAM(__s__) \
|
||||
do \
|
||||
{ \
|
||||
std::stringstream __ss__; \
|
||||
__ss__ __s__; \
|
||||
LogManager::getInstance()->logError(__ss__.str(), __FILE__, __FUNCTION__, __LINE__); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define LOG_INFO_STREAM_BARE(__s__) \
|
||||
do \
|
||||
{ \
|
||||
std::stringstream __ss__; \
|
||||
__ss__ __s__; \
|
||||
LogManager::getInstance()->logInfo(__ss__.str(), "", "", 0); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define LOG_WARNING_STREAM_BARE(__s__) \
|
||||
do \
|
||||
{ \
|
||||
std::stringstream __ss__; \
|
||||
__ss__ __s__; \
|
||||
LogManager::getInstance()->logWarning(__ss__.str(), "", "", 0); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define LOG_ERROR_STREAM_BARE(__s__) \
|
||||
do \
|
||||
{ \
|
||||
std::stringstream __ss__; \
|
||||
__ss__ __s__; \
|
||||
LogManager::getInstance()->logError(__ss__.str(), "", "", 0); \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#endif // LOGGING_H
|
||||
20
src/lib/utility/random/CMakeLists.txt
Normal file
20
src/lib/utility/random/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
SET(HDRS
|
||||
${HDRS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/RandomNumberGenerator.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/WeightedRandomGenerator.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/RandomBinaryFunction.h
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
SET(SRCS
|
||||
${SRCS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/RandomNumberGenerator.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/RandomBinaryFunction.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
set(LIB_INCLUDE_PATH
|
||||
${LIB_INCLUDE_PATH}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
29
src/lib/utility/random/RandomBinaryFunction.cpp
Normal file
29
src/lib/utility/random/RandomBinaryFunction.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#include "RandomBinaryFunction.h"
|
||||
|
||||
#include "utilityRandom.h"
|
||||
|
||||
RandomBinaryFunction::RandomBinaryFunction(float resolution_s, float stateChangeProbability)
|
||||
: m_resolution_s(resolution_s)
|
||||
, m_stateChangeProbability(stateChangeProbability)
|
||||
, m_passedTime_s(0.0f)
|
||||
, m_value(utility::getRandomBool())
|
||||
{
|
||||
}
|
||||
|
||||
void RandomBinaryFunction::update(float deltaTime_s)
|
||||
{
|
||||
m_passedTime_s += deltaTime_s;
|
||||
while (m_passedTime_s >= m_resolution_s)
|
||||
{
|
||||
m_passedTime_s -= m_resolution_s;
|
||||
if (utility::getRandomFloat() >= m_stateChangeProbability)
|
||||
{
|
||||
m_value = !m_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RandomBinaryFunction::getValue() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
19
src/lib/utility/random/RandomBinaryFunction.h
Normal file
19
src/lib/utility/random/RandomBinaryFunction.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef RANDOM_BINARY_FUNCTION_H
|
||||
#define RANDOM_BINARY_FUNCTION_H
|
||||
|
||||
class RandomBinaryFunction
|
||||
{
|
||||
public:
|
||||
RandomBinaryFunction(float resolution_s, float stateChangeProbability);
|
||||
|
||||
void update(float deltaTime_s);
|
||||
bool getValue() const;
|
||||
|
||||
private:
|
||||
const float m_resolution_s;
|
||||
const float m_stateChangeProbability;
|
||||
float m_passedTime_s;
|
||||
bool m_value;
|
||||
};
|
||||
|
||||
#endif // RANDOM_BINARY_FUNCTION_H
|
||||
68
src/lib/utility/random/RandomNumberGenerator.cpp
Normal file
68
src/lib/utility/random/RandomNumberGenerator.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include "RandomNumberGenerator.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
namespace
|
||||
{
|
||||
int randInt()
|
||||
{
|
||||
static bool initialized = false;
|
||||
if (!initialized)
|
||||
{
|
||||
std::srand(std::time(nullptr));
|
||||
initialized = true;
|
||||
}
|
||||
return std::rand();
|
||||
}
|
||||
}
|
||||
|
||||
RandomNumberGenerator::RandomNumberGenerator(unsigned int seed):
|
||||
m_seed(seed),
|
||||
m_value(seed),
|
||||
m_a(214013),
|
||||
m_b(2531011),
|
||||
m_m(2147483647)
|
||||
{
|
||||
}
|
||||
|
||||
void RandomNumberGenerator::setSeed(unsigned int seed)
|
||||
{
|
||||
m_seed = seed;
|
||||
reset();
|
||||
}
|
||||
|
||||
void RandomNumberGenerator::reset()
|
||||
{
|
||||
m_value = m_seed;
|
||||
}
|
||||
|
||||
int RandomNumberGenerator::getInt(int min, int max)
|
||||
{
|
||||
return min + (randInt() % (max - min + 1));
|
||||
//return min + (getNext() % (max - min + 1));
|
||||
}
|
||||
|
||||
unsigned int RandomNumberGenerator::getUnsignedInt(unsigned int min, unsigned int max)
|
||||
{
|
||||
return min + (randInt() % (max - min + 1));
|
||||
//return min + (getNext() % (max - min + 1));
|
||||
}
|
||||
|
||||
float RandomNumberGenerator::getFloat(float min, float max)
|
||||
{
|
||||
const int resolution = RAND_MAX;
|
||||
return min + (max - min) * (static_cast<float>(randInt() % (resolution + 1)) / resolution);
|
||||
//return min + float(getNext()) / m_m * (max - min);
|
||||
}
|
||||
|
||||
bool RandomNumberGenerator::getBool()
|
||||
{
|
||||
return (randInt() % 2);
|
||||
//return (getFloat(0.0f, 1.0f) < 0.5f ? true : false);
|
||||
}
|
||||
|
||||
int RandomNumberGenerator::getNext()
|
||||
{
|
||||
return m_value = (m_a * m_value + m_b) % m_m;
|
||||
}
|
||||
27
src/lib/utility/random/RandomNumberGenerator.h
Normal file
27
src/lib/utility/random/RandomNumberGenerator.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef RANDOM_NUMBER_GENERATOR_H
|
||||
#define RANDOM_NUMBER_GENERATOR_H
|
||||
|
||||
class RandomNumberGenerator
|
||||
{
|
||||
public:
|
||||
RandomNumberGenerator(unsigned int seed);
|
||||
|
||||
void setSeed(unsigned int seed);
|
||||
void reset();
|
||||
|
||||
int getInt(int min, int max);
|
||||
unsigned int getUnsignedInt(unsigned int min, unsigned int max);
|
||||
float getFloat(float min = 0.0f, float max = 1.0f);
|
||||
bool getBool();
|
||||
|
||||
private:
|
||||
int getNext();
|
||||
unsigned int m_seed;
|
||||
|
||||
unsigned int m_value;
|
||||
unsigned int m_a;
|
||||
unsigned int m_b;
|
||||
unsigned int m_m;
|
||||
};
|
||||
|
||||
#endif // RANDOM_NUMBER_GENERATOR_H
|
||||
133
src/lib/utility/random/WeightedRandomGenerator.h
Normal file
133
src/lib/utility/random/WeightedRandomGenerator.h
Normal file
@@ -0,0 +1,133 @@
|
||||
#ifndef WEIGHTED_RANDOM_GENERATOR_H
|
||||
#define WEIGHTED_RANDOM_GENERATOR_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "logging.h"
|
||||
#include "RandomNumberGenerator.h"
|
||||
|
||||
template <typename T>
|
||||
class WeightedRandomGenerator
|
||||
{
|
||||
public:
|
||||
WeightedRandomGenerator(unsigned int seed);
|
||||
|
||||
void setSeed(unsigned int seed);
|
||||
void reset();
|
||||
|
||||
bool hasResult(T value) const;
|
||||
bool hasResults() const;
|
||||
|
||||
void addResult(T value, float weight);
|
||||
T getResult();
|
||||
std::vector<T> getResults(int count, bool allowDuplicates);
|
||||
|
||||
private:
|
||||
RandomNumberGenerator m_randomGenerator;
|
||||
std::vector<std::pair<T, float>> m_results;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
WeightedRandomGenerator<T>::WeightedRandomGenerator(unsigned int seed):
|
||||
m_randomGenerator(seed)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void WeightedRandomGenerator<T>::setSeed(unsigned int seed)
|
||||
{
|
||||
m_randomGenerator.setSeed(seed);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void WeightedRandomGenerator<T>::reset()
|
||||
{
|
||||
m_randomGenerator.reset();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool WeightedRandomGenerator<T>::hasResult(T value) const
|
||||
{
|
||||
for (auto[v, p] : m_results)
|
||||
{
|
||||
if (v == value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool WeightedRandomGenerator<T>::hasResults() const
|
||||
{
|
||||
return !m_results.empty();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void WeightedRandomGenerator<T>::addResult(T value, float weight)
|
||||
{
|
||||
m_results.push_back(std::make_pair(value, weight));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T WeightedRandomGenerator<T>::getResult()
|
||||
{
|
||||
float summedWeights = 0;
|
||||
for (int i = 0; i < m_results.size(); i++)
|
||||
summedWeights += m_results[i].second;
|
||||
|
||||
float random = m_randomGenerator.getFloat(0.0f, summedWeights);
|
||||
|
||||
int index = 0;
|
||||
float weights = 0.0f;
|
||||
for (index = 0; index < m_results.size(); index++)
|
||||
{
|
||||
weights += m_results[index].second;
|
||||
if (weights >= random)
|
||||
break;
|
||||
}
|
||||
|
||||
return m_results[index].first;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> WeightedRandomGenerator<T>::getResults(int count, bool allowDuplicates)
|
||||
{
|
||||
if (!allowDuplicates && count > m_results.size())
|
||||
{
|
||||
LOG_WARNING("WeightedRandomGenerator has only " + std::to_string(m_results.size()) + " results. Unable to prevent duplicates for " + std::to_string(count) + " requested results.");
|
||||
allowDuplicates = true;
|
||||
}
|
||||
|
||||
std::vector<std::pair<T, float>> potentialResults = m_results;
|
||||
std::vector<T> results;
|
||||
|
||||
float summedWeights = 0;
|
||||
for (int i = 0; i < potentialResults.size(); i++)
|
||||
{
|
||||
summedWeights += potentialResults[i].second;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
float random = m_randomGenerator.getFloat(0.0f, summedWeights);
|
||||
|
||||
int index = 0;
|
||||
float weights = 0.0f;
|
||||
for (index = 0; index < potentialResults.size() - 1; index++)
|
||||
{
|
||||
weights += potentialResults[index].second;
|
||||
if (weights > random)
|
||||
break;
|
||||
}
|
||||
|
||||
results.push_back(potentialResults[index].first);
|
||||
summedWeights -= potentialResults[index].second;
|
||||
potentialResults.erase(potentialResults.begin() + index);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
#endif // WEIGHTED_RANDOM_GENERATOR_H
|
||||
24
src/lib/utility/utilityRandom.cpp
Normal file
24
src/lib/utility/utilityRandom.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include "RandomNumberGenerator.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
RandomNumberGenerator rng(0);
|
||||
}
|
||||
|
||||
namespace utility
|
||||
{
|
||||
int getRandomInt(int min, int max)
|
||||
{
|
||||
return rng.getInt(min, max);
|
||||
}
|
||||
|
||||
float getRandomFloat(float min = 0.0f, float max = 1.0f)
|
||||
{
|
||||
return rng.getFloat(min, max);
|
||||
}
|
||||
|
||||
bool getRandomBool()
|
||||
{
|
||||
return rng.getBool();
|
||||
}
|
||||
}
|
||||
11
src/lib/utility/utilityRandom.h
Normal file
11
src/lib/utility/utilityRandom.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef UTILITY_RANDOM_H
|
||||
#define UTILITY_RANDOM_H
|
||||
|
||||
namespace utility
|
||||
{
|
||||
int getRandomInt(int min, int max);
|
||||
float getRandomFloat(float min = 0.0f, float max = 1.0f);
|
||||
bool getRandomBool();
|
||||
}
|
||||
|
||||
#endif // UTILITY_RANDOM_H
|
||||
Reference in New Issue
Block a user