public ActiveProcessesService(TimeSpan refreshInterval, IScheduler scheduler)
        {
            Ensure.ArgumentNotNull(refreshInterval, nameof(refreshInterval));
            Ensure.ArgumentNotNull(scheduler, nameof(scheduler));

            _scheduler       = scheduler;
            _refreshInterval = refreshInterval;

            _scheduler.SchedulePeriodic(_refreshInterval, () =>
            {
                var processes = Process.GetProcesses();

                _processNames.Edit(innerList =>
                {
                    innerList.Clear();
                    innerList.AddRange(processes.Select(x => x.ProcessName));
                });

                _processNames.Edit(innerList =>
                {
                    innerList.Clear();
                    innerList.AddRange(processes.Select(x => x.MainWindowTitle));
                });
            });
        }
Exemple #2
0
 /// <summary>
 /// Removes a validation from the validations collection.
 /// </summary>
 /// <param name="validation">Validation component to be removed from the collection.</param>
 public void Remove(IValidationComponent validation) => _validationSource.Edit(list =>
 {
     if (list.Contains(validation))
     {
         list.Remove(validation);
     }
 });
        /// <summary>
        /// Binds the results to the specified <see cref="IObservableList{T}"/>. Unlike
        /// binding to a <see cref="ReadOnlyObservableCollection{T}"/> which loses the
        /// ability to refresh items, binding to an <see cref="IObservableList{T}"/>.
        /// allows for refresh changes to be preserved and keeps the list read-only.
        /// </summary>
        /// <typeparam name="TObject">The type of the object.</typeparam>
        /// <typeparam name="TKey">The type of the key.</typeparam>
        /// <param name="source">The source.</param>
        /// <returns>The <paramref name="source"/> changeset for continued chaining.</returns>
        /// <exception cref="System.ArgumentNullException">source</exception>
        public static IObservable <IChangeSet <TObject, TKey> > BindToObservableList <TObject, TKey>(
            this IObservable <IChangeSet <TObject, TKey> > source,
            out IObservableList <TObject> observableList)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            // Load our source list with the change set.
            // Each changeset we need to convert to remove the key.
            var sourceList = new SourceList <TObject>();

            // Output our readonly observable list, preventing the sourcelist from being editted from anywhere else.
            observableList = sourceList;

            // Return a observable that will connect to the source so we can properly dispose when the pipeline ends.
            return(Observable.Create <IChangeSet <TObject, TKey> >(observer =>
            {
                return source
                .Do(changes => sourceList.Edit(editor => editor.Clone(changes.RemoveKey(editor))))
                .Finally(() => sourceList.Dispose())
                .SubscribeSafe(observer);
            }));
        }
        public static IObservable <IChangeSet <TElement> > SelectedItemsAsObservable <TControl, TElement>(this TControl control) where TControl : ListViewBase
        {
            return(Observable.Create <IChangeSet <TElement> >(o =>
            {
                var disposes = new CompositeDisposable();
                var items = new SourceList <TElement>();

                control.Events()
                .SelectionChanged
                .Subscribe(x =>
                {
                    items.Edit(y =>
                    {
                        y.RemoveMany(x.RemovedItems.Cast <TElement>());
                        y.AddRange(x.AddedItems.Cast <TElement>());
                    });
                })
                .DisposeWith(disposes);
                items.Connect()
                .Subscribe(o)
                .DisposeWith(disposes);

                return disposes;
            }));
        }
Exemple #5
0
        private async Task SetRecommendationsAsync()
        {
            try
            {
                var profile = await _userProfileContainer.GetAsync();

                var statusId = profile?.StatusId;
                if (statusId != null)
                {
                    IsBusy = true;

                    var recommendationsList =
                        await _recommendationsService.GetRecommendationsAsync(statusId.Value, LifecycleToken);

                    _models.Edit((innerList) =>
                    {
                        innerList.Clear();
                        innerList.AddRange(recommendationsList.Data);
                    });
                }
            }
            catch (Exception e)
            {
                await _errorHandler.HandleAsync(e);
            }
            finally
            {
                IsBusy = false;
            }
        }
        public MainViewModel()
        {
            _locationSource.Edit(innerList =>
            {
                innerList.Add(new LocationViewModel()
                {
                    LocationNumber = "",
                    LocationName   = "",
                    LOB            = "",
                    ReportDate     = ""
                });
            });

            _driverSource.Edit(innerList =>
            {
                innerList.Add(new DriverViewModel()
                {
                    DriverName = ""
                });
            });

            _locationSource.Connect()
            .Bind(out _locations)
            .Subscribe();

            _driverSource.Connect()
            .Bind(out _drivers)
            .Subscribe();
        }
Exemple #7
0
        public DetailViewModel()
        {
            _sources = new SourceList <UserTask>();
            _sources.Connect()
            .Bind(out _items)
            .Subscribe();

            _sources.AddRange(GetDemoTask());

            Save = ReactiveCommand.Create(() =>
            {
                FileService.Save(_sources.Items.ToList());
            });

            Insert = ReactiveCommand.Create(() =>
            {
                _sources.Edit(x =>
                {
                    x.Add(new UserTask()
                    {
                        Contents = $"{DateTime.Now.ToString("hh:mm:ss")}",
                    });
                });
            });
        }
Exemple #8
0
        public FilterDynamicDataViewModel()
        {
            this.WhenActivated((CompositeDisposable disposables) =>
            {
                _searchResultSource = new SourceList <RssEntry>().DisposeWith(disposables);

                _searchResultSource
                .Connect()
                .ObserveOn(RxApp.MainThreadScheduler)
                .Bind(out var searchResultsBinding)
                .Subscribe()
                .DisposeWith(disposables);

                this.SearchResults = searchResultsBinding;

                Search =
                    ReactiveCommand
                    .CreateFromTask(
                        async(ct) =>
                {
                    var worldNews = await RssDownloader.DownloadRss("https://www.reddit.com/r/worldnews/new/.rss", ct).ConfigureAwait(false);

                    _searchResultSource
                    .Edit(
                        innerList =>
                    {
                        innerList.Clear();
                        innerList.AddRange(worldNews);
                    });
                })
                    .DisposeWith(disposables);
            });
        }
        public EndpointsViewModel()
        {
            sourceEndpoints = new SourceList<Endpoint>();

            var filter = Observable.Return("")
                .Concat(this.ChangedProperty<string>(nameof(Search)).Select(pc => pc.After))
                //.Throttle(TimeSpan.FromMilliseconds(500))
                .Select(BuildFilter);

            sourceEndpoints.Connect()
                .Filter(filter)
                .Sort(SortExpressionComparer<Endpoint>.Ascending(e => e.Name))
                .ObserveOnUI()
                .Bind(out endpoints)
                .Subscribe();

            ServiceControl.Instance.Endpoints()
                .SubscribeOnBackground()
                .Subscribe(es =>
                {
                    sourceEndpoints.Edit(inner =>
                    {
                        inner.Clear();
                        inner.AddRange(es.DeserializeCollection<Endpoint>());
                    });
                });
        }
        public void Reload(BoxScheme scheme)
        {
            _boardsSource.Edit(x =>
            {
                x.Clear();
                x.AddRange(scheme.Boards.Select(y => new BoardImportSchemeViewModel
                {
                    Id = y.Id, Name = y.Name, IsSelected = true
                }));
            });
            _columnsSource.Edit(x =>
            {
                x.Clear();
                x.AddRange(scheme.Columns.Select(y => new ColumnImportSchemeViewModel
                {
                    Id = y.Id, BoardId = y.BoardId, Name = y.Name, IsSelected = true
                }));
            });
            _rowsSource.Edit(x =>
            {
                x.Clear();
                x.AddRange(scheme.Rows.Select(y => new RowImportSchemeViewModel
                {
                    Id = y.Id, BoardId = y.BoardId, Name = y.Name, IsSelected = true
                }));
            });

            SelectedBoard = _boardsSource.Items.FirstOrDefault();
        }
        /// <summary>
        /// Binds the results to the specified <see cref="IObservableList{T}"/>. Unlike
        /// binding to a <see cref="ReadOnlyObservableCollection{T}"/> which loses the
        /// ability to refresh items, binding to an <see cref="IObservableList{T}"/>.
        /// allows for refresh changes to be preserved and keeps the list read-only.
        /// </summary>
        /// <typeparam name="TObject">The type of the object.</typeparam>
        /// <typeparam name="TKey">The type of the key.</typeparam>
        /// <param name="source">The source.</param>
        /// <returns>The <paramref name="source"/> changeset for continued chaining.</returns>
        /// <exception cref="System.ArgumentNullException">source</exception>
        public static IObservable <ISortedChangeSet <TObject, TKey> > BindToObservableList <TObject, TKey>(
            this IObservable <ISortedChangeSet <TObject, TKey> > source,
            out IObservableList <TObject> observableList)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            // Load our source list with the change set.
            // Each changeset we need to convert to remove the key.
            var sourceList = new SourceList <TObject>();

            // Output our readonly observable list, preventing the sourcelist from being editted from anywhere else.
            observableList = sourceList;

            // Return a observable that will connect to the source so we can properly dispose when the pipeline ends.
            return(Observable.Create <ISortedChangeSet <TObject, TKey> >(observer =>
            {
                return source
                .Do(changes =>
                {
                    switch (changes.SortedItems.SortReason)
                    {
                    case SortReason.InitialLoad:
                        sourceList.AddRange(changes.SortedItems.Select(kv => kv.Value));
                        break;

                    case SortReason.ComparerChanged:
                    case SortReason.DataChanged:
                    case SortReason.Reorder:
                        sourceList.Edit(editor => editor.Clone(changes.RemoveKey(editor)));
                        break;

                    case SortReason.Reset:
                        sourceList.Edit(editor =>
                        {
                            editor.Clear();
                            editor.AddRange(changes.SortedItems.Select(kv => kv.Value));
                        });
                        break;
                    }
                })
                .Finally(() => sourceList.Dispose())
                .SubscribeSafe(observer);
            }));
        }
Exemple #12
0
 public void Delete(UserDetailsViewModel viewModel)
 {
     _userService
     .DeleteUser(viewModel.Id)
     .Subscribe(_ =>
     {
         _users
         .Edit(innerList =>
         {
             var existing = innerList.FirstOrDefault(x => x.Id == viewModel.Id);
             if (existing != null)
             {
                 innerList.Remove(existing);
             }
         });
     });
 }
        public void SingleSubscriberThatThrows()
        {
            var s = new SourceList <int>();

            s.Connect().Subscribe(i => { throw new NotImplementedException(); });

            Assert.Throws <NotImplementedException>(() => s.Edit(u => u.Add(1)));
        }
Exemple #14
0
 public static void ClearAndAddRange <T>(this SourceList <T> list, IEnumerable <T> data)
 {
     list.Edit(il =>
     {
         il.Clear();
         il.AddRange(data);
     });
 }
        public async Task GetPage(string query, int pageNumber)
        {
            if (string.IsNullOrEmpty(query))
            {
                RemainingPages.OnNext(0);
                _moviesInternalList.Clear();
                _searchActive = false;
                return;
            }
            if (query == _query && pageNumber == _pageNumber)
            {
                return;
            }

            // Cancel search
            if (_searchActive)
            {
                _cts.Cancel();
                _cts = new CancellationTokenSource();
            }

            try
            {
                _searchActive = true;
                var result = await _dataService.GetItemsAsync(query, pageNumber, _cts.Token);

                if (_query != query)
                {
                    _moviesInternalList.Clear();
                }
                _query      = query;
                _pageNumber = pageNumber;
                if (result.Response)
                {
                    _moviesInternalList.Edit(list => list.AddRange(result.Movies));
                    RemainingPages.OnNext(result.RemainingPages);
                }
                else
                {
                    RemainingPages.OnNext(0);
                }
            }
            catch (OperationCanceledException)
            {
                Debug.WriteLine("Cancelled previous search");
                _searchActive = false;
                await GetPage(query, pageNumber);
            }
            catch (Exception e)
            {
                RemainingPages.OnNext(0);
                Debug.WriteLine("Something unexpected happened while fetching data");
            }
            finally
            {
                _searchActive = false;
            }
        }
Exemple #16
0
 public TradeModel(IEnumerable <ExchangeTrade> exchangeTrades = null)
 {
     Trades          = new SourceList <ExchangeTrade>();
     tradeObservable = Trades.Connect();
     if (exchangeTrades != null)
     {
         Trades.Edit(innerList => innerList.AddRange(exchangeTrades));
     }
 }
Exemple #17
0
        public SortDynamicDataViewModel()
        {
            this.WhenActivated((CompositeDisposable disposables) =>
            {
                _searchResultSource = new SourceList <RssEntry>().DisposeWith(disposables);

                var sorter =
                    this.WhenAnyValue(x => x.SelectedSortType)
                    .Select(
                        SelectedSortType =>
                {
                    switch (SelectedSortType)
                    {
                    case SortType.DateTimeAscending:
                        return(SortExpressionComparer <RssEntry> .Ascending(x => x.Updated));

                    case SortType.DateTimeDescending:
                        return(SortExpressionComparer <RssEntry> .Descending(x => x.Updated));

                    case SortType.TitleAscending:
                        return(SortExpressionComparer <RssEntry> .Ascending(x => x.Title));

                    case SortType.TitleDescending:
                    default:
                        return(SortExpressionComparer <RssEntry> .Descending(x => x.Title));
                    }
                });

                _searchResultSource
                .Connect()
                .SubscribeOn(RxApp.TaskpoolScheduler)
                .Sort(sorter)
                .ObserveOn(RxApp.MainThreadScheduler)
                .Bind(out var searchResultsBinding)
                .Subscribe()
                .DisposeWith(disposables);

                this.SearchResults = searchResultsBinding;

                Search =
                    ReactiveCommand
                    .CreateFromTask(
                        async(ct) =>
                {
                    var worldNews = await RssDownloader.DownloadRss("https://www.reddit.com/r/worldnews/new/.rss", ct).ConfigureAwait(false);

                    _searchResultSource
                    .Edit(
                        innerList =>
                    {
                        innerList.Clear();
                        innerList.AddRange(worldNews);
                    });
                })
                    .DisposeWith(disposables);
            });
        }
        public void ExceptionShouldBeThrownInSubscriberCode()
        {
            var changesCountFromSubscriber1 = 0;
            var changesCountFromSubscriber2 = 0;
            var source = new SourceList <int>();

            var observable = source.Connect().RefCount();

            observable.Subscribe(i => changesCountFromSubscriber1++);
            observable.Subscribe(i => { throw new NotImplementedException(); });
            observable.Subscribe(i => changesCountFromSubscriber2++);

            source.Edit(l => l.Add(1));
            source.Edit(l => l.Add(2));

            Assert.That(changesCountFromSubscriber1, Is.EqualTo(2));
            Assert.That(changesCountFromSubscriber2, Is.EqualTo(2));
        }
Exemple #19
0
        public async Task CreateData(CancellationToken ct)
        {
            var rng = new Random();

            while (!ct.IsCancellationRequested)
            {
                _dataList.Edit(innerList =>
                {
                    innerList.Clear();

                    Observable.Range(0, 20).Subscribe(index =>
                    {
                        var number = rng.Next(-10000, 10000);
                        innerList.Add(number);
                    });
                });
                await Task.Yield();
            }
        }
        public void MultipleSubscribersHandlingErrorsWithOneThrowing_MultipleEdits()
        {
            var firstSubscriberCallCount             = 0;
            var secondSubscriberCallCount            = 0;
            var firstSubscriberExceptionHandleCount  = 0;
            var secondSubscriberExceptionHandleCount = 0;
            var s = new SourceList <int>();

            s.Connect().Subscribe(i => firstSubscriberCallCount++, e => firstSubscriberExceptionHandleCount++);
            s.Connect().Subscribe(i => { throw new NotImplementedException(); });
            s.Connect().Subscribe(i => secondSubscriberCallCount++, e => secondSubscriberExceptionHandleCount++);

            s.Edit(u => u.Add(1));
            s.Edit(u => u.Add(1));

            Assert.That(firstSubscriberCallCount, Is.EqualTo(2));
            Assert.That(secondSubscriberCallCount, Is.EqualTo(2));
            Assert.That(firstSubscriberExceptionHandleCount, Is.EqualTo(1));
            Assert.That(secondSubscriberExceptionHandleCount, Is.EqualTo(1));
        }
Exemple #21
0
        public void ReadonlyCollectionDynamicData()
        {
            var scheduler  = new TestScheduler();
            var list       = new SourceList <int>();
            var filterFunc = new BehaviorSubject <Func <int, bool> >(x => true);

            list.Connect()
            //if you comment out the filter or the observeon then this passes
            .Filter(filterFunc.ObserveOn(scheduler))
            .ObserveOn(scheduler)
            .Bind(out var oc)
            .Subscribe();

            list.Edit(updateAction =>
            {
                updateAction.Add(1);
                updateAction.Add(2);
                updateAction.Add(3);
            });

            scheduler.Start();
            oc.Count.Should().Be(3);

            list.Edit(updateAction =>
            {
                updateAction.Remove(1);
                updateAction.Remove(2);
                updateAction.Remove(3);

                updateAction.Count.Should().Be(0);

                updateAction.Add(4);
                updateAction.Add(5);
                updateAction.Add(6);
            });

            scheduler.Start();

            //This fails and those other update actions aren't removed
            oc.Count.Should().Be(3);
        }
Exemple #22
0
        public LineScroller(FileInfo file,
                            IObservable <ILineProvider> latest,
                            IObservable <ScrollRequest> scrollRequest,
                            ILogger logger,
                            IScheduler scheduler = null)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }
            if (latest == null)
            {
                throw new ArgumentNullException(nameof(latest));
            }
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            logger.Info($"Constructing file tailer for {file.FullName}");

            var lines = new SourceList <Line>();

            Lines = lines.AsObservableList();

            var locker = new object();

            scrollRequest = scrollRequest.Synchronize(locker);


            var aggregator = latest.CombineLatest(scrollRequest, (currentLines, scroll) => currentLines.ReadLines(scroll).ToArray())
                             .Subscribe(currentPage =>
            {
                var previous = lines.Items.ToArray();
                var added    = currentPage.Except(previous, Line.TextStartComparer).ToArray();
                var removed  = previous.Except(currentPage, Line.TextStartComparer).ToArray();

                lines.Edit(innerList =>
                {
                    if (removed.Any())
                    {
                        innerList.RemoveMany(removed);
                    }
                    if (added.Any())
                    {
                        innerList.AddRange(added);
                    }
                });
            });

            _cleanUp = new CompositeDisposable(Lines, lines, aggregator);
        }
        public DashboardViewModelCore(DustService dustService = null, ExcelGenerator excelGenerator = null, IScreen screen = null)
        {
            _excelGenerator = excelGenerator ?? Locator.Current.GetService <ExcelGenerator>();
            _dustService    = dustService ?? Locator.Current.GetService <DustService>();
            HostScreen      = screen ?? Locator.Current.GetService <IScreen>();

            var canLoadDataCommand = this.WhenAnyValue(p => p.SelectedStation)
                                     .Select(p => p != null);

            LoadDataCommand = ReactiveCommand.CreateFromObservable <Station, Record[]>(station =>
            {
                //Info = new DashboardInfo();
                _values.Clear();

                IObservable <Record[]> s = _dustService.GetAvailableParametersAsync(station)
                                           .Select(@params => @params.Select(p => p.Param).ToArray())
                                           .Select(@params => _dustService.GetStationRecordsAsync(station.Code, @params)).Switch();

                return(Observable.Start(() => s, RxApp.TaskpoolScheduler).Switch().TakeUntil(CancelCommand));;
            }, canLoadDataCommand);

            CancelCommand = ReactiveCommand.Create(
                () => { },
                this.LoadDataCommand.IsExecuting);

            this.WhenActivated(cleanup =>
            {
                var share = _values.Connect().Publish().RefCount();
                share.ToCollection().Select(records =>
                {
                    return(Enum.GetValues(typeof(RecordType)).Cast <RecordType>()
                           .Select(type => records.LastOrDefault(r => r.Type == type)));
                }).BindTo(this, vm => vm.LastRecords).DisposeWith(cleanup);

                share.Bind(StationData).Subscribe().DisposeWith(cleanup);

                LoadDataCommand.ThrownExceptions.Subscribe(ShowError).DisposeWith(cleanup);

                LoadDataCommand.Subscribe(records =>
                {
                    _values.Edit(e => e.AddRange(records));
                }).DisposeWith(cleanup);

                var canSaveToExcelCommand = StationData.ObserveCollectionChanges().Select(_ => StationData.Count > 0);

                SaveToExcelCommand = ReactiveCommand.CreateFromTask <IEnumerable <Record> >(data => _excelGenerator.CreateExcel(SelectedStation.Code, data), canSaveToExcelCommand);

                SaveToExcelCommand.ThrownExceptions.Subscribe(ShowError);

                this.WhenAnyValue(p => p.SelectedStation).Where(p => p != null).Do(_ => CancelCommand.Execute().Subscribe()).InvokeCommand(LoadDataCommand).DisposeWith(cleanup);;
            });
        }
 public void UpdateRows(List <Row> rows)
 {
     _rowsSource.Edit(x =>
     {
         x.Clear();
         if (rows != null)
         {
             x.AddRange(rows.Select(y => new RowImportSchemeViewModel
             {
                 Id = y.Id, BoardId = y.BoardId, Name = y.Name, IsSelected = true
             }));
         }
     });
 }
 public void UpdateColumns(List <Column> columns)
 {
     _columnsSource.Edit(x =>
     {
         x.Clear();
         if (columns != null)
         {
             x.AddRange(columns.Select(y => new ColumnImportSchemeViewModel
             {
                 Id = y.Id, BoardId = y.BoardId, Name = y.Name, IsSelected = true
             }));
         }
     });
 }
        /// <summary>
        /// Use this constructor to create instances in your code.
        /// Note: leave the APInitOb null. Aplay sets this object if initialized by aplay.
        ///  if you want to determine in the constructor if the object is user created or by aplay - check IsInitializedByAPlay
        /// </summary>

        public ProjectManager()
        {
            //Todo: Read that shit and think about it.
            //Solange es keine Möglichkeit gibt die Änderungen der AplayList direkt
            //per Extension-Methode in einen SourceCache umzuwandeln findet die Umwandlung hier statt und nicht im VM.
            _projectsRx = new SourceList <Project>();

            _projectsRx.Edit(e =>
            {
                e.AddRange(Projects);
            });

            _cleanup = new CompositeDisposable(_projectsRx);

            //var asl = new APlaySourceList(handler => this.ProjectsAddEventHandler += handler);
        }
        public void UpdateBoards(List <Board> boards)
        {
            _boardsSource.Edit(x =>
            {
                x.Clear();
                if (boards != null)
                {
                    x.AddRange(boards.Select(y => new BoardImportSchemeViewModel
                    {
                        Id = y.Id, Name = y.Name, IsSelected = true, IsEnabled = true
                    }));
                }
            });

            SelectedBoard = _boardsSource.Items.FirstOrDefault();
        }
Exemple #28
0
        public void Upsert(RawQueryHistory item)
        {
            _historySourceList.Edit(list =>
            {
                var lastHistory = list
                                  .OrderByDescending(p => p.LastRunAt)
                                  .FirstOrDefault(p => RawQueryHistory.RawSourceComparer.Equals(item, p));

                if (lastHistory != null)
                {
                    lastHistory.LastRunAt = DateTime.UtcNow;
                }
                else
                {
                    list.Add(item);
                }
            });
        }
        public void SortAfterFilterList()
        {
            var source = new SourceList <Person>();

            var filterSubject = new BehaviorSubject <Func <Person, bool> >(p => true);

            var agg = source.Connect().Filter(filterSubject).Transform(x => new ViewModel(x.Name)).Sort(new ViewModel.Comparer()).AsAggregator();

            source.Edit(
                x =>
            {
                x.Add(new Person("A", 1, "F"));
                x.Add(new Person("a", 1, "M"));
                x.Add(new Person("B", 1, "F"));
                x.Add(new Person("b", 1, "M"));
            });

            filterSubject.OnNext(p => p.Name.Equals("a", StringComparison.OrdinalIgnoreCase));
        }
Exemple #30
0
        public void MultipleSubscribersHandlingErrorsWithOneThrowing()
        {
            var firstSubscriberCallCount             = 0;
            var secondSubscriberCallCount            = 0;
            var firstSubscriberExceptionHandleCount  = 0;
            var secondSubscriberExceptionHandleCount = 0;
            var s = new SourceList <int>();

            s.Connect().Subscribe(i => firstSubscriberCallCount++, e => firstSubscriberExceptionHandleCount++);
            s.Connect().Subscribe(i => { throw new NotImplementedException(); }, ex => {});
            s.Connect().Subscribe(i => secondSubscriberCallCount++, e => secondSubscriberExceptionHandleCount++);

            s.Edit(u => u.Add(1));

            firstSubscriberExceptionHandleCount.Should().Be(1);
            secondSubscriberExceptionHandleCount.Should().Be(1);
            firstSubscriberCallCount.Should().Be(1);
            secondSubscriberCallCount.Should().Be(1);
        }
Exemple #31
0
        public AddinViewModel(ISafeguard safeguard, IExcel excel)
        {
            Safeguard = safeguard;
            Excel     = excel;

            var canAuthenticate = this.WhenNotBusyAnd(
                this.WhenAnyValue(x => x.IsAuthenticated, x => x.NetworkAddress)
                .Select(x => !x.Item1 && !string.IsNullOrEmpty(x.Item2)));
            var authenticate = ReactiveCommand.Create(DoAuthenticate, canAuthenticate);

            AuthenticateCommand = authenticate;

            var canLogout = this.WhenNotBusyAnd(this.WhenAnyValue(x => x.IsAuthenticated));
            var logout    = ReactiveCommand.Create(DoLogout, canLogout);

            LogoutCommand = logout;

            var canExecuteReport = this.WhenNotBusyAnd(this.WhenAnyValue(x => x.SelectedReport).Select(x => x != null));
            var execute          = ReactiveCommand.CreateFromTask(DoExecute, canExecuteReport);

            ExecuteReportCommand = execute;

            _reports.Connect()
            .Bind(Reports)
            .Subscribe();

            safeguard.GetReports().ContinueWith(task =>
            {
                if (task.IsCompleted)
                {
                    _reports.Edit(inner =>
                    {
                        foreach (var report in task.Result)
                        {
                            inner.Add(new Report(report));
                        }
                    });
                }

                SelectedReport = Reports.First();
            });
        }
Exemple #32
0
        public FileTailer(FileInfo file,
                IObservable<FileSearchResult> filter,
                IObservable<ScrollRequest> scrollRequest,
                ILogger logger,
                IScheduler scheduler = null)
        {
            if (file == null) throw new ArgumentNullException(nameof(file));
            if (filter == null) throw new ArgumentNullException(nameof(filter));
            if (logger == null) throw new ArgumentNullException(nameof(logger));

            logger.Info($"Constructing file tailer for {file.FullName}");

            var lines = new SourceList<Line>();
            Lines = lines.AsObservableList();

            var isBusy = new Subject<bool>();
            IsSearching = isBusy.AsObservable();

            var locker = new object();
            scrollRequest = scrollRequest.Synchronize(locker);

            var fileWatcher = file.WatchFile(scheduler: scheduler)
                            .DistinctUntilChanged()
                            .TakeWhile(notification => notification.Exists).Repeat()
                            .Replay(1).RefCount();

            var indexer = fileWatcher.Index().Replay(1).RefCount();

            //compare latest lines and latest filter and only take the filtered results it is not empty
            var latestLines = indexer.Cast<ILineProvider>().Synchronize(locker);
            var latestFilter = filter.Cast<ILineProvider>().Synchronize(locker);
            var latest = latestLines.CombineLatest(latestFilter, (l, f) => f.IsEmpty ? l : f);

            MatchedLines = latest.Select(provider => provider.Count);
            TotalLines = latestLines.Select(x => x.Count);
            FileSize = fileWatcher.Select(notification => notification.Size);
            IsLoading = indexer.Take(1).Select(_ => false).StartWith(true);

            var aggregator = latest.CombineLatest(scrollRequest, (currentLines, scroll) =>
            {
                return currentLines.ReadLines(scroll).ToArray();
            })
            .Subscribe(currentPage =>
            {
                var previous = lines.Items.ToArray();
                var added = currentPage.Except(previous).ToArray();
                var removed = previous.Except(currentPage).ToArray();

                lines.Edit(innerList =>
                {
                    if (removed.Any()) innerList.RemoveMany(removed);
                    if (added.Any()) innerList.AddRange(added);
                });

            });

            //var aggregator = latest.CombineLatest(scrollRequest, (currentLines, scroll) =>
            //{
            //    //TODO: Read entire page, the check which lines should be added and which shold be removed
            //    //as part of that work, get the maximum inded [this is the head!]

            //    //   Debug.WriteLine($"{scroll.Mode}, {scroll.FirstIndex}, {scroll.PageSize}");

            //    var currentPage = currentLines.GetIndicies(scroll).ToArray();

            //    var previous = lines.Items.Select(l => l.LineInfo).ToArray();
            //    var removed = previous.Except(currentPage, LineInfo.LineIndexComparer).ToArray();
            //    var added = currentPage.Except(previous, LineInfo.LineIndexComparer).ToArray();
            //    //calculated added and removed lines
            //    var removedLines = lines.Items.Where(l => removed.Contains(l.LineInfo)).ToArray();

            //    Func<long, DateTime?> isTail = l =>
            //    {
            //        //account for time with tail (i.e. add time to ILineProvider.TailStartsAt )
            //        var tail = currentLines.TailStartsAt;
            //        var onTail = tail != -1 && l >= tail;
            //        return onTail ? DateTime.Now : (DateTime?)null;
            //    };

            //    //Console.WriteLine();
            //    //finally we can load the line from the file todo: Add encdoing back in
            //    var newLines = file.ReadLine(added, (lineIndex, text, position) => new Line(lineIndex, text, isTail(position)), Encoding.UTF8).ToArray();

            //    return new { NewLines = newLines, OldLines = removedLines };
            //})
            //.Where(fn => fn.NewLines.Length + fn.OldLines.Length > 0)
            //.Subscribe(changes =>
            //{
            //    //update observable list
            //    lines.Edit(innerList =>
            //{
            //    if (changes.OldLines.Any()) innerList.RemoveMany(changes.OldLines);
            //    if (changes.NewLines.Any()) innerList.AddRange(changes.NewLines);
            //});
            //});

            _cleanUp = new CompositeDisposable(Lines, lines, aggregator, Disposable.Create(() => isBusy.OnCompleted()));
        }
Exemple #33
0
        public FileTailer(FileInfo file, 
            IObservable<string> textToMatch,
            IObservable<ScrollRequest> scrollRequest,
            IScheduler scheduler=null)
        {
            if (file == null) throw new ArgumentNullException(nameof(file));
            if (textToMatch == null) throw new ArgumentNullException(nameof(textToMatch));

            //create list of lines which contain the observable text
               var matchedLines = textToMatch
                    .Select(searchText =>
                    {
                        Func<string, bool> predicate = null;
                        if (!string.IsNullOrEmpty(searchText))
                            predicate = s => s.Contains(searchText, StringComparison.OrdinalIgnoreCase);

                        return file.WatchFile(scheduler:scheduler ?? Scheduler.Default)
                                    .TakeWhile(notification => notification.Exists)
                                    .Repeat()
                                    .ScanFile(predicate);

                    }).Switch()
                    .Replay(1).RefCount();

            MatchedLines = matchedLines.Select(x => x.MatchingLines.Length);

            TotalLines = matchedLines.Select(x => x.TotalLines);

            //todo: plug in file missing or error into the screen

            var lines = new SourceList<Line>();
            Lines = lines.AsObservableList();

            //this is the beast! Dynamically combine lines requested by the consumer
            //with the lines which exist in the file. This enables proper virtualisation of the file
            var scroller = matchedLines
                .CombineLatest(scrollRequest, (scanResult, request) => new {scanResult , request })
                .Subscribe(x =>
                {
                    var mode = x.request.Mode;
                    var pageSize = x.request.PageSize;
                    var endOfTail = x.scanResult.EndOfTail;
                    var isInitial = x.scanResult.Index==0;
                    var allLines = x.scanResult.MatchingLines;
                    var previousPage = lines.Items.Select(l => new LineIndex(l.Number, l.Index)).ToArray();

                    //Otherwise take the page size and start index from the request
                    var currentPage = (mode == ScrollingMode.Tail
                        ? allLines.Skip(allLines.Length-pageSize).Take(pageSize).ToArray()
                        : allLines.Skip(x.request.FirstIndex).Take(pageSize)).ToArray();

                    var added = currentPage.Except(previousPage).ToArray();
                    var removed = previousPage.Except(currentPage).Select(li=>li.Line).ToArray();

                    if (added.Length + removed.Length == 0) return;

                    try
                    {
                        var addedLines = file.ReadLines(added, (lineIndex, text) =>
                        {
                            var isEndOfTail = !isInitial && lineIndex.Line > endOfTail;
                            return new Line(lineIndex.Line, lineIndex.Index, text, isEndOfTail ? DateTime.Now : (DateTime?)null);
                        }).ToArray();

                        //get old lines from the current collection
                        var removedLines = lines.Items.Where(l => removed.Contains(l.Number)).ToArray();

                        //finally relect changes in the list
                        lines.Edit(innerList =>
                        {
                            innerList.RemoveMany(removedLines);
                            innerList.AddRange(addedLines);
                        });
                    }
                    catch (Exception)
                    {
                        //Very small chance of an error here but if one is causght the next successful read will recify this
                        //TODO: 1. Feedback to user that steaming has stopped
                        //TODO: 2. Place the ReadLines(..) method with the select of an observable
                    }

                });
            _cleanUp = new CompositeDisposable(Lines, scroller, lines);
        }
Exemple #34
0
        public FileTailer(FileInfo file, 
            IObservable<string> textToMatch,
            IObservable<ScrollRequest> scrollRequest,
            IScheduler scheduler=null)
        {
            if (file == null) throw new ArgumentNullException(nameof(file));
            if (textToMatch == null) throw new ArgumentNullException(nameof(textToMatch));

            var lines = new SourceList<Line>();
            Lines = lines.AsObservableList();

            var matcher = textToMatch.Select(searchText =>
            {
                if (string.IsNullOrEmpty(searchText) || searchText.Length < 3)
                    return Observable.Return(LineMatches.None);

                return file.WatchFile(scheduler: scheduler)
                    .TakeWhile(notification => notification.Exists)
                    .Repeat()
                    .Match(s => s.Contains(searchText, StringComparison.OrdinalIgnoreCase));

            }).Switch()
            .Replay(1).RefCount();

            //temp mess for a few days
            var indexer = file.WatchFile(scheduler: scheduler)
                                .TakeWhile(notification => notification.Exists)
                                .Repeat()
                                .Index()
                                .Replay(1).RefCount();

            //count matching lines (all if no filter is specified)
            MatchedLines = indexer.CombineLatest(matcher, (indicies, matches) => matches == LineMatches.None ? indicies.Count : matches.Count);

            //count total line
            TotalLines = indexer.Select(x => x.Count);

            //todo: plug in file missing or error into the screen

            var locker = new object();
            var theBeast = indexer.Synchronize(locker)
                .CombineLatest(matcher.Synchronize(locker), scrollRequest.Synchronize(locker),(idx, mtch, scroll) => new CombinedResult(scroll, mtch, idx))
                .Select(result =>
                {
                    var scroll = result.Scroll;
                    var allLines = result.Incidies;
                    var matched = result.MatchedLines;

                    IEnumerable<LineIndex> indices;
                    if (result.MatchedLines.ChangedReason == LineMatchChangedReason.None)
                    {
                        indices = scroll.Mode == ScrollingMode.Tail
                            ? allLines.GetTail(scroll)
                            : allLines.GetFromIndex(scroll);
                    }
                    else
                    {
                        indices = scroll.Mode == ScrollingMode.Tail
                            ? allLines.GetTail(scroll, matched)
                            : allLines.GetFromIndex(scroll, matched);
                    }

                    return  file.ReadLines(indices, (lineIndex, text) =>
                    {
                        var isEndOfTail = allLines.ChangedReason != LinesChangedReason.Loaded && lineIndex.Line > allLines.TailStartsAt;
                        return new Line(lineIndex.Line, lineIndex.Index, text,isEndOfTail ? DateTime.Now : (DateTime?) null);
                    }).ToArray();
                })
                //.RetryWithBackOff((error, attempts) =>
                //{
                //    //TODO: Log
                //    return TimeSpan.FromSeconds(1);
                //})
                .Subscribe(newPage =>
                {
                    //update observable list
                    lines.Edit(innerList =>
                    {

                        var removed = innerList.Except(newPage).ToArray();
                        var added = newPage.Except(innerList).ToArray();

                        if (removed.Any()) innerList.RemoveMany(removed);
                        if (added.Any())  innerList.AddRange(added);
                    });

                });

            ////this is the beast! Dynamically combine lines requested by the consumer
            ////with the lines which exist in the file. This enables proper virtualisation of the file
            //var scroller = matchedLines
            //    .CombineLatest(scrollRequest, (scanResult, request) => new {scanResult , request })
            //    .Subscribe(x =>
            //    {
            //        var mode = x.request.Mode;
            //        var pageSize = x.request.PageSize;
            //        var endOfTail = x.scanResult.EndOfTail;
            //        var isInitial = x.scanResult.Index==0;
            //        var allLines = x.scanResult.MatchingLines;
            //        var previousPage = lines.Items.Select(l => new LineIndex(l.Number, l.Index, 0, 0)).ToArray();

            //        //Otherwise take the page size and start index from the request
            //        var currentPage = (mode == ScrollingMode.Tail
            //            ? allLines.Skip(allLines.Length-pageSize).Take(pageSize).ToArray()
            //            : allLines.Skip(x.request.FirstIndex).Take(pageSize)).ToArray();

            //        var added = currentPage.Except(previousPage).ToArray();
            //        var removed = previousPage.Except(currentPage).Select(li=>li.Line).ToArray();

            //        if (added.Length + removed.Length == 0) return;

            //        try
            //        {
            //            var addedLines = file.ReadLines(added, (lineIndex, text) =>
            //            {
            //                var isEndOfTail = !isInitial && lineIndex.Line > endOfTail;
            //                return new Line(lineIndex.Line, lineIndex.Index, text, isEndOfTail ? DateTime.Now : (DateTime?)null);
            //            }).ToArray();

            //            //get old lines from the current collection
            //            var removedLines = lines.Items.Where(l => removed.Contains(l.Number)).ToArray();

            //            //finally relect changes in the list
            //            lines.Edit(innerList =>
            //            {
            //                innerList.RemoveMany(removedLines);
            //                innerList.AddRange(addedLines);
            //            });
            //        }
            //        catch (Exception)
            //        {
            //            //Very small chance of an error here but if one is causght the next successful read will recify this
            //            //TODO: 1. Feedback to user that steaming has stopped
            //            //TODO: 2. Place the ReadLines(..) method with the select of an observable
            //        }

            //    });
            _cleanUp = new CompositeDisposable(Lines, lines);
        }
        public FileTailer(FileInfo file, 
            IObservable<string> textToMatch,
            IObservable<ScrollRequest> scrollRequest,
            IScheduler scheduler=null)
        {
            if (file == null) throw new ArgumentNullException(nameof(file));
            if (textToMatch == null) throw new ArgumentNullException(nameof(textToMatch));

            var lines = new SourceList<Line>();
            Lines = lines.AsObservableList();

            var locker = new object();
            scrollRequest = scrollRequest.Synchronize(locker);

            var metronome = Observable
                    .Interval(TimeSpan.FromMilliseconds(250), scheduler ?? Scheduler.Default)
                    .ToUnit()
                    .Replay().RefCount();

            //temp mess for a few days
            var indexer = file.WatchFile(metronome)
                            .TakeWhile(notification => notification.Exists)
                            .Repeat()
                            .Index()
                            .Synchronize(locker)
                            .Replay(1).RefCount();

            var matcher = textToMatch.Select(searchText =>
            {
                if (string.IsNullOrEmpty(searchText) || searchText.Length < 3)
                    return Observable.Return(LineMatches.None);

                return file.WatchFile(metronome)
                    .TakeWhile(notification => notification.Exists)
                    .Repeat()
                    .Match(s => s.Contains(searchText, StringComparison.OrdinalIgnoreCase));

            }).Switch()
            .Synchronize(locker)
            .Replay(1).RefCount();

            //count matching lines (all if no filter is specified)
            MatchedLines = indexer.CombineLatest(matcher, (indicies, matches) => matches == LineMatches.None ? indicies.Count : matches.Count);

            //count total line
            TotalLines = indexer.Select(x => x.Count);

            FileSize = file.WatchFile(metronome).Select(notification => notification.Size);

            var aggregator = indexer.CombineLatest(matcher, scrollRequest,(idx, mtch, scroll) => new CombinedResult(scroll, mtch, idx))
                .Select(result =>
                {
                    var scroll = result.Scroll;
                    var indicies = result.Incidies;
                    var matched = result.MatchedLines;

                    IEnumerable<LineIndex> indices;
                    if (result.MatchedLines.ChangedReason == LineMatchChangedReason.None)
                    {
                        indices = scroll.Mode == ScrollingMode.Tail
                            ? indicies.GetTail(scroll)
                            : indicies.GetFromIndex(scroll);
                    }
                    else
                    {
                        indices = scroll.Mode == ScrollingMode.Tail
                            ? indicies.GetTail(scroll, matched)
                            : indicies.GetFromIndex(scroll, matched);
                    }

                    var currentPage = indices.ToArray();
                    var previous = lines.Items.Select(l => l.LineIndex).ToArray();
                    var removed = previous.Except(currentPage).ToArray();
                    var removedLines = lines.Items.Where(l=> removed.Contains(l.LineIndex)).ToArray();

                    var added = currentPage.Except(previous).ToArray();
                    //finally we can load the line from the file
                    var newLines =  file.ReadLines(added, (lineIndex, text) =>
                    {
                        var isEndOfTail = indicies.ChangedReason != LinesChangedReason.Loaded && lineIndex.Line > indicies.TailStartsAt;

                        return new Line(lineIndex, text, isEndOfTail ? DateTime.Now : (DateTime?) null);
                    }, indicies.Encoding).ToArray();

                    return new { NewLines = newLines, OldLines = removedLines };
                })
                .RetryWithBackOff((Exception error, int attempts) =>
                {
                    //todo: plug in file missing or error into the screen
                    return TimeSpan.FromSeconds(1);
                 })
                 .Where(fn=> fn.NewLines.Length + fn.OldLines.Length > 0)
                .Subscribe(changes =>
                {
                    //update observable list
                    lines.Edit(innerList =>
                    {
                        if (changes.OldLines.Any()) innerList.RemoveMany(changes.OldLines);
                        if (changes.NewLines.Any())  innerList.AddRange(changes.NewLines);
                    });
                });
            _cleanUp = new CompositeDisposable(Lines, lines, aggregator);
        }