| | | 1 | | // ----------------------------------------------------------------------- |
| | | 2 | | // <copyright file="SortEngine.cs" company="Stéphane ANDRE"> |
| | | 3 | | // Copyright (c) Stéphane ANDRE. All rights reserved. |
| | | 4 | | // </copyright> |
| | | 5 | | // ----------------------------------------------------------------------- |
| | | 6 | | |
| | | 7 | | using System; |
| | | 8 | | using System.Collections.Generic; |
| | | 9 | | using System.Linq; |
| | | 10 | | using System.Reactive; |
| | | 11 | | using System.Reactive.Subjects; |
| | | 12 | | |
| | | 13 | | namespace MyNet.Observable.Collections.Sorting; |
| | | 14 | | |
| | | 15 | | /// <summary> |
| | | 16 | | /// Provides sorting capabilities for a collection of items of type T. It maintains the current sorting properties and e |
| | | 17 | | /// </summary> |
| | | 18 | | /// <typeparam name="T">The type of items to be sorted.</typeparam> |
| | | 19 | | public sealed class SortEngine<T> : IDisposable |
| | | 20 | | { |
| | | 21 | | /// <summary> |
| | | 22 | | /// Preserves source order when no explicit sort keys are configured (avoids <see cref="Comparer{T}.Default"/> on no |
| | | 23 | | /// </summary> |
| | 24 | 24 | | private static readonly IComparer<T> SourceOrderComparer = Comparer<T>.Create(static (_, _) => 0); |
| | | 25 | | |
| | 192 | 26 | | private readonly BehaviorSubject<IComparer<T>> _comparer = new(SourceOrderComparer); |
| | 192 | 27 | | private readonly Subject<Unit> _resort = new(); |
| | | 28 | | |
| | | 29 | | /// <summary> |
| | | 30 | | /// Gets the current sorting properties applied to the collection. This property holds an array of sorting propertie |
| | | 31 | | /// </summary> |
| | 192 | 32 | | public ISortingProperty<T>[] Current { get; private set; } = []; |
| | | 33 | | |
| | | 34 | | /// <summary> |
| | | 35 | | /// Gets an observable that emits the current comparer based on the sorting properties. Whenever the sorting propert |
| | | 36 | | /// </summary> |
| | 372 | 37 | | public IObservable<IComparer<T>> Comparer => _comparer; |
| | | 38 | | |
| | | 39 | | /// <summary> |
| | | 40 | | /// Gets an observable that emits a notification whenever the sorting engine is invalidated. This observable can be |
| | | 41 | | /// </summary> |
| | 372 | 42 | | public IObservable<Unit> Resort => _resort; |
| | | 43 | | |
| | | 44 | | /// <summary> |
| | | 45 | | /// Updates the sorting engine with a new set of sorting properties. This method takes an enumerable of sorting prop |
| | | 46 | | /// </summary> |
| | | 47 | | /// <param name="sorting">The new set of sorting properties to apply.</param> |
| | 27 | 48 | | public void Set(IEnumerable<ISortingProperty<T>> sorting) => OnNext(sorting); |
| | | 49 | | |
| | | 50 | | /// <summary> |
| | | 51 | | /// Clears the sorting engine by setting the sorting properties to an empty array. This method effectively removes a |
| | | 52 | | /// </summary> |
| | 78 | 53 | | public void Clear() => OnNext([]); |
| | | 54 | | |
| | | 55 | | /// <summary> |
| | | 56 | | /// Invalidates the sorting engine by re-emitting the current sorting properties. This method can be used to trigger |
| | | 57 | | /// </summary> |
| | 0 | 58 | | public void Invalidate() => _resort.OnNext(Unit.Default); |
| | | 59 | | |
| | | 60 | | /// <summary> |
| | | 61 | | /// Updates the sorting engine with a new set of sorting properties. This method takes an enumerable of sorting prop |
| | | 62 | | /// </summary> |
| | | 63 | | /// <param name="sorting">The new set of sorting properties to apply.</param> |
| | | 64 | | private void OnNext(IEnumerable<ISortingProperty<T>> sorting) |
| | | 65 | | { |
| | 105 | 66 | | var newSorting = sorting.ToArray(); |
| | 105 | 67 | | Current = newSorting; |
| | | 68 | | |
| | 105 | 69 | | if (newSorting.Length == 0) |
| | | 70 | | { |
| | 84 | 71 | | _comparer.OnNext(SourceOrderComparer); |
| | 84 | 72 | | _resort.OnNext(Unit.Default); |
| | 84 | 73 | | return; |
| | | 74 | | } |
| | | 75 | | |
| | 21 | 76 | | _comparer.OnNext(new SortingComparer<T>(newSorting)); |
| | 21 | 77 | | _resort.OnNext(Unit.Default); |
| | 21 | 78 | | } |
| | | 79 | | |
| | | 80 | | /// <summary> |
| | | 81 | | /// Disposes the sort engine by disposing the underlying comparer subject. This method is called when the sort engin |
| | | 82 | | /// </summary> |
| | | 83 | | public void Dispose() |
| | | 84 | | { |
| | 162 | 85 | | _comparer.Dispose(); |
| | 162 | 86 | | _resort.Dispose(); |
| | 162 | 87 | | } |
| | | 88 | | } |
| | | 89 | | |