From 64a862238b5294ed9a06233e1bcedeb49b8e3409 Mon Sep 17 00:00:00 2001 From: Njaecha Date: Sat, 17 Oct 2026 17:36:16 +0200 Subject: [PATCH] Add ArrayCacheEntry to handle multidimensional arrays --- .../RuntimeUnityEditor.Core.projitems | 1 + .../Entries/Contents/Fake/ArrayCacheEntry.cs | 84 +++++++++++++++++++ .../Windows/Inspector/MemberCollector.cs | 5 ++ 3 files changed, 90 insertions(+) create mode 100644 RuntimeUnityEditor.Core/Windows/Inspector/Entries/Contents/Fake/ArrayCacheEntry.cs diff --git a/RuntimeUnityEditor.Core/RuntimeUnityEditor.Core.projitems b/RuntimeUnityEditor.Core/RuntimeUnityEditor.Core.projitems index 73e6f76..4117360 100644 --- a/RuntimeUnityEditor.Core/RuntimeUnityEditor.Core.projitems +++ b/RuntimeUnityEditor.Core/RuntimeUnityEditor.Core.projitems @@ -73,6 +73,7 @@ + diff --git a/RuntimeUnityEditor.Core/Windows/Inspector/Entries/Contents/Fake/ArrayCacheEntry.cs b/RuntimeUnityEditor.Core/Windows/Inspector/Entries/Contents/Fake/ArrayCacheEntry.cs new file mode 100644 index 0000000..e758ef0 --- /dev/null +++ b/RuntimeUnityEditor.Core/Windows/Inspector/Entries/Contents/Fake/ArrayCacheEntry.cs @@ -0,0 +1,84 @@ +using System; +using System.Linq; +using System.Reflection; +using HarmonyLib; +using RuntimeUnityEditor.Core.ChangeHistory; + +namespace RuntimeUnityEditor.Core.Inspector.Entries +{ + /// + /// Represents a cache entry for an item inside an array of any rank. + /// + public class ArrayCacheEntry : CacheEntryBase, IFakeCacheEntry + { + private Type _type; + private readonly Array _array; + private readonly int[] _indices; + + /// + public ArrayCacheEntry(Array container, int flatIndex) : this(container, GetIndices(container, flatIndex)) { } + + private ArrayCacheEntry(Array container, int[] indices) : base(GetArrayItemName(indices), $"Item contained inside of an array.\n\nIndex: [{FormatIndices(indices)}]\n\nArray type: {container.GetType().FullDescription()}", null) + { + _array = container; + _indices = indices; + } + + /// + /// Convert a flat row-major index into per-dimension indices. + /// + internal static int[] GetIndices(Array array, int flatIndex) + { + var indices = new int[array.Rank]; + for (var dim = array.Rank - 1; dim >= 0; dim--) + { + var length = array.GetLength(dim); + indices[dim] = array.GetLowerBound(dim) + flatIndex % length; + flatIndex /= length; + } + return indices; + } + + internal static string GetArrayItemName(int[] indices) + { + return indices.Length == 1 + ? ReadonlyListCacheEntry.GetListItemName(indices[0]) + : "Index: [" + FormatIndices(indices) + "]"; + } + + private static string FormatIndices(int[] indices) + { + return string.Join(", ", indices.Select(x => x.ToString()).ToArray()); + } + + /// + public override object GetValueToCache() + { + return _array.GetValue(_indices); + } + + /// + protected override bool OnSetValue(object newValue) + { + var oldValue = _array.GetValue(_indices); + Change.WithUndo($"{{0}}[{FormatIndices(_indices)}] = {{1}}", _array, newValue, (arr, o) => arr.SetValue(o, _indices), oldValue: oldValue); + _type = null; + return true; + } + + /// + public override Type Type() + { + return _type ?? (_type = GetValue()?.GetType() ?? _array.GetType().GetElementType()); + } + + /// + public override MemberInfo MemberInfo => null; + + /// + public override bool CanSetValue() + { + return true; + } + } +} diff --git a/RuntimeUnityEditor.Core/Windows/Inspector/MemberCollector.cs b/RuntimeUnityEditor.Core/Windows/Inspector/MemberCollector.cs index fd8e894..5ae7f69 100644 --- a/RuntimeUnityEditor.Core/Windows/Inspector/MemberCollector.cs +++ b/RuntimeUnityEditor.Core/Windows/Inspector/MemberCollector.cs @@ -86,6 +86,11 @@ CallbackCacheEntry GetExportTexEntry(Texture texture) { // Prevent the list overloads from listing subcomponents } + else if (objectToOpen is Array arr) + { + for (var i = 0; i < arr.Length; i++) + fieldCache.Add(new ArrayCacheEntry(arr, i)); + } else if (objectToOpen is IList list) { for (var i = 0; i < list.Count; i++)