internal static ProfilerEntryViewModel BindView(ProfilerEntryViewModel cache = null) { if (cache != null) { return(cache); } using (_boundViewModelsLock.WriteUsing()) _boundViewModels.Add(GCHandle.Alloc(cache = new ProfilerEntryViewModel(), GCHandleType.Weak)); return(cache); }
private void FillPage(ProfilerEntryViewModel target, IEnumerator <ProfilerEntryViewModel> items) { using (target.Children.DeferredUpdate()) using (target.ChildrenSorted.DeferredUpdate()) { var count = 0; var time = 0.0; while (count < PaginationCount) { if (!items.MoveNext() || items.Current == null) { break; } ProfilerEntryViewModel entry = items.Current; if (count < target.Children.Count) { target.Children[count] = entry; } else { target.Children.Add(entry); } if (count < target.ChildrenSorted.Count) { target.ChildrenSorted[count] = entry; } else { target.ChildrenSorted.Add(entry); } time += entry.UpdateTime; count++; } while (target.Children.Count > count) { target.Children.RemoveAt(target.Children.Count - 1); } while (target.ChildrenSorted.Count > count) { target.ChildrenSorted.RemoveAt(target.ChildrenSorted.Count - 1); } target.UpdateTime = time; target.OnPropertyChanged(nameof(UpdateTime)); } }
private void UpdateInternal(object owner, SlimProfilerEntry entry, bool forcePropertyUpdate = false) { if (entry == null) { if (!OwnerName.Equals(_noData) || forcePropertyUpdate) { OwnerName = _noData; OnPropertyChanged(nameof(OwnerName)); } // ReSharper disable once CompareOfFloatsByEqualityOperator if (UpdateTime != 0 || forcePropertyUpdate) { UpdateTime = 0; OnPropertyChanged(nameof(UpdateTime)); } if (Children.Count > 0) { Children.Clear(); } return; } string ownerId = ProfilerObjectIdentifier.Identify(owner); if (!ownerId.Equals(OwnerName) || forcePropertyUpdate) { OwnerName = ownerId; OnPropertyChanged(nameof(OwnerName)); } UpdateTime = entry.UpdateTime; OnPropertyChanged(nameof(UpdateTime)); if (entry is FatProfilerEntry fat) { if (ChildrenSorted.IsObserved || Children.IsObserved || forcePropertyUpdate) { _childrenUpdateDeferred = false; ICollection <object> keys = fat.ChildUpdateKeys(); var id = 0; foreach (object key in keys) { if (fat.ChildUpdateTime.TryGetValue(key, out SlimProfilerEntry child) && child.UpdateTime > DisplayTimeThreshold) { if (id >= Children.Count) { var result = new ProfilerEntryViewModel(); result.UpdateInternal(key, child, forcePropertyUpdate); Children.Add(result); id++; } else { Children[id++].UpdateInternal(key, child, forcePropertyUpdate); } } } while (Children.Count > id) { Children.RemoveAt(Children.Count - 1); } using (ChildrenSorted.DeferredUpdate()) { var sortedEnumerable = Children.OrderBy(x => (int)(-x.UpdateTime / DisplayTimeThreshold)); if (Children.Count > PaginationCount) { var pageCount = (int)Math.Ceiling(Children.Count / (float)PaginationCount); if (_wasPaged) { while (ChildrenSorted.Count > pageCount) { ChildrenSorted.RemoveAt(ChildrenSorted.Count - 1); } } else { ChildrenSorted.Clear(); } while (ChildrenSorted.Count < pageCount) { ChildrenSorted.Add(new ProfilerEntryViewModel()); } using (var iterator = sortedEnumerable.GetEnumerator()) { for (var i = 0; i < pageCount; i++) { ChildrenSorted[i].OwnerName = $"Items {i * PaginationCount + 1} to {i * PaginationCount + PaginationCount}"; ChildrenSorted[i].OnPropertyChanged(nameof(OwnerName)); FillPage(ChildrenSorted[i], iterator); } } _wasPaged = true; } else { ChildrenSorted.Clear(); foreach (var k in sortedEnumerable) { ChildrenSorted.Add(k); } _wasPaged = false; } } } else { _childrenUpdateDeferred = true; } } else { Children.Clear(); ChildrenSorted.Clear(); } }