RandSync.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include "RandSync.h"
  11. #include "BitStream.h"
  12. #include <limits>
  13. #include <limits.h>
  14. namespace RakNet
  15. {
  16. RakNetRandomSync::RakNetRandomSync()
  17. {
  18. seed = (uint32_t) -1;
  19. callCount = 0;
  20. usedValueBufferCount = 0;
  21. }
  22. RakNetRandomSync::~RakNetRandomSync()
  23. {
  24. }
  25. void RakNetRandomSync::SeedMT( uint32_t _seed )
  26. {
  27. seed = _seed;
  28. rnr.SeedMT( seed );
  29. callCount = 0;
  30. usedValueBufferCount = 0;
  31. }
  32. void RakNetRandomSync::SeedMT( uint32_t _seed, uint32_t skipValues )
  33. {
  34. SeedMT(_seed);
  35. Skip(skipValues);
  36. }
  37. float RakNetRandomSync::FrandomMT( void )
  38. {
  39. return ( float ) ( ( double ) RandomMT() / (double) UINT_MAX );
  40. }
  41. unsigned int RakNetRandomSync::RandomMT( void )
  42. {
  43. if (usedValueBufferCount > 0)
  44. {
  45. --usedValueBufferCount;
  46. if (usedValueBufferCount < usedValues.Size())
  47. {
  48. // The remote system had less calls than the current system, so return values from the past
  49. return usedValues[usedValues.Size()-usedValueBufferCount-1];
  50. }
  51. else
  52. {
  53. // Unknown past value, too far back
  54. // Return true random
  55. return rnr.RandomMT();
  56. }
  57. }
  58. else
  59. {
  60. // Get random number and store what it is
  61. usedValues.Push(rnr.RandomMT(), _FILE_AND_LINE_);
  62. ++callCount;
  63. while (usedValues.Size()>64)
  64. usedValues.Pop();
  65. return usedValues[usedValues.Size()-1];
  66. }
  67. }
  68. uint32_t RakNetRandomSync::GetSeed( void ) const
  69. {
  70. return seed;
  71. }
  72. uint32_t RakNetRandomSync::GetCallCount( void ) const
  73. {
  74. return callCount;
  75. }
  76. void RakNetRandomSync::SetCallCount( uint32_t i )
  77. {
  78. callCount = i;
  79. }
  80. void RakNetRandomSync::SerializeConstruction(RakNet::BitStream *constructionBitstream)
  81. {
  82. constructionBitstream->Write(seed);
  83. constructionBitstream->Write(callCount);
  84. }
  85. bool RakNetRandomSync::DeserializeConstruction(RakNet::BitStream *constructionBitstream)
  86. {
  87. uint32_t _seed;
  88. uint32_t _skipValues;
  89. constructionBitstream->Read(_seed);
  90. bool success = constructionBitstream->Read(_skipValues);
  91. if (success)
  92. SeedMT(_seed, _skipValues);
  93. return success;
  94. }
  95. void RakNetRandomSync::Serialize(RakNet::BitStream *outputBitstream)
  96. {
  97. outputBitstream->Write(callCount);
  98. }
  99. void RakNetRandomSync::Deserialize(RakNet::BitStream *outputBitstream)
  100. {
  101. uint32_t _callCount;
  102. outputBitstream->Read(_callCount);
  103. if (_callCount < callCount )
  104. {
  105. // We locally read more values than the remote system
  106. // The next n calls should come from buffered values
  107. usedValueBufferCount = callCount - _callCount;
  108. }
  109. else if (_callCount > callCount )
  110. {
  111. // Remote system read more values than us
  112. uint32_t diff = _callCount - callCount;
  113. if (diff <= usedValueBufferCount)
  114. usedValueBufferCount -= diff;
  115. if (diff > 0)
  116. Skip(diff);
  117. }
  118. }
  119. void RakNetRandomSync::Skip( uint32_t count )
  120. {
  121. for (uint32_t i = 0; i < count; i++)
  122. rnr.RandomMT();
  123. callCount+=count;
  124. }
  125. } // namespace RakNet
  126. /*
  127. RakNetRandomSync r1, r2;
  128. BitStream bsTest;
  129. r1.SeedMT(0);
  130. r1.SerializeConstruction(&bsTest);
  131. bsTest.SetReadOffset(0);
  132. r2.DeserializeConstruction(&bsTest);
  133. printf("1. (r1) %f\n", r1.FrandomMT());
  134. printf("1. (r2) %f\n", r2.FrandomMT());
  135. printf("2. (r1) %f\n", r1.FrandomMT());
  136. printf("2. (r2) %f\n", r2.FrandomMT());
  137. printf("3. (r1) %f\n", r1.FrandomMT());
  138. printf("3. (r2) %f\n", r2.FrandomMT());
  139. printf("4. (r1) %f\n", r1.FrandomMT());
  140. printf("4. (r2) %f\n", r2.FrandomMT());
  141. printf("5. (r2) %f\n", r2.FrandomMT());
  142. printf("6. (r2) %f\n", r2.FrandomMT());
  143. printf("7. (r2) %f\n", r2.FrandomMT());
  144. bsTest.Reset();
  145. r1.Serialize(&bsTest);
  146. bsTest.SetReadOffset(0);
  147. r2.Deserialize(&bsTest);
  148. printf("Synched r2 to match r1\n");
  149. printf("5. (r1) %f\n", r1.FrandomMT());
  150. printf("5. (r2) %f --Should continue sequence from 5-\n", r2.FrandomMT());
  151. printf("6. (r1) %f\n", r1.FrandomMT());
  152. printf("6. (r2) %f\n", r2.FrandomMT());
  153. printf("7. (r1) %f -- Extra call to r1, no r2 equivalent --\n", r1.FrandomMT());
  154. printf("8. (r1) %f -- Extra call to r1, no r2 equivalent --\n", r1.FrandomMT());
  155. bsTest.Reset();
  156. r1.Serialize(&bsTest);
  157. bsTest.SetReadOffset(0);
  158. r2.Deserialize(&bsTest);
  159. printf("Synched r2 to match r1\n");
  160. printf("9. (r1) %f\n", r1.FrandomMT());
  161. printf("9. (r2) %f --SKIPPED 7,8, SHOULD MATCH 9-\n", r2.FrandomMT());
  162. */
粤ICP备19079148号