Skip to content

Commit be35b69

Browse files
Merge branch 'master' into moretests
2 parents 4a91ad0 + 4633163 commit be35b69

File tree

1 file changed

+55
-64
lines changed

1 file changed

+55
-64
lines changed

MLAPI/NetworkingManagerComponents/Binary/BitStream.cs

Lines changed: 55 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,32 @@ namespace MLAPI.NetworkingManagerComponents.Binary
1717
/// </summary>
1818
public sealed class BitStream : Stream
1919
{
20+
21+
/// <summary>
22+
/// A struct with a explicit memory layout. The struct has 4 fields. float,uint,double and ulong.
23+
/// Every field has the same starting point in memory. If you insert a float value, it can be extracted as a uint.
24+
/// This is to allow for lockless & garbage free conversion from float to uint and double to ulong.
25+
/// This allows for VarInt encoding and other integer encodings.
26+
/// </summary>
27+
[StructLayout(LayoutKind.Explicit)]
28+
internal struct UIntFloat
29+
{
30+
[FieldOffset(0)]
31+
public float floatValue;
32+
33+
[FieldOffset(0)]
34+
public uint uintValue;
35+
36+
[FieldOffset(0)]
37+
public double doubleValue;
38+
39+
[FieldOffset(0)]
40+
public ulong ulongValue;
41+
}
42+
2043
const int initialCapacity = 16;
2144
const float initialGrowthFactor = 2.0f;
2245
private byte[] target;
23-
private static readonly float[] holder_f = new float[1];
24-
private static readonly double[] holder_d = new double[1];
25-
private static readonly uint[] holder_i = new uint[1];
26-
private static readonly ulong[] holder_l = new ulong[1];
2746

2847
/// <summary>
2948
/// A stream that supports writing data smaller than a single byte. This stream also has a built-in compression algorithm that can (optionally) be used to write compressed data.
@@ -292,13 +311,10 @@ public void WriteBit(bool bit)
292311
/// <param name="value">Value to write</param>
293312
public void WriteSingle(float value)
294313
{
295-
lock (holder_f)
296-
lock (holder_i)
297-
{
298-
holder_f[0] = value;
299-
Buffer.BlockCopy(holder_f, 0, holder_i, 0, 4);
300-
WriteUInt32(holder_i[0]);
301-
}
314+
WriteUInt32(new UIntFloat
315+
{
316+
floatValue = value
317+
}.uintValue);
302318
}
303319

304320
/// <summary>
@@ -307,13 +323,10 @@ public void WriteSingle(float value)
307323
/// <param name="value">Value to write</param>
308324
public void WriteDouble(double value)
309325
{
310-
lock (holder_d)
311-
lock (holder_l)
312-
{
313-
holder_d[0] = value;
314-
Buffer.BlockCopy(holder_d, 0, holder_l, 0, 8);
315-
WriteUInt64(holder_l[0]);
316-
}
326+
WriteUInt64(new UIntFloat
327+
{
328+
doubleValue = value
329+
}.ulongValue);
317330
}
318331

319332
/// <summary>
@@ -322,13 +335,10 @@ public void WriteDouble(double value)
322335
/// <param name="value">Value to write</param>
323336
public void WriteSinglePacked(float value)
324337
{
325-
lock (holder_f)
326-
lock (holder_i)
327-
{
328-
holder_f[0] = value;
329-
Buffer.BlockCopy(holder_f, 0, holder_i, 0, 4);
330-
WriteUInt32Packed(BinaryHelpers.SwapEndian(holder_i[0]));
331-
}
338+
WriteUInt32Packed(new UIntFloat
339+
{
340+
floatValue = value
341+
}.uintValue);
332342
}
333343

334344
/// <summary>
@@ -337,13 +347,10 @@ public void WriteSinglePacked(float value)
337347
/// <param name="value">Value to write</param>
338348
public void WriteDoublePacked(double value)
339349
{
340-
lock (holder_d)
341-
lock (holder_l)
342-
{
343-
holder_d[0] = value;
344-
Buffer.BlockCopy(holder_d, 0, holder_l, 0, 8);
345-
WriteUInt64Packed(BinaryHelpers.SwapEndian(holder_l[0]));
346-
}
350+
WriteUInt64Packed(new UIntFloat
351+
{
352+
doubleValue = value
353+
}.ulongValue);
347354
}
348355

349356
/// <summary>
@@ -522,14 +529,10 @@ public void WriteRotation(Quaternion rotation, int bytesPerAngle)
522529
/// <returns>The read value</returns>
523530
public float ReadSingle()
524531
{
525-
uint read = ReadUInt32();
526-
lock (holder_f)
527-
lock (holder_i)
528-
{
529-
holder_i[0] = read;
530-
Buffer.BlockCopy(holder_i, 0, holder_f, 0, 4);
531-
return holder_f[0];
532-
}
532+
return new UIntFloat
533+
{
534+
uintValue = ReadUInt32()
535+
}.floatValue;
533536
}
534537

535538

@@ -539,14 +542,10 @@ public float ReadSingle()
539542
/// <returns>The read value</returns>
540543
public double ReadDouble()
541544
{
542-
ulong read = ReadUInt64();
543-
lock (holder_d)
544-
lock (holder_l)
545-
{
546-
holder_l[0] = read;
547-
Buffer.BlockCopy(holder_l, 0, holder_d, 0, 8);
548-
return holder_d[0];
549-
}
545+
return new UIntFloat
546+
{
547+
ulongValue = ReadUInt64()
548+
}.doubleValue;
550549
}
551550

552551
/// <summary>
@@ -555,14 +554,10 @@ public double ReadDouble()
555554
/// <returns>The read value</returns>
556555
public float ReadSinglePacked()
557556
{
558-
uint read = ReadUInt32Packed();
559-
lock (holder_f)
560-
lock (holder_i)
561-
{
562-
holder_i[0] = BinaryHelpers.SwapEndian(read);
563-
Buffer.BlockCopy(holder_i, 0, holder_f, 0, 4);
564-
return holder_f[0];
565-
}
557+
return new UIntFloat
558+
{
559+
uintValue = ReadUInt32Packed()
560+
}.floatValue;
566561
}
567562

568563
/// <summary>
@@ -571,14 +566,10 @@ public float ReadSinglePacked()
571566
/// <returns>The read value</returns>
572567
public double ReadDoublePacked()
573568
{
574-
ulong read = ReadUInt64Packed();
575-
lock (holder_d)
576-
lock (holder_l)
577-
{
578-
holder_l[0] = BinaryHelpers.SwapEndian(read);
579-
Buffer.BlockCopy(holder_l, 0, holder_d, 0, 8);
580-
return holder_d[0];
581-
}
569+
return new UIntFloat
570+
{
571+
ulongValue = ReadUInt64Packed()
572+
}.doubleValue;
582573
}
583574

584575
/// <summary>

0 commit comments

Comments
 (0)