using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using Mono.CSharp; using UnityEngine; namespace Explorer { public partial class CacheList : CacheObject { public bool IsExpanded { get; set; } public int ArrayOffset { get; set; } public Type EntryType { get { if (m_entryType == null) { m_entryType = Value?.GetType().GetGenericArguments()[0]; } return m_entryType; } set { m_entryType = value; } } private Type m_entryType; public IEnumerable Enumerable { get { if (m_enumerable == null && Value != null) { m_enumerable = Value as IEnumerable ?? CppListToEnumerable(Value); } return m_enumerable; } } private IEnumerable m_enumerable; private CacheObject[] m_cachedEntries; public CacheList(object obj) { if (obj != null) { Value = obj; EntryType = obj.GetType().GetGenericArguments()[0]; } } private IEnumerable CppListToEnumerable(object list) { if (EntryType == null) return null; return (IEnumerable)typeof(Il2CppSystem.Collections.Generic.List<>) .MakeGenericType(new Type[] { EntryType }) .GetMethod("ToArray") .Invoke(list, new object[0]); } public override void DrawValue(Rect window, float width) { int count = m_cachedEntries.Length; if (!IsExpanded) { if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) })) { IsExpanded = true; } } else { if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) })) { IsExpanded = false; } } GUI.skin.button.alignment = TextAnchor.MiddleLeft; string btnLabel = "[" + count + "] " + EntryType + ""; if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(window.width - 260) })) { WindowManager.InspectObject(Value, out bool _); } GUI.skin.button.alignment = TextAnchor.MiddleCenter; if (IsExpanded) { if (count > CppExplorer.ArrayLimit) { GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(null); GUILayout.Space(190); int maxOffset = (int)Mathf.Ceil((float)(count / (decimal)CppExplorer.ArrayLimit)) - 1; GUILayout.Label($"Page {ArrayOffset + 1}/{maxOffset + 1}", new GUILayoutOption[] { GUILayout.Width(80) }); // prev/next page buttons if (GUILayout.Button("< Prev", null)) { if (ArrayOffset > 0) ArrayOffset--; } if (GUILayout.Button("Next >", null)) { if (ArrayOffset < maxOffset) ArrayOffset++; } } int offset = ArrayOffset * CppExplorer.ArrayLimit; if (offset >= count) offset = 0; for (int i = offset; i < offset + CppExplorer.ArrayLimit && i < count; i++) { var entry = m_cachedEntries[i]; //collapsing the BeginHorizontal called from ReflectionWindow.WindowFunction or previous array entry GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(null); GUILayout.Space(190); if (entry.Value == null) { GUILayout.Label("null", null); } else { GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(30) }); entry.DrawValue(window, window.width - 250); } } } } public override void SetValue() { throw new NotImplementedException("TODO"); } /// /// Called when the user presses the "Update" button, or if AutoUpdate is on. /// public override void UpdateValue() { base.UpdateValue(); if (Value == null) return; var enumerator = Enumerable?.GetEnumerator(); if (enumerator == null) return; var list = new List(); while (enumerator.MoveNext()) { list.Add(GetCacheObject(enumerator.Current)); } m_cachedEntries = list.ToArray(); } } }