2021-11-27 00:53:57 +01:00
|
|
|
#pragma once
|
2019-01-19 21:20:23 -02:00
|
|
|
|
|
|
|
#include "Forwards.h"
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <chrono>
|
|
|
|
#include <random>
|
|
|
|
#include <memory>
|
|
|
|
#include <type_traits>
|
|
|
|
|
|
|
|
namespace Sapphire::World::Manager
|
|
|
|
{
|
|
|
|
/*!
|
|
|
|
* @brief Generator object that is used on multiple state situations
|
|
|
|
*/
|
|
|
|
template< typename T, typename = typename std::enable_if< std::is_arithmetic< T >::value, T >::type >
|
|
|
|
class RandGenerator
|
|
|
|
{
|
|
|
|
public:
|
2021-11-27 00:53:57 +01:00
|
|
|
RandGenerator( std::shared_ptr< std::mt19937 > pEngine, T minRange = std::numeric_limits< T >::min(), T maxRange = std::numeric_limits< T >::max() )
|
|
|
|
: m_engine( pEngine ), m_dist( minRange, maxRange )
|
2019-01-19 21:20:23 -02:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
T next()
|
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
return m_dist( *m_engine );
|
2019-01-19 21:20:23 -02:00
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
private:
|
2019-01-19 21:20:23 -02:00
|
|
|
std::uniform_real_distribution< T > m_dist;
|
2021-11-27 00:53:57 +01:00
|
|
|
std::shared_ptr< std::mt19937 > m_engine;
|
2019-01-19 21:20:23 -02:00
|
|
|
};
|
|
|
|
|
2020-03-01 01:00:57 +11:00
|
|
|
class RNGMgr
|
2019-01-19 21:20:23 -02:00
|
|
|
{
|
|
|
|
public:
|
2021-11-27 00:53:57 +01:00
|
|
|
RNGMgr()
|
|
|
|
{
|
|
|
|
m_engine = std::make_shared< std::mt19937 >( *engineSeed< std::mt19937::state_size >() );
|
|
|
|
}
|
|
|
|
|
2019-01-19 21:20:23 -02:00
|
|
|
virtual ~RNGMgr() = default;
|
|
|
|
|
|
|
|
RNGMgr( const RNGMgr& pRNGMgr ) = delete;
|
|
|
|
RNGMgr& operator=( const RNGMgr& pRNGMgr ) = delete;
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* @brief Creates a RNG with specified parameters for multiple uses
|
|
|
|
* @tparam Numeric type to be used for the generator
|
|
|
|
* @param Minimum value possible for the random value
|
|
|
|
* @param Maximum value possible for the random value
|
|
|
|
* @return Random number generator object
|
|
|
|
*/
|
|
|
|
template< typename T, typename = typename std::enable_if< std::is_arithmetic< T >::value, T >::type >
|
|
|
|
RandGenerator< T > getRandGenerator( T minRange, T maxRange )
|
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
return RandGenerator< T >( m_engine, minRange, maxRange );
|
2019-01-19 21:20:23 -02:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
template< std::size_t STATE_SIZE >
|
|
|
|
std::unique_ptr< std::seed_seq > engineSeed()
|
|
|
|
{
|
2021-11-27 00:53:57 +01:00
|
|
|
// initialize mt engine with manually seeded random_device
|
|
|
|
|
2019-01-19 21:20:23 -02:00
|
|
|
std::array< uint32_t, STATE_SIZE > seedArray;
|
|
|
|
std::random_device rd;
|
|
|
|
|
|
|
|
std::generate_n( seedArray.data(), seedArray.size(), std::ref( rd ) );
|
|
|
|
auto pSeq = std::make_unique< std::seed_seq >( std::begin( seedArray ), std::end( seedArray ) );
|
|
|
|
|
|
|
|
return pSeq;
|
|
|
|
}
|
|
|
|
|
2021-11-27 00:53:57 +01:00
|
|
|
std::shared_ptr< std::mt19937 > m_engine;
|
2019-01-19 21:20:23 -02:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|