Exemple #1
0
        public EventListViewModel(IConcurrencyService concurrencyService)
        {
            var eventsCollection = new ObservableCollectionExtended <EventItem>();

            Events = new ReadOnlyObservableCollection <EventItem>(eventsCollection);

            var selectionChangeSubject = new Subject <Func <Selection, Selection> >();

            mSubmitSelectionChange    = selectionChangeSubject.OnNext;
            WhenEventSelectionChanges = selectionChangeSubject
                                        .ObserveOn(concurrencyService.TaskPoolRxScheduler);

            this.WhenActivated((CompositeDisposable disposables) =>
            {
                var whenIncludeInputsChanges =
                    IncludeInputObservables
                    ?.ObserveOn(concurrencyService.TaskPoolRxScheduler)
                    .DistinctUntilChanged()
                    ?? Observable.Return(false);

                var eventsProcessedUntilInvalid =
                    whenIncludeInputsChanges.Publish(whenIncludeInputsChangesPub =>
                                                     whenIncludeInputsChangesPub.SelectMany(includeInputs =>
                                                                                            Observables
                                                                                            .ObserveOn(concurrencyService.TaskPoolRxScheduler)
                                                                                            .Replay(observablesPub =>
                {
                    var observablesExpanded =
                        observablesPub
                        .MergeMany(obs => Observable.Return(obs))
                        .ExpandDistinct(obs => includeInputs ? obs.Inputs : Observable.Empty <IObservableInstance>());

                    var events = observablesExpanded
                                 .SelectMany(obs => Observable.Return(EventItem.FromObservableInstance(obs))
                                             .Concat(obs.Subscriptions.SelectMany(sub => sub.Events.Select(e => EventItem.FromStreamEvent(sub, e)))))
                                 .Merge(ClientEvents?.Select(EventItem.FromClientEvent) ?? Observable.Empty <EventItem>());

                    var eventsProcessed = events
                                          .ToObservableChangeSet(e => e.SequenceId)
                                          .Filter(SequenceIdRange?.Select(CreateFilter) ?? Observable.Return <Func <EventItem, bool> >(_ => true))
                                          .Batch(TimeSpan.FromMilliseconds(100))
                                          .Sort(Utility.Comparer <EventItem> .ByKey(e => e.SequenceId));

                    // Terminate the stream if an observable is removed or the include inputs
                    // flag changes, as in both cases we need to rebuild the output from scratch.
                    return(eventsProcessed
                           .TakeUntil(observablesPub.Where(chg => chg.Removes > 0))
                           .TakeUntil(whenIncludeInputsChangesPub.Where(ii => ii != includeInputs)));
                }))
                                                     )
                    .SubscribeOn(concurrencyService.TaskPoolRxScheduler);

                Observable.Defer(() =>
                {
                    eventsCollection.Clear();

                    return(eventsProcessedUntilInvalid
                           .ObserveOn(concurrencyService.DispatcherRxScheduler)
                           .Bind(eventsCollection, new SortedObservableCollectionAdaptor <EventItem, long>(int.MaxValue)));
                })
                .SubscribeOn(concurrencyService.DispatcherRxScheduler)
                .Repeat()
                .Subscribe()
                .DisposeWith(disposables);
            });

            Func <EventItem, bool> CreateFilter((long start, long end) range)
            {
                return(e => e.SequenceId >= range.start && e.SequenceId <= range.end);
            }
        }