mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-01 08:27:46 +00:00
add templated int and real distribution to rngmgr; add func to return amount of random values; support untyped value deduction; use typed min/max ranges for unspecified type;
This commit is contained in:
parent
2f5d5e9d18
commit
92861799f8
3 changed files with 58 additions and 8 deletions
|
@ -45,6 +45,7 @@
|
||||||
#include "WorldServer.h"
|
#include "WorldServer.h"
|
||||||
|
|
||||||
#include "Session.h"
|
#include "Session.h"
|
||||||
|
#include <Manager/RNGMgr.h>
|
||||||
|
|
||||||
using namespace Sapphire::Network;
|
using namespace Sapphire::Network;
|
||||||
using namespace Sapphire::Network::Packets;
|
using namespace Sapphire::Network::Packets;
|
||||||
|
@ -177,6 +178,15 @@ void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr<
|
||||||
|
|
||||||
if( ( ( subCommand == "pos" ) || ( subCommand == "posr" ) ) && ( params != "" ) )
|
if( ( ( subCommand == "pos" ) || ( subCommand == "posr" ) ) && ( params != "" ) )
|
||||||
{
|
{
|
||||||
|
auto& rngMgr = Common::Service< RNGMgr >::ref();
|
||||||
|
auto state = rngMgr.getRandGenerator( 0, 10 );
|
||||||
|
auto arr = state.nextCount< 10 >();
|
||||||
|
|
||||||
|
for( auto val : arr )
|
||||||
|
{
|
||||||
|
Logger::info( std::to_string( val ) );
|
||||||
|
}
|
||||||
|
|
||||||
int32_t posX;
|
int32_t posX;
|
||||||
int32_t posY;
|
int32_t posY;
|
||||||
int32_t posZ;
|
int32_t posZ;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Sapphire::World::Manager
|
namespace Sapphire::World::Manager
|
||||||
{
|
{
|
||||||
|
@ -19,24 +20,47 @@ namespace Sapphire::World::Manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RandGenerator( std::shared_ptr< std::mt19937 > pEngine, T minRange = std::numeric_limits< T >::min(), T maxRange = std::numeric_limits< T >::max() )
|
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 )
|
: m_engine( pEngine ), m_fpuDist( minRange, maxRange ), m_intDist( minRange, maxRange )
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns a single value for T type on set ranges, deducing real or integer distribution from given numeric type
|
||||||
T next()
|
T next()
|
||||||
{
|
{
|
||||||
return m_dist( *m_engine );
|
if constexpr( std::is_integral< T >::value )
|
||||||
|
return m_intDist( *m_engine );
|
||||||
|
|
||||||
|
return m_fpuDist( *m_engine );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
// returns an array of size nSize with values type T on set ranges, deducing real or integer distribution from given numeric type
|
||||||
std::uniform_real_distribution< T > m_dist;
|
template< std::size_t nSize >
|
||||||
|
const std::array< T, nSize > nextCount()
|
||||||
|
{
|
||||||
|
std::array< T, nSize > _valPush;
|
||||||
|
|
||||||
|
for( auto i = 0; i < nSize; ++i )
|
||||||
|
{
|
||||||
|
if constexpr( std::is_integral< T >::value )
|
||||||
|
_valPush[ i ] = ( m_intDist( *m_engine ) );
|
||||||
|
else
|
||||||
|
_valPush[ i ] = ( m_fpuDist( *m_engine ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return _valPush;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::uniform_real_distribution<> m_fpuDist;
|
||||||
|
std::uniform_int_distribution<> m_intDist;
|
||||||
std::shared_ptr< std::mt19937 > m_engine;
|
std::shared_ptr< std::mt19937 > m_engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RNGMgr
|
class RNGMgr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// Constructs a manager to supply states for random integer and float distribution using a Mersenne Twister engine
|
||||||
RNGMgr()
|
RNGMgr()
|
||||||
{
|
{
|
||||||
m_engine = std::make_shared< std::mt19937 >( *engineSeed< std::mt19937::state_size >() );
|
m_engine = std::make_shared< std::mt19937 >( *engineSeed< std::mt19937::state_size >() );
|
||||||
|
@ -48,7 +72,7 @@ namespace Sapphire::World::Manager
|
||||||
RNGMgr& operator=( const RNGMgr& pRNGMgr ) = delete;
|
RNGMgr& operator=( const RNGMgr& pRNGMgr ) = delete;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Creates a RNG with specified parameters for multiple uses
|
* @brief Creates a state with specified parameters for multiple uses
|
||||||
* @tparam Numeric type to be used for the generator
|
* @tparam Numeric type to be used for the generator
|
||||||
* @param Minimum value possible for the random value
|
* @param Minimum value possible for the random value
|
||||||
* @param Maximum value possible for the random value
|
* @param Maximum value possible for the random value
|
||||||
|
@ -60,6 +84,17 @@ namespace Sapphire::World::Manager
|
||||||
return RandGenerator< T >( m_engine, minRange, maxRange );
|
return RandGenerator< T >( m_engine, minRange, maxRange );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Creates a state with only typed data arithmetic range
|
||||||
|
* @tparam Numeric type to be used for the generator and range (::min(), ::max() of numeric type)
|
||||||
|
* @return Random number generator object
|
||||||
|
*/
|
||||||
|
template< typename T, typename = typename std::enable_if< std::is_arithmetic< T >::value, T >::type >
|
||||||
|
RandGenerator< T > getRandGenerator()
|
||||||
|
{
|
||||||
|
return RandGenerator< T >( m_engine );
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template< std::size_t STATE_SIZE >
|
template< std::size_t STATE_SIZE >
|
||||||
|
@ -70,6 +105,11 @@ namespace Sapphire::World::Manager
|
||||||
std::array< uint32_t, STATE_SIZE > seedArray;
|
std::array< uint32_t, STATE_SIZE > seedArray;
|
||||||
std::random_device rd;
|
std::random_device rd;
|
||||||
|
|
||||||
|
// check if kernel can supply sufficiently non-deterministic output
|
||||||
|
|
||||||
|
if( rd.entropy() == 0.f )
|
||||||
|
Logger::error( "Kernel random device entropy reported zero - Random number generator may be poor quality" );
|
||||||
|
|
||||||
std::generate_n( seedArray.data(), seedArray.size(), std::ref( 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 ) );
|
auto pSeq = std::make_unique< std::seed_seq >( std::begin( seedArray ), std::end( seedArray ) );
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,9 @@ void WorldServer::run( int32_t argc, char* argv[] )
|
||||||
}
|
}
|
||||||
Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::set( pDb );
|
Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::set( pDb );
|
||||||
|
|
||||||
|
auto pRNGMgr = std::make_shared< Manager::RNGMgr >();
|
||||||
|
Common::Service< Manager::RNGMgr >::set( pRNGMgr );
|
||||||
|
|
||||||
Logger::info( "Loading all players" );
|
Logger::info( "Loading all players" );
|
||||||
if( !loadPlayers() )
|
if( !loadPlayers() )
|
||||||
{
|
{
|
||||||
|
@ -193,9 +196,6 @@ void WorldServer::run( int32_t argc, char* argv[] )
|
||||||
auto pNaviMgr = std::make_shared< Manager::NaviMgr >();
|
auto pNaviMgr = std::make_shared< Manager::NaviMgr >();
|
||||||
Common::Service< Manager::NaviMgr >::set( pNaviMgr );
|
Common::Service< Manager::NaviMgr >::set( pNaviMgr );
|
||||||
|
|
||||||
auto pRNGMgr = std::make_shared< Manager::RNGMgr >();
|
|
||||||
Common::Service< Manager::RNGMgr >::set( pRNGMgr );
|
|
||||||
|
|
||||||
Logger::info( "TerritoryMgr: Setting up zones" );
|
Logger::info( "TerritoryMgr: Setting up zones" );
|
||||||
auto pTeriMgr = std::make_shared< Manager::TerritoryMgr >();
|
auto pTeriMgr = std::make_shared< Manager::TerritoryMgr >();
|
||||||
auto pHousingMgr = std::make_shared< Manager::HousingMgr >();
|
auto pHousingMgr = std::make_shared< Manager::HousingMgr >();
|
||||||
|
|
Loading…
Add table
Reference in a new issue