diff --git a/src/UI/Panels/ObjectExplorer.cs b/src/UI/Panels/ObjectExplorer.cs index dfb849b..b8bd87c 100644 --- a/src/UI/Panels/ObjectExplorer.cs +++ b/src/UI/Panels/ObjectExplorer.cs @@ -51,7 +51,8 @@ namespace UnityExplorer.UI.Panels public override void Update() { - SceneExplorer.Update(); + if (SelectedTab == 0) + SceneExplorer.Update(); } public override void SaveToConfigManager() diff --git a/src/UI/Widgets/ScrollPool/DataHeightCache.cs b/src/UI/Widgets/ScrollPool/DataHeightCache.cs index 8ccd56c..cc5e996 100644 --- a/src/UI/Widgets/ScrollPool/DataHeightCache.cs +++ b/src/UI/Widgets/ScrollPool/DataHeightCache.cs @@ -43,12 +43,15 @@ namespace UnityExplorer.UI.Widgets public float DefaultHeight => m_defaultHeight ?? (float)(m_defaultHeight = ScrollPool.PrototypeCell.rect.height); private float? m_defaultHeight; + /// Get the first range (division of DefaultHeight) which the position appears in. private int GetRangeIndexOfPosition(float position) => (int)Math.Floor((decimal)position / (decimal)DefaultHeight); - // for efficient lookup of "which data index is at this position" - // list index: DefaultHeight * index from top of data - // list value: the data index at this position - private readonly List rangeToDataIndexCache = new List(); + /// + /// Lookup table for "which data index first appears at this position"
+ /// Index: DefaultHeight * index from top of data
+ /// Value: the first data index at this position
+ ///
+ private readonly List rangeCache = new List(); public DataViewInfo this[int index] { @@ -56,19 +59,30 @@ namespace UnityExplorer.UI.Widgets set => SetIndex(index, value); } - private int GetSpread(float startPosition, float height) + /// + /// Get the spread of the height, starting from the start position.

+ /// The "spread" begins at the start of the next interval of the DefaultHeight, then increases for + /// every interval beyond that. + ///
+ private int GetRangeSpread(float startPosition, float height) { + // get the remainder of the start position divided by min height float rem = startPosition % DefaultHeight; + // if there is a remainder, this means the previous cell started in + // our first cell and they take priority, so reduce our height by + // (minHeight - remainder) to account for that. We need to fill that + // gap and reach the next cell before we take priority. if (!Mathf.Approximately(rem, 0f)) height -= (DefaultHeight - rem); return (int)Math.Ceiling((decimal)height / (decimal)DefaultHeight); } + /// Append a data index to the cache with the provided height value. public void Add(float value) { - int spread = GetSpread(totalHeight, value); + int spread = GetRangeSpread(totalHeight, value); heightCache.Add(new DataViewInfo() { @@ -79,11 +93,12 @@ namespace UnityExplorer.UI.Widgets int dataIdx = heightCache.Count - 1; for (int i = 0; i < spread; i++) - rangeToDataIndexCache.Add(dataIdx); + rangeCache.Add(dataIdx); totalHeight += value; } + /// Remove the last (highest count) index from the height cache. public void RemoveLast() { if (!heightCache.Any()) @@ -94,6 +109,28 @@ namespace UnityExplorer.UI.Widgets heightCache.RemoveAt(heightCache.Count - 1); } + /// Get the data index at the specific position of the total height cache. + public int GetDataIndexAtPosition(float desiredHeight) => GetDataIndexAtPosition(desiredHeight, out _); + + /// Get the data index at the specific position of the total height cache. + public int GetDataIndexAtPosition(float desiredHeight, out DataViewInfo cache) + { + cache = null; + int rangeIndex = GetRangeIndexOfPosition(desiredHeight); + + if (rangeIndex <= 0) + return 0; + + if (rangeCache.Count <= rangeIndex) + return rangeCache[rangeCache.Count - 1]; + + int dataIndex = rangeCache[rangeIndex]; + cache = heightCache[dataIndex]; + + return dataIndex; + } + + /// Set a given data index with the specified value. public void SetIndex(int dataIndex, float height, bool ignoreDataCount = false) { if (!ignoreDataCount) @@ -134,29 +171,13 @@ namespace UnityExplorer.UI.Widgets int rangeIndex = GetRangeIndexOfPosition(cache.startPosition); // var spread = GetRangeIndexOfPosition(value); - int spread = GetSpread(cache.startPosition, height); + int spread = GetRangeSpread(cache.startPosition, height); - // setting range index beyond current count, need to append - if (rangeToDataIndexCache.Count <= rangeIndex) + if (rangeCache.Count <= rangeIndex) { - // if the gap is > 1, we need to fill that gap. This shouldn't really ever happen but just in case. - if (rangeToDataIndexCache.Count < rangeIndex) - { - int lastDataIdx = rangeToDataIndexCache[rangeToDataIndexCache.Count - 1]; - while (rangeToDataIndexCache.Count < rangeIndex) - { - if (lastDataIdx < dataIndex - 1) - lastDataIdx++; - rangeToDataIndexCache.Add(lastDataIdx); - heightCache[lastDataIdx].normalizedSpread++; - } - } - - // apend spread for this data - for (int i = 0; i < spread; i++) - rangeToDataIndexCache.Add(dataIndex); - - cache.normalizedSpread = spread; + // This should never happen, there is a gap in the previous data. Trigger rebuild? + // I stress-tested the scroll pool and didn't seem to encounter this, leaving for now. + ExplorerCore.LogWarning($"rangeToDataIndex.Count ({rangeCache.Count}) <= rangeIndex ({rangeIndex})?"); } else if (spread != cache.normalizedSpread) { @@ -168,11 +189,11 @@ namespace UnityExplorer.UI.Widgets int rangeStart = -1; // the start will always be at LEAST (no less) PrototypeHeight * index, cells can never be smaller than that. - int minStart = rangeToDataIndexCache[dataIndex]; + int minStart = rangeCache[dataIndex]; - for (int i = minStart; i < rangeToDataIndexCache.Count; i++) + for (int i = minStart; i < rangeCache.Count; i++) { - if (rangeToDataIndexCache[i] == dataIndex) + if (rangeCache[i] == dataIndex) { rangeStart = i; break; @@ -180,24 +201,27 @@ namespace UnityExplorer.UI.Widgets // our index is further down. add the min difference and try again. // the iterator will add 1 on the next loop so account for that. - int jmp = dataIndex - rangeToDataIndexCache[i] - 1; + int jmp = dataIndex - rangeCache[i] - 1; i += jmp < 1 ? 0 : jmp; } if (rangeStart == -1) - rangeStart = rangeToDataIndexCache.Count - 1; + { + ExplorerCore.LogWarning($"DataHeightCache corrupt? Couldn't find dataIndex {dataIndex} anywhere in range cache."); + return; + } if (spreadDiff > 0) { // need to insert for (int i = 0; i < spreadDiff; i++) - rangeToDataIndexCache.Insert(rangeStart, dataIndex); + rangeCache.Insert(rangeStart, dataIndex); } else { // need to remove for (int i = 0; i < -spreadDiff; i++) - rangeToDataIndexCache.RemoveAt(rangeStart); + rangeCache.RemoveAt(rangeStart); } } @@ -209,24 +233,5 @@ namespace UnityExplorer.UI.Widgets SisterCache.SetIndex(realIdx, height, true); } } - - public int GetDataIndexAtPosition(float desiredHeight) - { - return GetDataIndexAtPosition(desiredHeight, out _); - } - - public int GetDataIndexAtPosition(float desiredHeight, out DataViewInfo cache) - { - cache = null; - int rangeIndex = GetRangeIndexOfPosition(desiredHeight); - - if (rangeToDataIndexCache.Count <= rangeIndex || rangeIndex < 0) - return -1; - - int dataIndex = rangeToDataIndexCache[rangeIndex]; - cache = heightCache[dataIndex]; - - return dataIndex; - } } }