public IObservable <IGroupChangeSet <TObject, TKey, TGroupKey> > Run() { return(Observable.Create <IGroupChangeSet <TObject, TKey, TGroupKey> >( observer => { var locker = new object(); // create source group cache var sourceGroups = _source.Synchronize(locker).Group(_groupSelector).DisposeMany().AsObservableCache(); // create parent groups var parentGroups = _resultGroupSource.Synchronize(locker).Transform( x => { // if child already has data, populate it. var result = new ManagedGroup <TObject, TKey, TGroupKey>(x); var child = sourceGroups.Lookup(x); if (child.HasValue) { // dodgy cast but fine as a groups is always a ManagedGroup; var group = (ManagedGroup <TObject, TKey, TGroupKey>)child.Value; result.Update(updater => updater.Clone(group.GetInitialUpdates())); } return result; }).DisposeMany().AsObservableCache(); // connect to each individual item and update the resulting group var updatesFromChildren = sourceGroups.Connect().SubscribeMany( x => x.Cache.Connect().Subscribe( updates => { var groupToUpdate = parentGroups.Lookup(x.Key); if (groupToUpdate.HasValue) { groupToUpdate.Value.Update(updater => updater.Clone(updates)); } })).DisposeMany().Subscribe(); var notifier = parentGroups.Connect().Select( x => { var groups = x.Select(s => new Change <IGroup <TObject, TKey, TGroupKey>, TGroupKey>(s.Reason, s.Key, s.Current)); return new GroupChangeSet <TObject, TKey, TGroupKey>(groups); }).SubscribeSafe(observer); return Disposable.Create( () => { notifier.Dispose(); sourceGroups.Dispose(); parentGroups.Dispose(); updatesFromChildren.Dispose(); }); })); }
private Tuple <ManagedGroup <TObject, TKey, TGroupKey>, bool> GetCache(TGroupKey key) { var cache = _groupCache.Lookup(key); if (cache.HasValue) { return(Tuple.Create(cache.Value, false)); } var newcache = new ManagedGroup <TObject, TKey, TGroupKey>(key); _groupCache[key] = newcache; return(Tuple.Create(newcache, true)); }
private bool Equals(ManagedGroup <TObject, TKey, TGroupKey> other) { return(EqualityComparer <TGroupKey> .Default.Equals(Key, other.Key)); }