Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: feature to send strings as index #1176

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Assets/Mirage/Runtime/Serialization/NetworkReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ namespace Mirage.Serialization
/// </summary>
public unsafe class NetworkReader : IDisposable
{
public StringStore StringStore;
private byte[] _managedBuffer;
private GCHandle _handle;
private ulong* _longPtr;
Expand Down
4 changes: 3 additions & 1 deletion Assets/Mirage/Runtime/Serialization/NetworkWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,16 @@ namespace Mirage.Serialization
/// </summary>
public unsafe class NetworkWriter
{
public StringStore StringStore;

/// <summary>
/// Max buffer size = 0.5MB
/// </summary>
private const int MAX_BUFFER_SIZE = 524_288;
private byte[] _managedBuffer;
private int _bitCapacity;

/// <summary>Allow internal buffer to resize if capcity is reached</summary>
/// <summary>Allow internal buffer to resize if capacity is reached</summary>
private readonly bool _allowResize;
private GCHandle _handle;
private ulong* _longPtr;
Expand Down
84 changes: 82 additions & 2 deletions Assets/Mirage/Runtime/Serialization/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

Expand Down Expand Up @@ -31,11 +32,29 @@ public static int MaxStringLength
private static byte[] stringBuffer = new byte[MaxStringLength];

/// <param name="value">string or null</param>
public static void WriteString(this NetworkWriter writer, string value) => WriteString(writer, value, defaultEncoding);
public static void WriteString(this NetworkWriter writer, string value)
{
// note, only use StringStore for default encoding
if (writer.StringStore != null)
{
writer.StringStore.WriteString(writer, value);
return;
}

WriteString(writer, value, defaultEncoding);
}

/// <returns>string or null</returns>
/// <exception cref="ArgumentException">Throws if invalid utf8 string is received</exception>
public static string ReadString(this NetworkReader reader) => ReadString(reader, defaultEncoding);
public static string ReadString(this NetworkReader reader)
{
if (reader.StringStore != null)
{
return reader.StringStore.ReadString(reader);
}

return ReadString(reader, defaultEncoding);
}

/// <param name="encoding">Use this for encoding other than the default (UTF8). Make sure to use same encoding for ReadString</param>
/// <param name="value">string or null</param>
Expand Down Expand Up @@ -90,5 +109,66 @@ public static string ReadString(this NetworkReader reader, Encoding encoding)
// convert directly from buffer to string via encoding
return encoding.GetString(data.Array, data.Offset, data.Count);
}
public static void WriteStringStore(this NetworkWriter writer, StringStore store)
{
var count = (uint)store.Strings.Count;
writer.WritePackedUInt32(count);
for (var i = 0; i < count; i++)
// use defaultEncoding, so we use the real write method and not the one that uses StringStore
writer.WriteString(store.Strings[i], defaultEncoding);
}
public static StringStore ReadStringStore(this NetworkReader reader)
{
var store = new StringStore();
var list = store.Strings;
var count = reader.ReadPackedUInt32();
for (var i = 0; i < count; i++)
list.Add(reader.ReadString(defaultEncoding));
return store;
}
}

public class StringStore
{
public Dictionary<string, int> Lookup = new Dictionary<string, int>();
public List<string> Strings = new List<string>();

public int GetKey(string value)
{
if (Lookup.TryGetValue(value, out var index))
{
return index;
}
else
{
index = Strings.Count;
Strings.Add(value);
Lookup.Add(value, index);
return index;
}
}

public void WriteString(NetworkWriter writer, string value)
{
if (value == null)
{
writer.WritePackedUInt32(0);
}
else
{
var key = GetKey(value);
writer.WritePackedUInt32(checked((uint)(key + 1)));
}
}

public string ReadString(NetworkReader reader)
{
var key = reader.ReadPackedUInt32();
if (key == 0)
return null;

var index = checked((int)(key - 1));
return Strings[index];
}
}
}
Loading