SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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