Beispiel #1
0
        public CustomTotalRows(IObservableCache <Trade, int> source)
        {
            /*
             *  This technique can be used to create grid data with dynamic running totals
             *
             *  [In production systems I also include the ability to have total row expanders - perhaps an example could follow another time]
             */

            //1. create a trade proxy which enriches the trade with an aggregation id
            var tickers = source.Connect()
                          .ChangeKey(proxy => new AggregationKey(AggregationType.Item, proxy.Id.ToString()))
                          .Transform((trade, key) => new TradeProxy(trade, key));


            //2. create grouping based on each ticker
            var tickerTotals = source.Connect()
                               .GroupWithImmutableState(trade => new AggregationKey(AggregationType.SubTotal, trade.Ticker))
                               .Transform(grouping => new TradeProxy(grouping.Items.ToArray(), grouping.Key));

            //3. create grouping of 1 so we can create grand total row
            var overallTotal = source.Connect()
                               .GroupWithImmutableState(trade => new AggregationKey(AggregationType.GrandTotal, "All"))
                               .Transform(grouping => new TradeProxy(grouping.Items.ToArray(), grouping.Key));

            //4. join all togther so results are in a single cache
            AggregatedData = tickers.Or(overallTotal)
                             .Or(tickerTotals)
                             .AsObservableCache();

            _cleanUp = AggregatedData;
        }
Beispiel #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SharedWindowsViewModel"/> class.
        ///     Initializes a new instance of the <see cref="RemoteViewerViewModel"/> class.
        /// </summary>
        /// <param name="screen">
        /// The screen.
        /// </param>
        /// <param name="remoteHost">
        /// The favorite.
        /// </param>
        /// <param name="shareableWindows">
        /// The shareable Windows.
        /// </param>
        /// <param name="header">
        /// The header.
        /// </param>
        public SharedWindowsViewModel(IScreen screen, RemoteHost remoteHost, IObservableCache<ShareableWindow, IntPtr> shareableWindows, string header)
        {
            this.HostScreen = screen;
            this.RemoteHost = remoteHost;

            this.Header = header;

            // create proxy objects from source cache to have individual instances per RemoteHost
            this.cleanUp = shareableWindows.Connect().Transform(
                window => {
                    // observe IsShared property and update header if necessary
                    var w = new RemoteHostShareableWindow(window);
                    w.WhenPropertyChanged(shareableWindow => shareableWindow.IsShared).Subscribe(
                        shareableWindow => this.RaisePropertyChanged("Header"));

                    w.WhenPropertyChanged(shareableWindow => shareableWindow.IsShared).Subscribe( x => {
                        if (x.Value)
                            RemoteContext.Instance.ShareWindows(
                                remoteHost.Name,
                                this.shareableWindows.Select(sw => new Window() { Id = sw.Handle.ToString(), Name = sw.ProcessName }).ToList());
                    });

                    //w.WhenAnyValue(x => x.IsShared).Where(x => x)
                    //    .Subscribe(x => RemoteContext.Instance.ShareWindows(
                    //        remoteHost.Name, this.shareableWindows.Select(sw => new Window() { Id = sw.Handle.ToString(), Name = sw.ProcessName }).ToList()));

                    return w;
                }).ObserveOnDispatcher().Bind(out this.shareableWindows).Subscribe();

            // Update Header when Number of windows changed, maybe a shared window has been removed
            this.shareableWindows.WhenPropertyChanged(windows => windows.Count).Subscribe(windows => this.RaisePropertyChanged("Header"));
        }
Beispiel #3
0
        public IObservable <IChangeSet <TObject, TKey> > Run()
        {
            return(Observable.Create <IChangeSet <TObject, TKey> >(observer =>
            {
                lock (_locker)
                    if (++_refCount == 1)
                    {
                        _cache = _source.AsObservableCache();
                    }

                var subscriber = _cache.Connect().SubscribeSafe(observer);

                return Disposable.Create(() =>
                {
                    subscriber.Dispose();
                    IDisposable cacheToDispose = null;
                    lock (_locker)
                        if (--_refCount == 0)
                        {
                            cacheToDispose = _cache;
                            _cache = null;
                        }
                    cacheToDispose?.Dispose();
                });
            }));
        }
Beispiel #4
0
        //private ReadOnlyObservableCollection<SHDObject<T>> _items;

        public InteractiveCollectionViewModel(IObservableCache <T, R> observable,
                                              IObservable <Predicate <T> > visiblefilter,
                                              IObservable <Predicate <T> > enabledfilter,
                                              IScheduler scheduler, Func <T, IConvertible> getkey = null, string title = null)
        {
            disposable = observable.Connect()
                         .ObserveOn(scheduler)
                         .Transform(s =>
            {
                var so = new SHDObject <T>(s, visiblefilter, enabledfilter, getkey?.Invoke(s));
                this.ReactToChanges(so);
                return((IContain <T>)so);
            })
                         .Bind(out _items)
                         .DisposeMany()
                         .Subscribe(
                _ =>
            {
                foreach (var x in _.Select(a => new KeyValuePair <IContain <T>, ChangeReason>(a.Current, a.Reason)))
                {
                    (Changes as Subject <KeyValuePair <IContain <T>, ChangeReason> >).OnNext(x);
                }
            },
                ex =>
            {
                (Errors as ISubject <Exception>).OnNext(ex);
                Console.WriteLine("Error in generic view model");
            },
                () => Console.WriteLine("observable completed"));

            Title = title;
        }
Beispiel #5
0
        public IObservable <IChangeSet <TObject, TKey> > Run()
        {
            return(Observable.Create <IChangeSet <TObject, TKey> >(observer =>
            {
                Interlocked.Increment(ref _refCount);
                if (Volatile.Read(ref _refCount) == 1)
                {
                    Interlocked.Exchange(ref _cache, _source.AsObservableCache());
                }

                // ReSharper disable once PossibleNullReferenceException (never the case!)
                var subscriber = _cache.Connect().SubscribeSafe(observer);

                return Disposable.Create(() =>
                {
                    Interlocked.Decrement(ref _refCount);
                    subscriber.Dispose();
                    if (Volatile.Read(ref _refCount) != 0)
                    {
                        return;
                    }
                    _cache.Dispose();
                    Interlocked.Exchange(ref _cache, null);
                });
            }));
        }
        protected override RoleViewModel TransformToViewModel(Role model)
        {
            var vm = base.TransformToViewModel(model);

            var permissionsChanges = _permissionsCache.Connect();
            var rolePermissions    = _domain0.Model.RolePermissions
                                     .Connect()
                                     .ToCollection();

            var combined = Observable.CombineLatest(
                rolePermissions,
                permissionsChanges,
                (rp, _) => rp
                .Where(x => x.RoleId == vm.Id)
                .Select(x => _permissionsCache.Lookup(x.Id.Value).Value)
                );

            combined
            .Subscribe(x =>
            {
                vm.Permissions       = x;
                vm.PermissionsString = string.Join(",", x.Select(p => p.Name));
            })
            .DisposeWith(vm.Disposables);

            return(vm);
        }
Beispiel #7
0
        public SelectCacheItem(ISchedulerProvider schedulerProvider)
        {
            /*
             * Example to show how to select an item after after it has been added to a cache and subsequently transformed.
             *
             * If a filter is applied before the transform this methodology will not work. In that case, alternatives would be
             * to:
             *
             * 1. Add .Do(changes => some custom logic) after the bind statement
             * 2  Add .OnItemAdded(i => SelectedItem = i) after the bind statement
             *
             * In both these options there is no need to split the source cache into a separate transformed cache
             */

            _schedulerProvider = schedulerProvider;

            _transformedCache = _sourceCache.Connect()
                                .Transform(si => new TransformedCacheItem(si))
                                .AsObservableCache();

            var binder = _transformedCache.Connect()
                         .ObserveOn(schedulerProvider.MainThread)
                         .Bind(out var data)
                         .Subscribe();

            Data = data;

            _cleanUp = new CompositeDisposable(binder, _transformedCache, _sourceCache);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="T:System.Object"/> class.
 /// </summary>
 public AnonymousObservableCache(IObservableCache <TObject, TKey> cache)
 {
     if (cache == null)
     {
         throw new ArgumentNullException(nameof(cache));
     }
     _cache = new ObservableCache <TObject, TKey>(cache.Connect());
 }
Beispiel #9
0
 public DeferUntilLoaded(IObservableCache <TObject, TKey> source)
 {
     _result = source.CountChanged.Where(count => count != 0)
               .Take(1)
               .Select(_ => new ChangeSet <TObject, TKey>())
               .Concat(source.Connect())
               .NotEmpty();
 }
Beispiel #10
0
 /// <summary>
 /// Creates a stream using the specified controlled filter.
 /// The controlled filter enables dynamic inline changing of the filter.
 /// </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>
 /// <param name="filterController">The controlled filter.</param>
 /// <returns></returns>
 /// <exception cref="System.ArgumentNullException">filterController</exception>
 public static IObservable <IChangeSet <TObject, TKey> > Connect <TObject, TKey>(this IObservableCache <TObject, TKey> source, FilterController <TObject> filterController)
 {
     if (filterController == null)
     {
         throw new ArgumentNullException(nameof(filterController));
     }
     return(source.Connect().Filter(filterController));
 }
Beispiel #11
0
 public LibraryViewModel(IObservableCache <Modpack, Guid> modpacks)
 {
     modpacks.Connect()
     .ObserveOn(RxApp.MainThreadScheduler)
     .Transform(m => new ModpackViewModel(m))
     .Bind(Modpacks)
     .Subscribe();
     LogTo.Verbose("Library initialized");
 }
Beispiel #12
0
 /// <summary>
 ///     Gets a filtered observable of controllers of the <see cref="T">specified type</see>
 /// </summary>
 /// <typeparam name="T">The controller type.</typeparam>
 /// <param name="devices">The devices collection.</param>
 /// <param name="predicate">The optional predicate to filter controllers.</param>
 /// <returns>An observable of controllers.</returns>
 public static IObservable <T> Controllers <T>(this IObservableCache <Device, string> devices,
                                               Func <T, bool>?predicate = null)
     where T : Controller
 => devices.Connect()
 .Flatten()
 .Where(change => change.Reason == ChangeReason.Add)
 .Select(change => change.Current)
 .Select(HIDDevices.Controllers.Controller.Create <T>)
 .Where(controller => controller != null && (predicate is null || predicate(controller)));
Beispiel #13
0
        /// <summary>
        /// Connects to the cache, and casts the object to the specified type
        /// Alas, I had to add the converter due to type inference issues
        /// </summary>
        /// <typeparam name="TSource">The type of the object.</typeparam>
        /// <typeparam name="TKey">The type of the key.</typeparam>
        /// <typeparam name="TDestination">The type of the destination.</typeparam>
        /// <param name="source">The source.</param>
        /// <param name="converter">The conversion factory.</param>
        /// <returns></returns>
        public static IObservable <IChangeSet <TDestination, TKey> > Cast <TSource, TKey, TDestination>(this IObservableCache <TSource, TKey> source, Func <TSource, TDestination> converter)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return(source.Connect().Cast(converter));
        }
Beispiel #14
0
 public SearchItemGroup(string title, IObservableCache <ISearchItem, ComposedKey> groupCache)
 {
     Title = title;
     groupCache.Connect()
     .Bind(out _items)
     .DisposeMany()
     .ObserveOn(RxApp.MainThreadScheduler)
     .Subscribe();
 }
        public MonitoringGroup(string name, IObservableCache <IMonitoredCall, int> monitoredCalls)
        {
            mNameSubject = new BehaviorSubject <string>(name ?? throw new ArgumentNullException(nameof(name)));
            mCallIds     = new SourceCache <int, int>(id => id);

            WhenNameChanges = mNameSubject.AsObservable();
            Calls           = monitoredCalls.Connect()
                              .InnerJoin(mCallIds.Connect(), id => id, (call, _) => call)
                              .RemoveKey();
        }
Beispiel #16
0
        /// <summary>
        ///     Gets a filtered observable of controllers of the <see cref="T">specified type</see>
        /// </summary>
        /// <typeparam name="T">The controller type.</typeparam>
        /// <param name="devices">The devices collection.</param>
        /// <param name="predicate">The optional predicate to filter controllers.</param>
        /// <returns>An observable of controllers.</returns>
        public static IObservable <T> Controllers <T>(this IObservableCache <Device, string> devices,
                                                      Func <T, bool>?predicate = null)
            where T : Controller
        => devices.Connect()
        .Flatten()
        .Where(change => change.Reason == ChangeReason.Add)
        .Select(change => change.Current)
#pragma warning disable CS8621 // Nullability of reference types in return type doesn't match the target delegate (possibly because of nullability attributes).
        .Select(HIDDevices.Controllers.Controller.Create <T>)
#pragma warning restore CS8621 // Nullability of reference types in return type doesn't match the target delegate (possibly because of nullability attributes).
        .Where(controller => controller != null && (predicate is null || predicate(controller)));
Beispiel #17
0
        public MyYearAndWeekAggregations(IObservableCache <MyCalendarEntry, int> source)
        {
            _cleanUp = source.Connect()
                       .Group(x => x.DateTime.Year)
                       .Transform(group => new AnnualGrouping(group))
                       .DisposeMany()
                       .Bind(out var years)
                       .Subscribe();

            Years = years;
        }
Beispiel #18
0
 public DeferUntilLoaded([NotNull] IObservableCache <TObject, TKey> source)
 {
     if (source == null)
     {
         throw new ArgumentNullException(nameof(source));
     }
     _result = source.CountChanged.Where(count => count != 0)
               .Take(1)
               .Select(_ => new ChangeSet <TObject, TKey>())
               .Concat(source.Connect())
               .NotEmpty();
 }
Beispiel #19
0
        protected override PermissionViewModel TransformToViewModel(Permission model)
        {
            var vm = base.TransformToViewModel(model);

            _applicationsCache
            .Connect()
            .Select(x => _applicationsCache.Lookup(vm.ApplicationId).ValueOrDefault()?.Name)
            .Subscribe(x => vm.Application = x)
            .DisposeWith(vm.Disposables);

            return(vm);
        }
Beispiel #20
0
        protected override MessageTemplateViewModel TransformToViewModel(MessageTemplate model)
        {
            var vm = base.TransformToViewModel(model);

            _environmentsCache
            .Connect()
            .Select(_ => _environmentsCache.Lookup(vm.EnvironmentId).ValueOrDefault()?.Name)
            .Subscribe(x => vm.Environment = x)
            .DisposeWith(vm.Disposables);

            return(vm);
        }
Beispiel #21
0
 public FlattenNestedObservableCollection(IObservableCache <ClassWithNestedObservableCollection, int> source)
 {
     /*
      * Create a flat cache based on a nested observable collection.
      *
      * Since a new changeset is produced each time a parent is added, I recommend applying  Batch()
      * after TransformMany() to reduce notifications (particularly on initial load)
      */
     Children = source.Connect()
                .TransformMany(parent => parent.Children.ToObservableChangeSet(c => c.Name))
                .AsObservableCache();
 }
 /// <summary>
 ///  print changed curPositionPerClientCache
 /// </summary>
 public void PrintcurPositionPerClientCache()
 {
     curPositionPerClientCache.Connect()
     .Subscribe(
         c =>
     {
         foreach (var item in c)
         {
             LogInfo("curPositionPerClientCache:|" + item.Reason.ToString() + " | " + item.Current.ToString());
         }
     }
         );
 }
Beispiel #23
0
        private IDisposable LogChanges()
        {
            //todo: Move this to a log writing service
            const string messageTemplate = "{0} {1} {2} ({4}). Status = {3}";

            return(_all.Connect().SkipInitial()
                   .Transform(trade => string.Format(messageTemplate,
                                                     trade.BuyOrSell,
                                                     trade.Amount,
                                                     trade.CurrencyPair,
                                                     trade.Status,
                                                     trade.Customer))
                   .Subscribe(changes => changes.ForEach(change => _logger.Info(change.Current))));
        }
        private IDisposable LogChanges()
        {
            const string messageTemplate = "{0} {1} {2} ({4}). Status = {3}";

            return(_all.Connect().Skip(1)
                   .WhereReasonsAre(ChangeReason.Add, ChangeReason.Update)
                   .Convert(trade => string.Format(messageTemplate,
                                                   trade.BuyOrSell,
                                                   trade.Amount,
                                                   trade.CurrencyPair,
                                                   trade.Status,
                                                   trade.Customer))
                   .ForEachChange(change => _logger.Info(change.Current))
                   .Subscribe());
        }
 public MailFolderSelectionViewModel(IObservableCache <MailFolder, string> folders)
 {
     folders.Connect()
     .ObserveOn(RxApp.TaskpoolScheduler)
     .Filter(this.WhenAnyValue(x => x.IncludeRoot).Select <bool, Func <MailFolder, bool> >(
                 includeRoot => f => includeRoot || f.Type != FolderType.Root))
     .Sort(SortExpressionComparer <MailFolder> .Ascending(f => f.Type).ThenByAscending(f => f.Name))
     .TransformToTree(f => f.ParentId)
     .Transform(n => new MailFolderSelectionItem(n))
     .DisposeMany()
     .ObserveOn(RxApp.MainThreadScheduler)
     .Bind(out _folders)
     .Subscribe()
     .DisposeWith(_disposables);
 }
 public AutoRefreshForPropertyChanges(IObservableCache <MutableThing, int> dataSource)
 {
     /*
      * The observable cache has no concept of mutable properties. It only knows about adds, updates and removes.
      * However it does have the concept of a refresh, which is a manual way to tell downstream operators like
      * distinct, sort, filter and grouping to re-evaluate
      *
      * To force a refresh, you need to manually trigger when to do so. In this case property changes are monitored
      * and the data source sends a refresh signal to all downstream operators.
      */
     DistinctCount = dataSource.Connect()
                     .AutoRefresh(t => t.Value) //Omit param to refresh for any property
                     .DistinctValues(m => m.Value)
                     .Count();
 }
 public EndpointGroupViewModel(
     EndpointGroup group,
     IObservable <IChangeSet <NodeInputViewModel> > allInputs,
     IObservable <IChangeSet <NodeOutputViewModel> > allOutputs,
     IObservableCache <Node <EndpointGroup, EndpointGroup>, EndpointGroup> children,
     EndpointGroupViewModelFactory endpointGroupViewModelFactory)
 {
     Group          = group;
     VisibleInputs  = allInputs.Filter(e => e.Group == group).AsObservableList();
     VisibleOutputs = allOutputs.Filter(e => e.Group == group).AsObservableList();
     children
     .Connect()
     .Transform(n => endpointGroupViewModelFactory(n.Key, allInputs, allOutputs, n.Children, endpointGroupViewModelFactory))
     .Bind(out _children)
     .Subscribe();
 }
Beispiel #28
0
        public CustomBinding(IObservableCache <Animal, string> source)
        {
            /*
             *   Sometimes the default binding does not behave exactly as you want.
             *   Using VariableThresholdObservableCollectionAdaptor is an example of how you can inject your own behaviour.
             */

            Threshold = 5;

            _cleanUp = source.Connect()
                       .Sort(SortExpressionComparer <Animal> .Ascending(a => a.Name))
                       .Bind(out var data, adaptor: new VariableThresholdObservableCollectionAdaptor <Animal, string>(() => Threshold))
                       .Subscribe();

            Data = data;
        }
        public SearchCollection(ISearchInfoCollection searchInfoCollection, ISchedulerProvider schedulerProvider)
        {
            _viewModels = searchInfoCollection.Searches.Connect()
                          .Transform(tail => new SearchViewModel(tail, vm =>
            {
                searchInfoCollection.Remove(vm.Text);
            }))
                          .DisposeMany()
                          .AsObservableCache();

            var shared = _viewModels.Connect();//.Publish();

            var binderLoader = shared
                               .Sort(SortExpressionComparer <SearchViewModel>
                                     .Ascending(tvm => tvm.SearchType == SearchType.All ? 1:2)
                                     .ThenByAscending(tvm => tvm.Text))
                               .ObserveOn(schedulerProvider.MainThread)
                               .Bind(out _items)
                               .Subscribe();

            var autoSelector = shared.WhereReasonsAre(ChangeReason.Add)
                               .Flatten()
                               .Select(change => change.Current)
                               .Subscribe(latest => Selected = latest);


            var removed = shared.WhereReasonsAre(ChangeReason.Remove)
                          .Subscribe(_ => Selected = _viewModels.Items.First());

            var counter = shared.ToCollection()
                          .Subscribe(count => Count = count.Count);

            SelectedText = this.WhenValueChanged(sc => sc.Selected)
                           .Where(x => x != null)
                           .Select(svm => svm.Text)
                           .Replay(1).RefCount();

            Latest = this.WhenValueChanged(sc => sc.Selected)
                     .Where(x => x != null)
                     .Select(svm => svm.Latest)
                     .Switch()
                     .Replay(1).RefCount();


            _cleanUp = new CompositeDisposable(_viewModels, binderLoader, counter, removed, autoSelector);
        }
Beispiel #30
0
        public SearchCollection(ISearchInfoCollection searchInfoCollection, ISchedulerProvider schedulerProvider)
        {
            _viewModels = searchInfoCollection.Searches.Connect()
                .Transform(tail => new SearchViewModel(tail, vm =>
                {
                    searchInfoCollection.Remove(vm.Text);
                }))
                .DisposeMany()
                .AsObservableCache();

            var shared = _viewModels.Connect();//.Publish();

            var binderLoader = shared
                .Sort(SortExpressionComparer<SearchViewModel>
                               .Ascending(tvm => tvm.SearchType== SearchType.All ? 1:2)
                               .ThenByAscending(tvm => tvm.Text))
                .ObserveOn(schedulerProvider.MainThread)
                .Bind(out _items)
                .Subscribe();

            var autoSelector = shared.WhereReasonsAre(ChangeReason.Add)
                .Flatten()
                .Select(change => change.Current)
                .Subscribe(latest => Selected = latest);

            var removed = shared.WhereReasonsAre(ChangeReason.Remove)
                .Subscribe(_ => Selected = _viewModels.Items.First());

            var counter = shared.ToCollection()
                .Subscribe(count => Count = count.Count);

               SelectedText = this.WhenValueChanged(sc => sc.Selected)
                                .Where(x => x != null)
                                .Select(svm => svm.Text)
                                .Replay(1).RefCount();

               Latest = this.WhenValueChanged(sc => sc.Selected)
                .Where(x=>x!=null)
                .Select(svm => svm.Latest)
                .Switch()
                .Replay(1).RefCount();

            _cleanUp = new CompositeDisposable(_viewModels, binderLoader, counter, removed, autoSelector);
        }
        public IDisposable Switch(bool useGroup)
        {
            SourceList.Clear();
            return(Choose()
                   .Subscribe(a =>
            {
                SourceList.EditDiff(a);
            }));

            IObservable <IEnumerable <object> > Choose()
            {
                return(useGroup == false
                    ? ungrouped
                       .Connect()
                       .ToCollection()
                    : grouped
                       .Connect()
                       .ToCollection());
            }
        }
Beispiel #32
0
        public BaseSummaryService(IObservableCache <Stock, T> stocks, IObservableCache <Stock, TK> fundStocks, IScheduler scheduler)
        {
            if (stocks == null || fundStocks == null)
            {
                throw new NotSupportedException("stocks or fundStocks null parametr not supported");
            }

            var all = stocks.Connect();

            Observable.ObserveOn(all.Count(), scheduler).Subscribe(x => TotalNumber = x);

            Observable.ObserveOn(all.Sum(x => new StockProxy(x).MarketValue), scheduler).Subscribe(x => TotalMarketValue = x);

            Observable.ObserveOn(fundStocks.Connect().Sum(x => new StockProxy(x).MarketValue), scheduler).Subscribe(x =>
            {
                TotalStockWeight = all.Sum(item => new StockProxy(item)
                {
                    TotalMarketValue = x
                }.StockWeight).ToProperty(this, item => item.TotalStockWeight).Value;
            });
        }