11using System ;
22using System . Collections . Generic ;
3+ using Mirror ;
34using TMPro ;
45using UnityEngine ;
56using UnityEngine . UI ;
@@ -12,6 +13,7 @@ public class MemoryDevConsole : MonoBehaviour {
1213 public GameObject logInstance ;
1314 public ScrollRect scrollRect ;
1415 public RectTransform contentFrame ;
16+ public TMP_Text totalBytesLabel ;
1517
1618 [ SerializeField ] private GameObject sortedButton ;
1719
@@ -22,17 +24,27 @@ public class MemoryDevConsole : MonoBehaviour {
2224
2325 private LuauContext _context = LuauContext . Game ;
2426 private MemoryEnvironment _environment = MemoryEnvironment . Client ;
25- private bool _sorted ;
27+ private MemorySort _sort = MemorySort . None ;
2628
2729 private float _lastRefreshTime ;
2830 private Dictionary < LuauContext , List < LuauPlugin . LuauMemoryCategoryDumpItem > > _dumps ;
2931
32+ private AirshipLuauDebugger _luauDebugger ;
33+ private bool _hasLuauDebugger = false ;
34+
3035 private readonly List < TMP_InputField > _logItems = new ( ) ;
36+ private readonly List < TMP_InputField > _logItemsPool = new ( ) ;
3137
32- public enum MemoryEnvironment {
38+ private enum MemoryEnvironment {
3339 Client ,
3440 Server ,
3541 }
42+
43+ private enum MemorySort {
44+ None ,
45+ Bytes ,
46+ Alphabetical ,
47+ }
3648
3749 private static string FormatBytes ( ulong bytes ) {
3850 if ( bytes < 1024 ) {
@@ -52,11 +64,26 @@ private static string FormatBytes(ulong bytes) {
5264
5365 private void Start ( ) {
5466 _lastRefreshTime = 0 ;
67+
5568 _dumps = new Dictionary < LuauContext , List < LuauPlugin . LuauMemoryCategoryDumpItem > > {
5669 [ LuauContext . Game ] = new ( ) ,
5770 [ LuauContext . Protected ] = new ( ) ,
5871 } ;
72+
73+ _luauDebugger = FindAnyObjectByType < AirshipLuauDebugger > ( ) ;
74+ _hasLuauDebugger = _luauDebugger != null ;
75+
5976 UpdateSortedButtonAppearance ( ) ;
77+
78+ if ( _hasLuauDebugger ) {
79+ _luauDebugger . ServerMemDump . OnChange += OnServerMemDumpChanged ;
80+ }
81+ }
82+
83+ private void OnDestroy ( ) {
84+ if ( _hasLuauDebugger ) {
85+ _luauDebugger . ServerMemDump . OnChange -= OnServerMemDumpChanged ;
86+ }
6087 }
6188
6289 private void OnEnable ( ) {
@@ -94,19 +121,42 @@ public void OnEnvironmentDropdownSelected(int n) {
94121 if ( newEnvironment != _environment ) {
95122 _environment = newEnvironment ;
96123 _lastRefreshTime = 0 ;
124+
125+ if ( newEnvironment == MemoryEnvironment . Server && ! _hasLuauDebugger ) {
126+ _luauDebugger = FindAnyObjectByType < AirshipLuauDebugger > ( ) ;
127+ _hasLuauDebugger = _luauDebugger != null ;
128+ }
129+ }
130+ }
131+
132+ private void OnServerMemDumpChanged ( SyncDictionary < LuauContext , List < LuauPlugin . LuauMemoryCategoryDumpItem > > . Operation op , LuauContext ctx , List < LuauPlugin . LuauMemoryCategoryDumpItem > dump ) {
133+ if ( _environment == MemoryEnvironment . Client || ctx != _context ) {
134+ return ;
97135 }
136+
137+ Refresh ( ) ;
98138 }
99139
100140 private void UpdateSortedButtonAppearance ( ) {
141+ var sorted = _sort != MemorySort . None ;
142+
101143 var image = sortedButton . GetComponent < Image > ( ) ;
102- image . color = _sorted ? sortedButtonBackgroundColorActive : sortedButtonBackgroundColorInactive ;
144+ image . color = sorted ? sortedButtonBackgroundColorActive : sortedButtonBackgroundColorInactive ;
103145
104146 var text = sortedButton . GetComponentInChildren < TMP_Text > ( ) ;
105- text . color = _sorted ? sortedButtonTextColorActive : sortedButtonTextColorInactive ;
147+ text . color = sorted ? sortedButtonTextColorActive : sortedButtonTextColorInactive ;
148+
149+ text . text = _sort switch {
150+ MemorySort . Bytes => "Sort [Bytes]" ,
151+ MemorySort . Alphabetical => "Sort [A-Z]" ,
152+ _ => "Sort"
153+ } ;
106154 }
107155
108156 public void OnSortedButtonClicked ( ) {
109- _sorted = ! _sorted ;
157+ // Cursed enum increment:
158+ _sort = ( MemorySort ) ( ( ( int ) _sort + 1 ) % 3 ) ;
159+
110160 _lastRefreshTime = 0 ;
111161 UpdateSortedButtonAppearance ( ) ;
112162 }
@@ -119,37 +169,71 @@ private void Update() {
119169
120170 _lastRefreshTime = now ;
121171
172+ if ( _environment == MemoryEnvironment . Server && _hasLuauDebugger ) {
173+ _luauDebugger . FetchServerMemoryDump ( _context ) ;
174+ }
175+
122176 Refresh ( ) ;
123177 }
124178
125179 private void Refresh ( ) {
126- var dump = _dumps [ _context ] ;
127- LuauPlugin . LuauGetMemoryCategoryDump ( _context , dump ) ;
180+ List < LuauPlugin . LuauMemoryCategoryDumpItem > dump = null ;
181+ switch ( _environment ) {
182+ case MemoryEnvironment . Client :
183+ dump = _dumps [ _context ] ;
184+ LuauPlugin . LuauGetMemoryCategoryDump ( _context , dump ) ;
185+ break ;
186+ case MemoryEnvironment . Server :
187+ if ( _hasLuauDebugger ) {
188+ _luauDebugger . ServerMemDump . TryGetValue ( _context , out dump ) ;
189+ }
190+ dump ??= new List < LuauPlugin . LuauMemoryCategoryDumpItem > ( ) ;
191+ break ;
192+ default :
193+ throw new Exception ( "unknown environment" ) ;
194+ }
128195
129- if ( _sorted ) {
130- var sortedDump = new List < LuauPlugin . LuauMemoryCategoryDumpItem > ( _dumps [ _context ] ) ;
196+ if ( _sort == MemorySort . Bytes ) {
197+ var sortedDump = new List < LuauPlugin . LuauMemoryCategoryDumpItem > ( dump ) ;
131198 sortedDump . Sort ( ( ( itemA , itemB ) => itemA . Bytes == itemB . Bytes ? 0 : itemA . Bytes < itemB . Bytes ? 1 : - 1 ) ) ;
132199 dump = sortedDump ;
200+ } else if ( _sort == MemorySort . Alphabetical ) {
201+ var sortedDump = new List < LuauPlugin . LuauMemoryCategoryDumpItem > ( dump ) ;
202+ sortedDump . Sort ( ( ( itemA , itemB ) => string . Compare ( itemA . ShortName , itemB . ShortName , StringComparison . Ordinal ) ) ) ;
203+ dump = sortedDump ;
133204 }
134205
206+ var totalBytes = 0UL ;
207+
135208 var i = 0 ;
136209 foreach ( var item in dump ) {
137210 TMP_InputField instance ;
138211 if ( i < _logItems . Count ) {
139212 instance = _logItems [ i ] ;
213+ } else if ( _logItemsPool . Count > 0 ) {
214+ instance = _logItemsPool [ ^ 1 ] ;
215+ _logItemsPool . RemoveAt ( _logItemsPool . Count - 1 ) ;
216+ instance . transform . SetParent ( contentFrame ) ;
217+ _logItems . Add ( instance ) ;
140218 } else {
141219 var go = Instantiate ( logInstance , contentFrame ) ;
142220 go . GetComponent < LogFieldInstance > ( ) . redirectTarget = scrollRect ;
143221 instance = go . GetComponent < TMP_InputField > ( ) ;
144222 _logItems . Add ( instance ) ;
145223 }
146224 instance . text = $ "{ item . ShortName } : <b><color=\" green\" >{ FormatBytes ( item . Bytes ) } </color></b>";
225+ totalBytes += item . Bytes ;
147226 i ++ ;
148227 }
149228
229+ // Trim off unused labels:
150230 while ( _logItems . Count > i ) {
151- Destroy ( _logItems [ ^ 1 ] . gameObject ) ;
231+ var item = _logItems [ ^ 1 ] ;
232+ item . transform . SetParent ( null ) ;
233+ _logItemsPool . Add ( item ) ;
152234 _logItems . RemoveAt ( _logItems . Count - 1 ) ;
153235 }
236+
237+ totalBytesLabel . text = $ "Total: <b><color=\" green\" >{ FormatBytes ( totalBytes ) } </color></b>";
154238 }
155239}
0 commit comments