/// <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")); }
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(); }); })); }
//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; }
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; }
public Watcher(IObservable <IChangeSet <TObject, TKey> > source, IScheduler scheduler) { _source = source.AsObservableCache(); var onCompletePublisher = _subscribers.Connect() .Synchronize(_locker) .ObserveOn(scheduler) .SubscribeMany((t, k) => Disposable.Create(t.OnCompleted)) .Subscribe(); var sourceSubscriber = source.Synchronize(_locker).Subscribe(updates => updates.ForEach(update => { var subscriber = _subscribers.Lookup(update.Key); if (subscriber.HasValue) { scheduler.Schedule(() => subscriber.Value.OnNext(update)); } })); _disposer = Disposable.Create(() => { onCompletePublisher.Dispose(); sourceSubscriber.Dispose(); _source.Dispose(); _subscribers.Dispose(); }); }
public void Initialise() { _source = new SourceCache <Person, string>(p => p.Name); _controller = new GroupController(); _grouped = _source.Connect(p => _grouper(p) != AgeBracket.Pensioner) .Group(_grouper, _controller).AsObservableCache(); }
public FileDataService( IDirectoryDataService directorySetupService, INotificationCenterService notificationCenterService, ISettingsService settingsService) : base(settingsService, notificationCenterService) { this._directorySetupService = directorySetupService; this._notificationCenterService = notificationCenterService; this._settingsService = settingsService; _getFullFileInfo = this._directorySetupService .Get() .Connect() .LeftJoinMany( this.cache.Connect(), (dirSetup) => dirSetup.DirectorySetupId, (left, right) => right.Items.Select(item => new FileInfoEx(left, item)) ) .TransformMany(x => x, x => x.FileInfo.Id) .TakeUntil(destroy) .AsObservableCache(); _getFullFIleInfoByHash = this._getFullFileInfo .Connect() .Filter(file => FileInfoHashKey.CanBuild(file.FileInfo)) .ChangeKey(file => file.FileInfo.HashKey.Value) .AsObservableCache(); _fileHashCache = this.cache .Connect() .Filter(file => file.FileHash.HasValue && file.IsAccessible) .ChangeKey(file => file.HashKey.Value) .AsObservableCache(); }
public TradeService(ILogger logger, TradeGenerator tradeGenerator, ISchedulerProvider schedulerProvider) { _logger = logger; _tradeGenerator = tradeGenerator; _schedulerProvider = schedulerProvider; //construct a cache specifying that the primary key is Trade.Id _tradesSource = new SourceCache <Trade, long>(trade => trade.Id); //call AsObservableCache() to hide the update methods as we are exposing the cache _all = _tradesSource.AsObservableCache(); //create a derived cache _live = _tradesSource.Connect(trade => trade.Status == TradeStatus.Live).AsObservableCache(); //code to emulate an external trade provider var tradeLoader = GenerateTradesAndMaintainCache(); //expire closed items from the cache ro avoid unbounded data var expirer = _tradesSource .ExpireAfter(t => t.Status == TradeStatus.Closed ? TimeSpan.FromMinutes(1) : (TimeSpan?)null, TimeSpan.FromMinutes(1), schedulerProvider.TaskPool) .Subscribe(x => _logger.Info("{0} filled trades have been removed from memory", x.Count())); //log changes var loggerWriter = LogChanges(); _cleanup = new CompositeDisposable(_all, _tradesSource, tradeLoader, loggerWriter, expirer); }
public GroupControllerForFilteredItemsFixture() { _source = new SourceCache <Person, string>(p => p.Name); _grouped = _source.Connect(p => _grouper(p) != AgeBracket.Pensioner) .Group(_grouper, _refreshSubject).AsObservableCache(); }
public void Initialise() { _source = new SourceCache<Person, string>(p => p.Name); _controller = new GroupController(); _grouped = _source.Connect(p => _grouper(p)!= AgeBracket.Pensioner) .Group(_grouper, _controller).AsObservableCache(); }
public void ConverterCacheEventArgsTests() { IObservableCache cache = InstantiateCache(); IObservableCache newCache = InstantiateCache(); IConverter cDown = new ConvertDown(); IConverter cUp = new ConvertUp(); CacheEventArgs evt = new CacheEventArgs(cache, CacheEventType.Inserted, cDown.Convert("key"), cDown.Convert("valueOld"), cDown.Convert("valueNew"), false); CacheEventArgs convEvt = ConverterCollections.GetCacheEventArgs(newCache, evt, cUp, cUp); Assert.IsNotNull(convEvt); Assert.AreEqual(convEvt.Cache, newCache); Assert.IsFalse(convEvt.Cache.Equals(evt.Cache)); Assert.AreEqual(convEvt.EventType, evt.EventType); Assert.AreEqual(convEvt.IsSynthetic, evt.IsSynthetic); Assert.AreEqual(convEvt.OldValue, cUp.Convert(evt.OldValue)); Assert.AreEqual(convEvt.NewValue, cUp.Convert(evt.NewValue)); Assert.AreEqual(convEvt.Key, cUp.Convert(evt.Key)); Assert.IsInstanceOf(typeof(ConverterCollections.ConverterCacheEventArgs), convEvt); ConverterCollections.ConverterCacheEventArgs ccea = convEvt as ConverterCollections.ConverterCacheEventArgs; Assert.IsNotNull(ccea); Assert.AreEqual(ccea.CacheEvent, evt); Assert.AreEqual(ccea.ConverterKeyUp, cUp); Assert.AreEqual(ccea.ConverterValueUp, cUp); }
public TradeService(ILogger logger,TradeGenerator tradeGenerator, ISchedulerProvider schedulerProvider) { _logger = logger; _tradeGenerator = tradeGenerator; _schedulerProvider = schedulerProvider; //construct a cache specifying that the primary key is Trade.Id _tradesSource = new SourceCache<Trade, long>(trade => trade.Id); //call AsObservableCache() to hide the update methods as we are exposing the cache _all = _tradesSource.AsObservableCache(); //create a derived cache _live = _tradesSource.Connect(trade => trade.Status == TradeStatus.Live).AsObservableCache(); //code to emulate an external trade provider var tradeLoader = GenerateTradesAndMaintainCache(); //expire closed items from the cache ro avoid unbounded data var expirer = _tradesSource .ExpireAfter(t => t.Status == TradeStatus.Closed ? TimeSpan.FromMinutes(1) : (TimeSpan?)null,TimeSpan.FromMinutes(1),schedulerProvider.TaskPool) .Subscribe(x=>_logger.Info("{0} filled trades have been removed from memory",x.Count())); //log changes var loggerWriter = LogChanges(); _cleanup = new CompositeDisposable(_all, _tradesSource, tradeLoader, loggerWriter, expirer); }
public static async Task InitializeAsync() { Watchers = IndexService.MusicFolders.Connect() .TransformAsync(x => FolderWatcher.CreateAsync(x)) .DisposeMany() .AsObservableCache(); }
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); }
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 SourceCache<Line, LineKey>(l=>l.Key); Lines = lines.AsObservableCache(); 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(innerCache => { if (removed.Any()) innerCache.Remove(removed); if (added.Any()) innerCache.AddOrUpdate(added); }); }); _cleanUp = new CompositeDisposable(Lines, lines, aggregator); }
public LineScroller([NotNull] IObservable <ILineProvider> latest, [NotNull] IObservable <ScrollRequest> scrollRequest) { if (latest == null) { throw new ArgumentNullException(nameof(latest)); } if (scrollRequest == null) { throw new ArgumentNullException(nameof(scrollRequest)); } var lines = new SourceCache <Line, LineKey>(l => l.Key); Lines = lines.Connect().IgnoreUpdateWhen((current, previous) => current.Key == previous.Key).AsObservableCache(); var locker = new object(); scrollRequest = scrollRequest.Synchronize(locker); latest = latest.Synchronize(locker); var aggregator = latest .CombineLatest(scrollRequest, (currentLines, scroll) => new { currentLines, scroll }) .Sample(TimeSpan.FromMilliseconds(50)) .Select(x => { if (x.scroll == ScrollRequest.None || x.scroll.PageSize == 0 || x.currentLines.Count == 0) { return(new Line[0]); } return(x.currentLines.ReadLines(x.scroll).ToArray()); }) .RetryWithBackOff <Line[], Exception>((ex, i) => TimeSpan.FromSeconds(1)) .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(innerCache => { if (currentPage.Length == 0) { innerCache.Clear(); } if (removed.Any()) { innerCache.Remove(removed); } if (added.Any()) { innerCache.AddOrUpdate(added); } }); }); _cleanUp = new CompositeDisposable(Lines, lines, aggregator); }
/// <summary> /// Initializes a new instance of the <see cref="T:System.Object"/> class. /// </summary> public AnomynousObservableCache(IObservableCache <TObject, TKey> cache) { if (cache == null) { throw new ArgumentNullException("cache"); } _cache = new ObservableCache <TObject, TKey>(cache.Connect()); }
public AnonymousObservableCache(IObservable <IChangeSet <TObject, TKey> > source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } _cache = new ObservableCache <TObject, TKey>(source); }
public SearchMetadataCollection([NotNull] ILogger logger) { if (logger == null) throw new ArgumentNullException(nameof(logger)); _logger = logger; Metadata = _searches.AsObservableCache(); _cleanUp = new CompositeDisposable(_searches, Metadata); }
public DeferUntilLoaded(IObservableCache <TObject, TKey> source) { _result = source.CountChanged.Where(count => count != 0) .Take(1) .Select(_ => new ChangeSet <TObject, TKey>()) .Concat(source.Connect()) .NotEmpty(); }
public TransformTreeFixture() { _sourceCache = new SourceCache <EmployeeDto, int>(e => e.Id); _result = _sourceCache.Connect() .TransformToTree(e => e.BossId) .AsObservableCache(); }
public CacheSourceGroupSwitcher( ISourceList <object> sourceList, IObservableCache <T, TKey> ungrouped, IObservableCache <GroupViewModel <T, TKey, string>, string> grouped) : base(sourceList) { this.ungrouped = ungrouped; this.grouped = grouped; }
public AnonymousObservableCache(IObservableCache <TObject, TKey> cache) { if (cache == null) { throw new ArgumentNullException(nameof(cache)); } _cache = cache; }
public PolicyUserDTO(PolicyUserMsgs.PolicyUserAdded @event) { PolicyUserId = @event.PolicyUserId; UserId = @event.UserId; PolicyId = @event.PolicyId; RolesCache = _rolesSource.AsObservableCache(); OneRolePerUser = @event.OneRolePerUser; }
public TransformTreeFixture() { _sourceCache = new SourceCache <EmployeeDto, int>(e => e.Id); _filter = new BehaviorSubject <Func <Node <EmployeeDto, int>, bool> >(n => n.IsRoot); _result = _sourceCache.Connect().TransformToTree(e => e.BossId, _filter).AsObservableCache(); }
/// <summary> /// Constructs a new FilterEventArgs. /// </summary> /// <param name="cache"> /// The <see cref="IObservableCache"/> object that fired the /// event. /// </param> /// <param name="type"> /// This event's type. /// </param> /// <param name="key"> /// The key into the cache. /// </param> /// <param name="valueOld"> /// The old value. /// </param> /// <param name="valueNew"> /// The new value. /// </param> /// <param name="isSynthetic"> /// <b>true</b> if the event is caused by the cache internal /// processing such as eviction or loading. /// </param> /// <param name="filters"> /// An array of filters caused this event. /// </param> public FilterEventArgs(IObservableCache cache, CacheEventType type, object key, object valueOld, object valueNew, bool isSynthetic, IFilter[] filters) : base(cache, type, key, valueOld, valueNew, isSynthetic, TransformationState.TRANSFORMABLE, false) { Debug.Assert(filters != null); m_filters = filters; }
public PolicyUserDTO(Guid policyUserId, Guid userId, Guid policyId, bool oneRolePerUser, List <RoleDTO> roles = null) { PolicyUserId = policyUserId; UserId = userId; PolicyId = policyId; OneRolePerUser = oneRolePerUser; RolesCache = _rolesSource.AsObservableCache(); AddRoles(roles); }
/// <summary> /// Add an index to the given dictionary of indexes, keyed by the given /// extractor. Also add the index as a listener to the given cache. /// </summary> /// <param name="extractor"> /// The IValueExtractor object that is used to extract an indexable /// property value from a cache entry. /// </param> /// <param name="ordered"> /// True if the contents of the indexed information should be ordered; /// false otherwise /// </param> /// <param name="comparator"> /// The IComparer object which imposes an ordering on entries in the /// indexed cache or <c>null</c> if the entries' values natural /// ordering should be used. /// </param> /// <param name="cache"> /// The cache that the newly created ICacheIndex will use for /// initialization and listen to for changes. /// </param> /// <param name="dictIndex"> /// The dictionary of indexes that the newly created ICacheIndex will /// be added to. /// </param> public static void AddIndex(IValueExtractor extractor, bool ordered, IComparer comparator, IObservableCache cache, IDictionary dictIndex) { var index = (ICacheIndex)dictIndex[extractor]; if (index == null) { for (int cAttempts = 4; ;) { if (extractor is IIndexAwareExtractor) { index = ((IIndexAwareExtractor)extractor). CreateIndex(ordered, comparator, dictIndex); if (index == null) { return; } } else { index = new SimpleCacheIndex(extractor, ordered, comparator); dictIndex[extractor] = index; } ICacheListener listener = EnsureListener(index); cache.AddCacheListener(listener, null, false); try { // build the index foreach (ICacheEntry entry in cache) { index.Insert(entry); } break; } catch (InvalidOperationException ioe) //collection was modified { cache.RemoveCacheListener(listener); if (--cAttempts == 0) { RemoveIndex(extractor, cache, dictIndex); CacheFactory.Log("Exception occured during index rebuild: " + ioe, CacheFactory.LogLevel.Error); throw; } } } } else if (!(ordered == index.IsOrdered && Equals(comparator, index.Comparer))) { throw new InvalidOperationException("Index for " + extractor + " already exists;" + " remove the index and add it with the new settings"); } }
public SearchInfoCollection(ISearchMetadataCollection metadataCollection) { //var filters = metadataCollection.Metadata // .Connect(m=>m.Filter) // .Transform(meta=>new SearchInfo(meta.SearchText,)) Searches = _searches.AsObservableCache(); _cleanUp = new CompositeDisposable(_searches, Searches); }
public SearchItemGroup(string title, IObservableCache <ISearchItem, ComposedKey> groupCache) { Title = title; groupCache.Connect() .Bind(out _items) .DisposeMany() .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(); }
/// <summary> /// Gets the <typeparamref name="TValue" /> for the specified <paramref name="key" />. /// </summary> /// <typeparam name="TKey">The type of the key.</typeparam> /// <typeparam name="TValue">The type of the value.</typeparam> /// <param name="cache">The cache to use.</param> /// <param name="key">The key to retrieve the <typeparamref name="TValue" /> for.</param> /// <param name="throwIfExpired">If set to <c>true</c>, a <see cref="KeyHasExpiredException{TKey}"/> will be thrown if it has expired before retrieval.</param> /// <param name="scheduler">Scheduler to perform the retrieval on.</param> /// <returns> /// An observable stream that returns the <typeparamref name="TValue"/> for the provided <paramref name="key" />. /// </returns> public static IObservable <TValue> Get <TKey, TValue>(this IObservableCache <TKey, TValue> cache, TKey key, bool throwIfExpired = true, IScheduler scheduler = null) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return(cache.Get(Observable.Return(key), throwIfExpired, scheduler)); }
/// <summary> /// Adds the specified <paramref name="keyValuePair" /> to the <paramref name="cache" />. /// </summary> /// <typeparam name="TKey">The type of the key.</typeparam> /// <typeparam name="TValue">The type of the value.</typeparam> /// <param name="cache">The cache to use.</param> /// <param name="keyValuePair">The key/value pair to add.</param> /// <param name="expiry"> /// The expiry of the <paramref name="keyValuePair" />. If none is provided the /// <paramref name="keyValuePair" /> will virtually never expire. /// </param> /// <param name="expirationType">Defines how the <paramref name="keyValuePair" /> shall expire.</param> /// <param name="scheduler">The scheduler to run the addition on.</param> /// <returns> /// An observable stream that, when done, returns an <see cref="Unit" />. /// </returns> public static IObservable <KeyValuePair <TKey, TValue> > Add <TKey, TValue>(this IObservableCache <TKey, TValue> cache, KeyValuePair <TKey, TValue> keyValuePair, TimeSpan expiry, ObservableCacheExpirationType expirationType = ObservableCacheExpirationType.DoNothing, IScheduler scheduler = null) { if (cache == null) { throw new ArgumentNullException(nameof(cache)); } return(cache.Add(Observable.Return(keyValuePair), expiry, expirationType, scheduler)); }
protected DataServiceBase( ISettingsService settingsService, INotificationCenterService notificationCenter) { _readOnlyCache = cache.AsObservableCache(); this.cache.DisposeWith(disposables); this.settingsService = settingsService; this.notificationCenter = notificationCenter; }
public LibraryViewModel(IObservableCache <Modpack, Guid> modpacks) { modpacks.Connect() .ObserveOn(RxApp.MainThreadScheduler) .Transform(m => new ModpackViewModel(m)) .Bind(Modpacks) .Subscribe(); LogTo.Verbose("Library initialized"); }
/// <summary> /// Removes all keys and values from the <paramref name="cache"/>. /// </summary> /// <param name="cache">The cache to clear.</param> /// <param name="scheduler">Scheduler to perform the clear action on.</param> /// <returns> /// An observable stream that signals when finished clear with an <see cref="Unit" />. /// </returns> public static IObservable <Unit> Clear <TKey, TValue>(this IObservableCache <TKey, TValue> cache, IScheduler scheduler = null) { if (cache == null) { throw new ArgumentNullException(nameof(cache)); } return(cache.Clear(Observable.Return(Unit.Default), scheduler)); }
/// <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)));
public TradeService(ILogger logger,TradeGenerator tradeGenerator, ISchedulerProvider schedulerProvider) { _logger = logger; _tradeGenerator = tradeGenerator; _schedulerProvider = schedulerProvider; //construct a cache specifying that the unique key is Trade.Id _tradesSource = new SourceCache<Trade, long>(trade => trade.Id); //call AsObservableCache() to hide the update methods as we are exposing the cache _tradesCache = _tradesSource.AsObservableCache(); //code to emulate an external trade provider var tradeLoader = GenerateTradesAndMaintainCache(); _cleanup = new CompositeDisposable(_tradesCache, _tradesSource, tradeLoader); }
public LineScroller([NotNull] IObservable<ILineProvider> latest, [NotNull] IObservable<ScrollRequest> scrollRequest) { if (latest == null) throw new ArgumentNullException(nameof(latest)); if (scrollRequest == null) throw new ArgumentNullException(nameof(scrollRequest)); var lines = new SourceCache<Line, LineKey>(l => l.Key); Lines = lines.AsObservableCache(); var locker = new object(); scrollRequest = scrollRequest.Synchronize(locker); latest = latest.Synchronize(locker); var aggregator = latest .CombineLatest(scrollRequest, (currentLines, scroll) => { try { var x = currentLines.ReadLines(scroll).ToArray(); return x; } catch (Exception ex) { throw ex; } }) .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(innerCache => { if (removed.Any()) innerCache.Remove(removed); if (added.Any()) innerCache.AddOrUpdate(added); }); }); _cleanUp = new CompositeDisposable(Lines, lines, aggregator); }
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 TradeService(ILogger logger,TradeGenerator tradeGenerator, ISchedulerProvider schedulerProvider) { _logger = logger; _tradeGenerator = tradeGenerator; _schedulerProvider = schedulerProvider; //construct a cache specifying that the primary key is Trade.Id _tradesSource = new SourceCache<Trade, long>(trade => trade.Id); //call AsObservableCache() to hide the update methods as we are exposing the cache _all = _tradesSource.AsObservableCache(); //create a child cache _live = _tradesSource.Connect(trade => trade.Status == TradeStatus.Live).AsObservableCache(); //code to emulate an external trade provider var tradeLoader = GenerateTradesAndMaintainCache(); //log changes var loggerWriter = LogChanges(); _cleanup = new CompositeDisposable(_all, _tradesSource, tradeLoader, loggerWriter); }
public SearchMetadataCollection() { Metadata = _searches.AsObservableCache(); _cleanUp = new CompositeDisposable(_searches, Metadata); }
public PersonWithEmployment(IGroup<PersonEmployment, PersonEmpKey, string> source) { _source = source; _empData = source.Cache; }
public WindowsController(ILogger logger) { _logger = logger; Views = _views.AsObservableCache(); }