Example #1
0
        public IObservable <IChangeSet <T> > Run()
        {
            return(Observable.Create <IChangeSet <T> >(observer =>
            {
                var locker = new object();

                Func <T, bool> predicate = t => false;

                var all = new List <ItemWithMatch>();
                var filtered = new ChangeAwareList <ItemWithMatch>();


                //requery when predicate changes
                var predicateChanged = _predicates.Synchronize(locker)
                                       .Select(newPredicate =>
                {
                    predicate = newPredicate;
                    Requery(predicate, all, filtered);
                    return filtered.CaptureChanges();
                });

                /*
                 * Apply the transform operator so 'IsMatch' state can be evalutated and captured one time only
                 * This is to eliminate the need to re-apply the predicate when determining whether an item was previously matched
                 */
                var filteredResult = _source.Synchronize(locker)
                                     .Transform(t => new ItemWithMatch(t, predicate(t)))
                                     .Select(changes =>
                {
                    all.Clone(changes);                           //keep track of all changes
                    filtered.Filter(changes, iwm => iwm.IsMatch); //maintain filtered result
                    return filtered.CaptureChanges();
                });

                return predicateChanged.Merge(filteredResult)
                .NotEmpty()
                .Select(changes => changes.Transform(iwm => iwm.Item))
                .SubscribeSafe(observer);
            }));
        }