wabbajack/Wabbajack/Extensions/DynamicDataExt.cs
2020-02-09 14:04:40 -06:00

83 lines
2.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using DynamicData;
namespace Wabbajack
{
public static class DynamicDataExt
{
public static IObservable<int> CollectionCount<TObject>(this IObservable<IChangeSet<TObject>> source)
{
int count = 0;
return source
.Select(changeSet =>
{
count += changeSet.Adds;
count -= changeSet.Removes;
return count;
})
.StartWith(0);
}
public static IObservable<int> CollectionCount<TObject, TKey>(this IObservable<IChangeSet<TObject, TKey>> source)
{
int count = 0;
return source
.Select(changeSet =>
{
count += changeSet.Adds;
count -= changeSet.Removes;
return count;
})
.StartWith(0);
}
public static IObservable<IChangeSet<TCache, TKey>> TransformAndCache<TObject, TKey, TCache>(
this IObservable<IChangeSet<TObject, TKey>> obs,
Func<TKey, TObject, TCache> onAdded,
Action<Change<TObject, TKey>, TCache> onUpdated)
{
var cache = new ChangeAwareCache<TCache, TKey>();
return obs
.Select(changeSet =>
{
foreach (var change in changeSet)
{
switch (change.Reason)
{
case ChangeReason.Add:
case ChangeReason.Update:
case ChangeReason.Refresh:
var lookup = cache.Lookup(change.Key);
TCache val;
if (lookup.HasValue)
{
val = lookup.Value;
}
else
{
val = onAdded(change.Key, change.Current);
cache.Add(val, change.Key);
}
onUpdated(change, val);
break;
case ChangeReason.Remove:
cache.Remove(change.Key);
break;
case ChangeReason.Moved:
break;
default:
throw new NotImplementedException();
}
}
return cache.CaptureChanges();
})
.Where(cs => cs.Count > 0);
}
}
}