Skip to content

Commit 27aaea0

Browse files
committed
More performant CUIHelper
1 parent 6a8452c commit 27aaea0

File tree

1 file changed

+73
-22
lines changed

1 file changed

+73
-22
lines changed

src/RustCui.cs

Lines changed: 73 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,55 +4,106 @@
44
using References::Newtonsoft.Json;
55
using References::Newtonsoft.Json.Converters;
66
using References::Newtonsoft.Json.Linq;
7+
using References::ProtoBuf;
78
using System;
89
using System.Collections.Generic;
10+
using System.Globalization;
11+
using System.IO;
12+
using System.Text;
913
using UnityEngine;
1014
using UnityEngine.UI;
1115

1216
namespace Oxide.Game.Rust.Cui
1317
{
18+
public sealed class JsonArrayPool<T> : IArrayPool<T>
19+
{
20+
public static readonly JsonArrayPool<T> Shared = new JsonArrayPool<T>();
21+
public T[] Rent(int minimumLength) => System.Buffers.ArrayPool<T>.Shared.Rent(minimumLength);
22+
public void Return(T[] array) => System.Buffers.ArrayPool<T>.Shared.Return(array);
23+
}
24+
1425
public static class CuiHelper
1526
{
16-
public static string ToJson(List<CuiElement> elements, bool format = false)
27+
private static readonly StringBuilder sb = new StringBuilder(64 * 1024);
28+
29+
private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
1730
{
18-
return JsonConvert.SerializeObject(elements, format ? Formatting.Indented : Formatting.None, new JsonSerializerSettings
19-
{
20-
DefaultValueHandling = DefaultValueHandling.Ignore
21-
}).Replace("\\n", "\n");
31+
DefaultValueHandling = DefaultValueHandling.Ignore,
32+
NullValueHandling = NullValueHandling.Ignore,
33+
DateParseHandling = DateParseHandling.None,
34+
FloatFormatHandling = FloatFormatHandling.Symbol,
35+
StringEscapeHandling = StringEscapeHandling.Default
36+
};
37+
38+
private static readonly JsonSerializer _serializer = JsonSerializer.Create(Settings);
39+
private static readonly StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture);
40+
private static readonly JsonTextWriter jw = new JsonTextWriter(sw)
41+
{
42+
Formatting = Formatting.None,
43+
ArrayPool = JsonArrayPool<char>.Shared,
44+
CloseOutput = false
45+
};
46+
private static readonly JsonTextWriter jwFormated = new JsonTextWriter(sw)
47+
{
48+
Formatting = Formatting.Indented,
49+
ArrayPool = JsonArrayPool<char>.Shared,
50+
CloseOutput = false
51+
};
52+
53+
public static string ToJson(IReadOnlyList<CuiElement> elements, bool format = false)
54+
{
55+
sb.Clear();
56+
var writer = format ? jwFormated : jw;
57+
_serializer.Serialize(writer, elements);
58+
var json = sb.ToString().Replace("\\n", "\n");
59+
return json;
2260
}
2361

2462
public static List<CuiElement> FromJson(string json) => JsonConvert.DeserializeObject<List<CuiElement>>(json);
2563

26-
public static string GetGuid() => Guid.NewGuid().ToString().Replace("-", string.Empty);
64+
public static string GetGuid() => Guid.NewGuid().ToString("N");
2765

28-
public static bool AddUi(BasePlayer player, List<CuiElement> elements) => AddUi(player, ToJson(elements));
66+
public static bool AddUi(BasePlayer player, List<CuiElement> elements)
67+
{
68+
if (player?.net == null)
69+
return false;
70+
71+
var json = ToJson(elements);
72+
73+
if (Interface.CallHook("CanUseUI", player, json) != null)
74+
return false;
75+
76+
CommunityEntity.ServerInstance.ClientRPC(RpcTarget.Player("AddUI", player.net.connection), json);
77+
return true;
78+
}
2979

3080
public static bool AddUi(BasePlayer player, string json)
3181
{
32-
if (player?.net != null && Interface.CallHook("CanUseUI", player, json) == null)
33-
{
34-
CommunityEntity.ServerInstance.ClientRPC(RpcTarget.Player("AddUI", player.net.connection ), json);
35-
return true;
36-
}
82+
if (player?.net == null || Interface.CallHook("CanUseUI", player, json) != null)
83+
return false;
3784

38-
return false;
85+
CommunityEntity.ServerInstance.ClientRPC(RpcTarget.Player("AddUI", player.net.connection), json);
86+
return true;
3987
}
4088

4189
public static bool DestroyUi(BasePlayer player, string elem)
4290
{
43-
if (player?.net != null)
44-
{
45-
Interface.CallHook("OnDestroyUI", player, elem);
46-
CommunityEntity.ServerInstance.ClientRPC(RpcTarget.Player("DestroyUI", player.net.connection ), elem);
47-
return true;
48-
}
91+
if (player?.net == null)
92+
return false;
4993

50-
return false;
94+
Interface.CallHook("OnDestroyUI", player, elem);
95+
CommunityEntity.ServerInstance.ClientRPC(RpcTarget.Player("DestroyUI", player.net.connection ), elem);
96+
return true;
5197
}
5298

5399
public static void SetColor(this ICuiColor elem, Color color)
54100
{
55-
elem.Color = $"{color.r} {color.g} {color.b} {color.a}";
101+
sb.Clear();
102+
sb.Append(color.r).Append(' ')
103+
.Append(color.g).Append(' ')
104+
.Append(color.b).Append(' ')
105+
.Append(color.a);
106+
elem.Color = sb.ToString();
56107
}
57108

58109
public static Color GetColor(this ICuiColor elem) => ColorEx.Parse(elem.Color);
@@ -299,7 +350,7 @@ public class CuiRawImageComponent : ICuiComponent, ICuiColor
299350

300351
[JsonProperty("png")]
301352
public string Png { get; set; }
302-
353+
303354
[JsonProperty("steamid")]
304355
public string SteamId { get; set; }
305356

0 commit comments

Comments
 (0)