Progress on ReflectionInspector, framework mostly done

This commit is contained in:
Sinai
2021-04-28 20:47:48 +10:00
parent a2ff37e36d
commit b0d54b1d80
22 changed files with 523 additions and 257 deletions

View File

@ -24,8 +24,7 @@ namespace UnityExplorer.UI.Widgets
ScrollPool = scrollPool;
}
// initialize with a reasonably sized pool, most caches will allocate a fair bit.
private readonly List<DataViewInfo> heightCache = new List<DataViewInfo>(16384);
private readonly List<DataViewInfo> heightCache = new List<DataViewInfo>();
public DataViewInfo this[int index]
{
@ -104,12 +103,8 @@ namespace UnityExplorer.UI.Widgets
heightCache.RemoveAt(heightCache.Count - 1);
int idx = heightCache.Count;
if (idx > 0)
{
while (rangeCache[rangeCache.Count - 1] == idx)
rangeCache.RemoveAt(rangeCache.Count - 1);
}
while (rangeCache.Count > 0 && rangeCache[rangeCache.Count - 1] == idx)
rangeCache.RemoveAt(rangeCache.Count - 1);
}
/// <summary>Get the data index at the specific position of the total height cache.</summary>
@ -119,31 +114,29 @@ namespace UnityExplorer.UI.Widgets
public int GetDataIndexAtPosition(float desiredHeight, out DataViewInfo cache)
{
cache = default;
if (!heightCache.Any())
return 0;
int rangeIndex = GetRangeIndexOfPosition(desiredHeight);
if (rangeIndex < 0)
return 0;
if (rangeIndex >= rangeCache.Count)
{
ExplorerCore.LogWarning("RangeIndex < 0? " + rangeIndex);
return -1;
}
if (rangeCache.Count <= rangeIndex)
{
ExplorerCore.LogWarning("Want range index " + rangeIndex + " but count is " + rangeCache.Count);
RebuildCache();
rangeIndex = GetRangeIndexOfPosition(desiredHeight);
if (rangeCache.Count <= rangeIndex)
throw new Exception("Range index (" + rangeIndex + ") exceeded rangeCache count (" + rangeCache.Count + ")");
ExplorerCore.Log("desiredHeight is " + desiredHeight + ", but our total height is " + totalHeight + ", clamping to data count");
ExplorerCore.Log("highest data index: " + (ScrollPool.DataSource.ItemCount - 1) + ", rangeIndex was " + rangeIndex + ", actual range limit is " + (rangeCache.Count - 1));
cache = heightCache[heightCache.Count - 1];
return ScrollPool.DataSource.ItemCount - 1;
}
int dataIndex = rangeCache[rangeIndex];
cache = heightCache[dataIndex];
return dataIndex;
}
/// <summary>Set a given data index with the specified value.</summary>
public void SetIndex(int dataIndex, float height)
public void SetIndex(int dataIndex, float height, bool inRebuild = false)
{
if (dataIndex >= ScrollPool.DataSource.ItemCount)
{
@ -166,7 +159,6 @@ namespace UnityExplorer.UI.Widgets
var diff = height - prevHeight;
if (diff != 0.0f)
{
// LogWarning("Height for data index " + dataIndex + " changed by " + diff);
totalHeight += diff;
cache.height = height;
}
@ -183,8 +175,16 @@ namespace UnityExplorer.UI.Widgets
if (rangeCache.Count <= rangeIndex)
{
RebuildCache();
return;
if (rangeCache[rangeCache.Count - 1] != dataIndex - 1)
{
// The previous index in the range cache is not the previous data index for the data we were given.
// Need to rebuild.
if (!inRebuild)
RebuildCache();
else
throw new Exception($"DataHeightCache rebuild failed. Trying to set {rangeIndex} but current count is {rangeCache.Count}!");
return;
}
}
if (spread != cache.normalizedSpread)
@ -199,6 +199,7 @@ namespace UnityExplorer.UI.Widgets
// In some rare cases we may not find our data index at the expected range index.
// We can make some educated guesses and find the real index pretty quickly.
int minStart = GetRangeIndexOfPosition(dataIndex * DefaultHeight);
if (minStart < 0) minStart = 0;
for (int i = minStart; i < rangeCache.Count; i++)
{
if (rangeCache[i] == dataIndex)
@ -218,10 +219,8 @@ namespace UnityExplorer.UI.Widgets
// our data index is further down. add the min difference and try again.
// the iterator will add 1 on the next loop so account for that.
// also, add the (spread - 1) of the cell we found at this index to skip it.
var spreadCurr = heightCache[rangeCache[i]].normalizedSpread;
int jmp = dataIndex - rangeCache[i] - 1;
jmp += spreadCurr - 2;
i = (jmp < 1 ? i : i + jmp);
}
}
@ -263,7 +262,7 @@ namespace UnityExplorer.UI.Widgets
{
//start at 1 because 0's start pos is always 0
for (int i = 1; i < heightCache.Count; i++)
SetIndex(i, heightCache[i].height);
SetIndex(i, heightCache[i].height, true);
}
}
}

View File

@ -9,7 +9,6 @@ namespace UnityExplorer.UI.Widgets
public interface IPoolDataSource<T> where T : ICell
{
int ItemCount { get; }
int GetRealIndexOfTempIndex(int tempIndex);
void OnCellBorrowed(T cell);
void OnCellReturned(T cell);

View File

@ -100,7 +100,7 @@ namespace UnityExplorer.UI.Widgets
private bool writingLocked;
private float timeofLastWriteLock;
private float prevContentHeight;
private float prevContentHeight = 1.0f;
public void SetUninitialized()
{
@ -115,8 +115,10 @@ namespace UnityExplorer.UI.Widgets
if (writingLocked && timeofLastWriteLock < Time.time)
writingLocked = false;
if (prevContentHeight == 0.0f && Content?.rect.height != 0.0f)
if (prevContentHeight <= 1f && Content?.rect.height > 1f)
{
prevContentHeight = Content.rect.height;
}
else if (Content.rect.height != prevContentHeight)
{
prevContentHeight = Content.rect.height;
@ -240,21 +242,13 @@ namespace UnityExplorer.UI.Widgets
{
bottomPoolIndex++;
////Instantiate and add to Pool
//RectTransform rect = GameObject.Instantiate(PrototypeCell.gameObject).GetComponent<RectTransform>();
//rect.gameObject.SetActive(true);
//rect.name = $"Cell_{CellPool.Count}";
//var cell = DataSource.CreateCell(rect);
//CellPool.Add(cell);
//rect.SetParent(ScrollRect.content, false);
var cell = Pool<T>.Borrow();
DataSource.OnCellBorrowed(cell);
var rect = cell.Rect;
//var rect = cell.Rect;
CellPool.Add(cell);
rect.SetParent(ScrollRect.content, false);
cell.Rect.SetParent(ScrollRect.content, false);
currentPoolCoverage += rect.rect.height;
currentPoolCoverage += PrototypeHeight;
}
if (andResetDataIndex)
@ -289,30 +283,29 @@ namespace UnityExplorer.UI.Widgets
var requiredCoverage = Math.Abs(RecycleViewBounds.y - RecycleViewBounds.x);
var currentCoverage = CellPool.Count * PrototypeHeight;
int cellsRequired = (int)Math.Ceiling((decimal)(requiredCoverage - currentCoverage) / (decimal)PrototypeHeight);
int cellsRequired = (int)Math.Floor((decimal)(requiredCoverage - currentCoverage) / (decimal)PrototypeHeight);
if (cellsRequired > 0 || forceRecreate)
{
WritingLocked = true;
//// Disable cells so DataSource can handle its content if need be
//var enumerator = GetPoolEnumerator();
//while (enumerator.MoveNext())
//{
// var curr = enumerator.Current;
// DataSource.DisableCell(CellPool[curr.cellIndex], curr.dataIndex);
//}
bottomDataIndex += cellsRequired;
int maxDataIndex = Math.Max(CellPool.Count + cellsRequired - 1, DataSource.ItemCount - 1);
if (bottomDataIndex > maxDataIndex)
bottomDataIndex = maxDataIndex;
// CreateCellPool will destroy existing cells and recreate list.
float curAnchor = Content.localPosition.y;
float curHeight = Content.rect.height;
CreateCellPool(resetDataIndex);
LayoutRebuilder.ForceRebuildLayoutImmediate(Content);
// fix slight jumping when resizing panel and size increases
if (Content.rect.height != curHeight)
{
var diff = Content.rect.height - curHeight;
Content.localPosition = new Vector3(Content.localPosition.x, Content.localPosition.y + (diff * 0.5f));
}
//Content.anchoredPosition = new Vector2(0, pos);
ScrollRect.UpdatePrevData();
SetScrollBounds();
@ -437,10 +430,7 @@ namespace UnityExplorer.UI.Widgets
SetRecycleViewBounds(true);
//if (!SetRecycleViewBounds(true))
// RefreshCells(false);
float yChange = (ScrollRect.content.anchoredPosition - prevAnchoredPos).y;
float yChange = ((Vector2)ScrollRect.content.localPosition - prevAnchoredPos).y;
float adjust = 0f;
if (yChange > 0) // Scrolling down
@ -642,7 +632,6 @@ namespace UnityExplorer.UI.Widgets
{
if (TopDataIndex > poolStartIndex && TopDataIndex < desiredBottomIndex)
{
//ExplorerCore.Log("Scroll bottom to top");
// top cell falls within the new range, rotate around that
int rotate = TopDataIndex - poolStartIndex;
for (int i = 0; i < rotate; i++)
@ -659,7 +648,6 @@ namespace UnityExplorer.UI.Widgets
}
else if (bottomDataIndex > poolStartIndex && bottomDataIndex < desiredBottomIndex)
{
//ExplorerCore.Log("Scroll top to bottom");
// bottom cells falls within the new range, rotate around that
int rotate = desiredBottomIndex - bottomDataIndex;
for (int i = 0; i < rotate; i++)
@ -676,9 +664,6 @@ namespace UnityExplorer.UI.Widgets
}
else
{
// new cells are completely different, set all cells
//ExplorerCore.Log("Scroll jump");
bottomDataIndex = desiredBottomIndex;
var enumerator = GetPoolEnumerator();
while (enumerator.MoveNext())
@ -692,17 +677,6 @@ namespace UnityExplorer.UI.Widgets
SetRecycleViewBounds(true);
//CheckDataSourceCountChange(out bool jumpToBottom);
//// force check recycles
//if (andReloadFromDataSource)
//{
// RecycleBottomToTop();
// RecycleTopToBottom();
//}
//LayoutRebuilder.ForceRebuildLayoutImmediate(Content);
SetScrollBounds();
ScrollRect.UpdatePrevData();