| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- /*
- * Copyright (c) 2014, Oculus VR, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
- #include "RandSync.h"
- #include "BitStream.h"
- #include <limits>
- #include <limits.h>
- namespace RakNet
- {
- RakNetRandomSync::RakNetRandomSync()
- {
- seed = (uint32_t) -1;
- callCount = 0;
- usedValueBufferCount = 0;
- }
- RakNetRandomSync::~RakNetRandomSync()
- {
- }
- void RakNetRandomSync::SeedMT( uint32_t _seed )
- {
- seed = _seed;
- rnr.SeedMT( seed );
- callCount = 0;
- usedValueBufferCount = 0;
- }
- void RakNetRandomSync::SeedMT( uint32_t _seed, uint32_t skipValues )
- {
- SeedMT(_seed);
- Skip(skipValues);
- }
- float RakNetRandomSync::FrandomMT( void )
- {
- return ( float ) ( ( double ) RandomMT() / (double) UINT_MAX );
- }
- unsigned int RakNetRandomSync::RandomMT( void )
- {
- if (usedValueBufferCount > 0)
- {
- --usedValueBufferCount;
- if (usedValueBufferCount < usedValues.Size())
- {
- // The remote system had less calls than the current system, so return values from the past
- return usedValues[usedValues.Size()-usedValueBufferCount-1];
- }
- else
- {
- // Unknown past value, too far back
- // Return true random
- return rnr.RandomMT();
- }
- }
- else
- {
- // Get random number and store what it is
- usedValues.Push(rnr.RandomMT(), _FILE_AND_LINE_);
- ++callCount;
- while (usedValues.Size()>64)
- usedValues.Pop();
- return usedValues[usedValues.Size()-1];
- }
- }
- uint32_t RakNetRandomSync::GetSeed( void ) const
- {
- return seed;
- }
- uint32_t RakNetRandomSync::GetCallCount( void ) const
- {
- return callCount;
- }
- void RakNetRandomSync::SetCallCount( uint32_t i )
- {
- callCount = i;
- }
- void RakNetRandomSync::SerializeConstruction(RakNet::BitStream *constructionBitstream)
- {
- constructionBitstream->Write(seed);
- constructionBitstream->Write(callCount);
- }
- bool RakNetRandomSync::DeserializeConstruction(RakNet::BitStream *constructionBitstream)
- {
- uint32_t _seed;
- uint32_t _skipValues;
- constructionBitstream->Read(_seed);
- bool success = constructionBitstream->Read(_skipValues);
- if (success)
- SeedMT(_seed, _skipValues);
- return success;
- }
- void RakNetRandomSync::Serialize(RakNet::BitStream *outputBitstream)
- {
- outputBitstream->Write(callCount);
- }
- void RakNetRandomSync::Deserialize(RakNet::BitStream *outputBitstream)
- {
- uint32_t _callCount;
- outputBitstream->Read(_callCount);
- if (_callCount < callCount )
- {
- // We locally read more values than the remote system
- // The next n calls should come from buffered values
- usedValueBufferCount = callCount - _callCount;
- }
- else if (_callCount > callCount )
- {
- // Remote system read more values than us
- uint32_t diff = _callCount - callCount;
- if (diff <= usedValueBufferCount)
- usedValueBufferCount -= diff;
- if (diff > 0)
- Skip(diff);
- }
- }
- void RakNetRandomSync::Skip( uint32_t count )
- {
- for (uint32_t i = 0; i < count; i++)
- rnr.RandomMT();
- callCount+=count;
- }
- } // namespace RakNet
- /*
- RakNetRandomSync r1, r2;
- BitStream bsTest;
- r1.SeedMT(0);
- r1.SerializeConstruction(&bsTest);
- bsTest.SetReadOffset(0);
- r2.DeserializeConstruction(&bsTest);
- printf("1. (r1) %f\n", r1.FrandomMT());
- printf("1. (r2) %f\n", r2.FrandomMT());
- printf("2. (r1) %f\n", r1.FrandomMT());
- printf("2. (r2) %f\n", r2.FrandomMT());
- printf("3. (r1) %f\n", r1.FrandomMT());
- printf("3. (r2) %f\n", r2.FrandomMT());
- printf("4. (r1) %f\n", r1.FrandomMT());
- printf("4. (r2) %f\n", r2.FrandomMT());
- printf("5. (r2) %f\n", r2.FrandomMT());
- printf("6. (r2) %f\n", r2.FrandomMT());
- printf("7. (r2) %f\n", r2.FrandomMT());
- bsTest.Reset();
- r1.Serialize(&bsTest);
- bsTest.SetReadOffset(0);
- r2.Deserialize(&bsTest);
- printf("Synched r2 to match r1\n");
- printf("5. (r1) %f\n", r1.FrandomMT());
- printf("5. (r2) %f --Should continue sequence from 5-\n", r2.FrandomMT());
- printf("6. (r1) %f\n", r1.FrandomMT());
- printf("6. (r2) %f\n", r2.FrandomMT());
- printf("7. (r1) %f -- Extra call to r1, no r2 equivalent --\n", r1.FrandomMT());
- printf("8. (r1) %f -- Extra call to r1, no r2 equivalent --\n", r1.FrandomMT());
- bsTest.Reset();
- r1.Serialize(&bsTest);
- bsTest.SetReadOffset(0);
- r2.Deserialize(&bsTest);
- printf("Synched r2 to match r1\n");
- printf("9. (r1) %f\n", r1.FrandomMT());
- printf("9. (r2) %f --SKIPPED 7,8, SHOULD MATCH 9-\n", r2.FrandomMT());
- */
|