Files
MicrosoftIris/UIX/Microsoft/Iris/Data/UpdateHelper.cs
T
2022-03-03 08:14:05 -06:00

193 lines
6.7 KiB
C#

// Decompiled with JetBrains decompiler
// Type: Microsoft.Iris.Data.UpdateHelper
// Assembly: UIX, Version=4.8.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217
// MVID: A56C6C9D-B7F6-46A9-8BDE-B3D9B8D60B11
// Assembly location: C:\Program Files\Zune\UIX.dll
using Microsoft.Iris.Session;
using Microsoft.Iris.ViewItems;
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace Microsoft.Iris.Data
{
internal class UpdateHelper
{
private const int c_millisecondsBetweenUpdates = 100;
private const int c_millisecondsAllowedPerUpdate = 10;
private UpdateHelper.ItemDistanceComparer _itemDistanceComparer;
private IVirtualList _virtualList;
private List<int> _itemsToUpdate;
private int _lastInterestIndex;
private DispatcherTimer _timer;
private bool _listIsDirty;
private List<int> _outstandingUpdates;
private int _throttle;
public UpdateHelper(IVirtualList virtualList)
{
_virtualList = virtualList;
_itemsToUpdate = new List<int>();
_throttle = Environment.ProcessorCount * 2;
_outstandingUpdates = new List<int>();
}
public void AddIndex(int index)
{
_itemsToUpdate.Add(index);
_listIsDirty = true;
TriggerNextUpdate();
}
public void AdjustIndices(int lowThreshold, int amount) => AdjustIndices(lowThreshold, int.MaxValue, amount);
public void AdjustIndices(int lowThreshold, int highThreshold, int amt)
{
for (int index = 0; index < _itemsToUpdate.Count; ++index)
{
int num = _itemsToUpdate[index];
if (num >= lowThreshold && num <= highThreshold)
_itemsToUpdate[index] = num + amt;
}
if (_lastInterestIndex < lowThreshold || _lastInterestIndex > highThreshold)
return;
_lastInterestIndex += amt;
}
public void Clear() => _itemsToUpdate.Clear();
public void RemoveIndex(int index)
{
int count = _itemsToUpdate.Count;
int index1 = 0;
while (index1 < count && _itemsToUpdate[index1] != index)
++index1;
if (index1 >= count)
return;
int index2 = index1;
for (int index3 = index1 + 1; index3 < count; ++index3)
{
int num = _itemsToUpdate[index3];
if (num != index)
{
_itemsToUpdate[index2] = num;
++index2;
}
}
_itemsToUpdate.RemoveRange(index2, count - index2);
}
public void Dispose()
{
if (_timer == null)
return;
_timer.Enabled = false;
}
private void TriggerNextUpdate()
{
EnsureTimer();
_timer.Enabled = true;
}
private void DeliverNextUpdate(object senderObject, EventArgs unusedArgs)
{
if (_itemsToUpdate.Count == 0)
return;
if (_outstandingUpdates.Count == _throttle)
{
TriggerNextUpdate();
}
else
{
Repeater repeaterHost = _virtualList.RepeaterHost;
if (repeaterHost == null)
return;
int index1 = -1;
repeaterHost.GetFocusedIndex(ref index1);
if (repeaterHost.GetExtendedLayoutOutput(VisibleIndexRangeLayoutOutput.DataCookie) is VisibleIndexRangeLayoutOutput extendedLayoutOutput)
{
if (index1 != -1 && (index1 < extendedLayoutOutput.BeginVisible || index1 > extendedLayoutOutput.EndVisible))
index1 = -1;
if (index1 == -1)
index1 = extendedLayoutOutput.BeginVisible;
}
if (index1 != -1)
{
int dataIndex;
ListUtility.GetWrappedIndex(index1, _virtualList.Count, out dataIndex, out int _);
if (_lastInterestIndex != dataIndex)
_listIsDirty = true;
_lastInterestIndex = dataIndex;
}
if (_listIsDirty)
{
if (_itemDistanceComparer == null)
_itemDistanceComparer = new UpdateHelper.ItemDistanceComparer();
_itemDistanceComparer.Initialize(_lastInterestIndex, _virtualList.Count);
_itemsToUpdate.Sort(_itemDistanceComparer);
_listIsDirty = false;
}
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int count = 0;
do
{
++count;
int index2 = _itemsToUpdate[_itemsToUpdate.Count - count];
_outstandingUpdates.Add(index2);
_virtualList.NotifyRequestSlowData(index2);
}
while (stopwatch.ElapsedMilliseconds < 10L && _itemsToUpdate.Count != count && _outstandingUpdates.Count < _throttle);
_itemsToUpdate.RemoveRange(_itemsToUpdate.Count - count, count);
if (_itemsToUpdate.Count == 0)
return;
TriggerNextUpdate();
}
}
public int Throttle
{
get => _throttle;
set => _throttle = value;
}
public bool NotifySlowDataAcquireComplete(int index) => _outstandingUpdates.Remove(index);
private void EnsureTimer()
{
if (_timer != null)
return;
_timer = new DispatcherTimer();
_timer.AutoRepeat = false;
_timer.Interval = 100;
_timer.Tick += new EventHandler(DeliverNextUpdate);
}
private class ItemDistanceComparer : IComparer<int>
{
private int _focusedIndex;
private int _totalCount;
private int _midPoint;
public void Initialize(int focusedIndex, int totalCount)
{
_focusedIndex = focusedIndex;
_totalCount = totalCount;
_midPoint = totalCount / 2;
}
public int Compare(int left, int right) => GetDistance(right) - GetDistance(left);
private int GetDistance(int potential)
{
int num = Math.Abs(potential - _focusedIndex);
if (num > _midPoint)
num = _totalCount - num + 1;
return num;
}
}
}
}