add basic c++ project setup

This commit is contained in:
2026-04-19 10:19:27 +02:00
parent 1e1f2d7816
commit 8b740dfe8e
36 changed files with 16842 additions and 0 deletions

View 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
)

View 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
)

View 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;
}

View 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

View 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)
{
}

View 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

View 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;
}

View 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

View 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

View 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);
}
}

View 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

View 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

View 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
)

View 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;
}

View 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

View 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;
}

View 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

View 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

View 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();
}
}

View 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