public MessageHeader(int uid, Folder f) { if (uid < 0) { throw new System.ArgumentException("Invalid UID Value", "uid"); } folder_ = f; Uid = uid; id = uid; // Set this as a default, but the server might update it. flags_ = new BehaviorSubject <MessageFlags>(MessageFlags.None); UnRead = flags_.Select((flags) => flags.HasFlag(MessageFlags.Seen) == false); Deleted = flags_.Select((flags) => flags.HasFlag(MessageFlags.Deleted)); Flagged = flags_.Select((flags) => flags.HasFlag(MessageFlags.Flagged)); UnRead.Subscribe(val => IsUnRead = val); Deleted.Subscribe(val => IsDeleted = val); attachments_ = new List <BodyPart>(); related_ = new List <BodyPart>(); To = new MailAddressCollection(); Cc = new MailAddressCollection(); // Build the BodyPart required to pull the whole message. FullMessage = new BodyPart(this, "text/plain"); FullMessage.PartNumber = ""; }
public Submission() { children = new BehaviorSubject <IEnumerable <Submission> >(Enumerable.Empty <Submission>()); answer = new BehaviorSubject <string>(""); manualGrade = new BehaviorSubject <float?>(null); childGrade = children.Select(xs => xs.Select(x => x.grade).CombineLatestSafe()).Merge().Select(x => x.Flatten().AverageSafe()); childPass = children.Select(xs => xs.Select(x => x.pass).CombineLatestSafe()).Merge().Select(xs => xs.Conjunction()); grade = manualGrade.CombineLatest(childGrade, childPass, (manualGrade1, childGrade1, childPass1) => { if (manualGrade1.HasValue) { return(manualGrade1); } else { if (childPass1) { return(childGrade1); } else { return(null); } } }); pass = grade.Select(g => g.HasValue ? g >= 5.5f : false); }
public BuildArgs(IEnumerable <string> initialArgs) { var buildArgs = GetDefines(initialArgs).Select(d => "-D" + d) .Concat(GetVerbose(initialArgs) ? Optional.Some("-v") : Optional.None()); All = new BehaviorSubject <ImmutableList <string> >(buildArgs.ToImmutableList()); Defines = All.Select(GetDefines).DistinctUntilSequenceChanged().Replay(1).RefCount(); Verbose = All.Select(GetVerbose).DistinctUntilChanged().Replay(1).RefCount(); }
public void RxComposition() { var input = new BehaviorSubject <int>(0); var timesTwo = input.Select(value => value * 2); var timesThree = input.Select(value => value * 3); var sumOfBoth = timesTwo.CombineLatest(timesThree, (first, second) => first + second); sumOfBoth.Subscribe(value => Console.WriteLine("sumOfBoth = " + value)); //Prints 'sumOfBoth = 0' input.OnNext(1); //Prints 'sumOfBoth = 2' and 'sumOfBoth = 5' input.OnNext(2); //Prints 'sumOfBoth = 7' and 'sumOfBoth = 10' }
public RatingViewModel( ITimeService timeService, ITogglDataSource dataSource, IRatingService ratingService, IAnalyticsService analyticsService, IOnboardingStorage onboardingStorage, IMvxNavigationService navigationService, ISchedulerProvider schedulerProvider, IRxActionFactory rxActionFactory) { Ensure.Argument.IsNotNull(dataSource, nameof(dataSource)); Ensure.Argument.IsNotNull(timeService, nameof(timeService)); Ensure.Argument.IsNotNull(ratingService, nameof(ratingService)); Ensure.Argument.IsNotNull(analyticsService, nameof(analyticsService)); Ensure.Argument.IsNotNull(onboardingStorage, nameof(onboardingStorage)); Ensure.Argument.IsNotNull(navigationService, nameof(navigationService)); Ensure.Argument.IsNotNull(schedulerProvider, nameof(schedulerProvider)); Ensure.Argument.IsNotNull(rxActionFactory, nameof(rxActionFactory)); this.dataSource = dataSource; this.timeService = timeService; this.ratingService = ratingService; this.analyticsService = analyticsService; this.onboardingStorage = onboardingStorage; this.navigationService = navigationService; this.schedulerProvider = schedulerProvider; this.rxActionFactory = rxActionFactory; Impression = impressionSubject.AsDriver(this.schedulerProvider); CallToActionTitle = impressionSubject .Select(callToActionTitle) .AsDriver(this.schedulerProvider); CallToActionDescription = impressionSubject .Select(callToActionDescription) .AsDriver(this.schedulerProvider); CallToActionButtonTitle = impressionSubject .Select(callToActionButtonTitle) .AsDriver(this.schedulerProvider); IsFeedbackSuccessViewShowing = isFeedbackSuccessViewShowing.AsDriver(this.schedulerProvider); HideRatingView = hideRatingView.AsDriver(this.schedulerProvider); PerformMainAction = rxActionFactory.FromAsync(performMainAction); }
private IDisposable ShouldPopulateNamesWithFilteredNames() { return(_allNames .Select(allNames => _filter.Select(filter => ApplyFilter(filter, allNames))) .Switch() .Subscribe(_names)); }
public IObservable <IData> Run(IData initialData) { return(Observable.Create <IData>( observer => { var state = _factory.FromData(initialData); var states = new BehaviorSubject <IState>(state); // First create a stream of changes by ... IConnectableObservable <IChange> changes = states // ... enter the current state ... .Select(state => state.Enter()) // ... subscribing to the change observable ... .Switch() // ... and ensure only a single shared subscription is made to the change observable ... .Publish(); IObservable <IData> data = changes.OfType <IData>(); // Then, for each transition type, select the new state... IObservable <IState> transitions = changes .OfType <ITransition>() .Select(_ => _factory.FromData(initialData)) .ObserveOn(Scheduler.CurrentThread); return new CompositeDisposable( transitions.Subscribe(states), data.Subscribe(observer), changes.Connect(), states ); } )); }
private ShellViewModel() { FilePath = new BehaviorSubject <string>(@"Test.mrpd"); this.WhenActivated(d => { TestCommand = ReactiveCommand.Create(() => { TestName = "Test"; }); (LoadFileCommand = ReactiveCommand.Create(LoadFile)).DisposeWith(d); (UpCommand = ReactiveCommand.Create(Up, this.WhenAnyValue(s => s.SelectedNodeIndex).Select(i => i > 0))).DisposeWith(d); (CreateNodeCommand = ReactiveCommand.Create(CreateNode)).DisposeWith(d); (_deleteNodeCommand = ReactiveCommand.Create <string>(DeleteNode)).DisposeWith(d); (_enterNodeCommand = ReactiveCommand.Create <string>(EnterNode)).DisposeWith(d); (_startRenameNodeCommand = ReactiveCommand.Create <string>(StartRenameNode)).DisposeWith(d); (_endRenameNodeCommand = ReactiveCommand.Create <(string, string)>(EndRenameNode)).DisposeWith(d); (_deleteDataCommand = ReactiveCommand.Create <string>(DeleteData)).DisposeWith(d); NodeNameList.Connect().ObserveOnDispatcher(DispatcherPriority.Background).Bind(out _nodeNames).Subscribe().DisposeWith(d); NodeItemViewModelCache.Connect().Sort(SortExpressionComparer <ItemViewModelBase> .Ascending(i => i.Name)).Concat(DataItemViewModelCache.Connect().Sort(SortExpressionComparer <ItemViewModelBase> .Ascending(i => i.Name))).Bind(out _itemViewModels).Subscribe().DisposeWith(d); this.WhenAnyValue(s => s.SelectedNodeIndex).Skip(1).Subscribe(SelectedNodeIndexChanged).DisposeWith(d); FilePath.Subscribe(FilePathChanged).DisposeWith(d); FilePath.Select(f => f != null).ToProperty(this, s => s.HasFile, out _hasFile).DisposeWith(d); (SaveCommand = ReactiveCommand.Create(async() => { await this.ShowProgressAsync("", "正在保存..."); })).DisposeWith(d); }); }
/// <summary> /// Map a Behaviour of one type to a Behaviour of another using a function. /// </summary> public Behaviour <B> Select <B>(Func <A, B> selector) { var r = new Behaviour <B>(selector(Value)); Subject.Select(selector).Subscribe(r.Subject); return(r); }
private async Task Connect(IScheduler _, CancellationToken ct) { try { using (_client = new ClientWebSocket()) using (_state.Select(Update).Switch().Subscribe(__ => { }, e => Dispose())) { await _client.ConnectAsync(_owner._endpoint, ct); // We must be connected **before** ReceiveAsync var buffer = WebSocket.CreateClientBuffer(8192, 4096); while (!ct.IsCancellationRequested && _client.State == WebSocketState.Open) { var message = await _client.ReceiveAsync(buffer, ct); if (!message.EndOfMessage) { throw new InternalBufferOverflowException(); // TODO } switch (message.MessageType) { case WebSocketMessageType.Close: return; case WebSocketMessageType.Binary: this.Log().Error("Received unknown binary message."); break; case WebSocketMessageType.Text: OnMessageReceived(buffer); break; } } } } catch (Exception e) { this.Log().Error("Connection failed", e); } finally { Dispose(); } IObservable <Unit> Update(State state) => Observable.FromAsync(async ct2 => { switch (state) { case State.Authenticating: await _client.SendAsync(new ArraySegment <byte>(JsonSerializer.SerializeToUtf8Bytes(new AuthRequest(_owner._authToken), JsonWriteOpts)), WebSocketMessageType.Text, true, ct2); break; case State.Disconnected: Dispose(); break; } }); }
public Scenario1() { this.InitializeComponent(); enableCommand = new ReactiveCommand(isEnabled); disableCommand = new ReactiveCommand(isEnabled.Select(b => !b)); simulateData = new ReactiveCommand(isEnabled); }
[SerializeField] private Explosion _deathExplosion; // Explosion that will be created after unit death. #endregion private void Awake() { _health = new BehaviorSubject <float>(_startingHealth); _health.DoOnCompleted(OnDeath); _health.Subscribe(_ => { }, OnDeath); HealthPercentageStream = _health.Select(currentHealth => currentHealth / _startingHealth); }
public MainForm() { InitializeComponent(); //var source = Observable.Create<int>((observer) => { // observer.OnNext(1); // observer.OnNext(2); // observer.OnNext(3); // observer.OnCompleted(); // return Disposable.Create(() => Console.WriteLine($"Observer has unsubscribed")); //}).SelectMany(it => ////var source = Observable.Range(1, 5).SelectMany(it => //{ // return new List<string> // { // $"#{it}", // $"#{it + 10}" // }; //}); //var trigger = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1)); //var triggeredSource = source.Zip(trigger, (s, _) => s); //triggeredSource.Finally(() => //{ // Console.WriteLine("Finally does not work in here"); //}); //triggeredSource.Finally(() => //{ // Console.WriteLine("Finally"); //}).Timestamp().Subscribe(timer => //{ // Console.WriteLine($"Timer:{timer.Timestamp} {timer.Value}"); //}, //ex => //{ // Console.WriteLine($"Error {ex}"); //}, //() => //{ // Console.WriteLine($"Complete"); //}); tableLayoutPanel1.Visible = false; _app.OnStopVisualization.Subscribe(_ => { startButton.Text = "&Start"; randomButton.Enabled = true; checkedListBox1.Enabled = true; }); checkedListBox1.SetItemChecked(0, true); delayNumericUpDown.Value = App.DefaultStepDelay; _stepTrigger.Select(t => Observable.Interval(TimeSpan.FromMilliseconds(t))). Switch().Subscribe(_ => { Debug.WriteLine("tick-tack "); _visualizationTick.OnNext(Unit.Default); }); //_visualizationTick = Observable.Timer( // TimeSpan.Zero, // TimeSpan.FromMilliseconds(StepDelay)); }
public RowModel(TreeViewModel tree) { _tree = tree; var elUxClass = ElementSwitch(el => el.UxClass()); _iconName = ElementSwitch(el => el.Name, ""); _isSelected = new BehaviorSubject <bool>(false); _isAncestorSelected = new BehaviorSubject <bool>(false); _expandToggleEnabled = new BehaviorSubject <bool>(false); _isExpanded = new BehaviorSubject <bool>(false); _selectCommand = Command.Create( ElementSelect(el => Optional.Some((Action)(() => _tree._context.Select(el))), Optional.None <Action>())); _headerText = ElementSwitch( el => el.Name.CombineLatest( el.UxGlobal(), el.UxProperty(), elUxClass, el.UxInnerClass(), (name, uxGlobal, uxProperty, uxClass, uxInnerClass) => uxGlobal.Or(uxProperty).Or(uxClass) .Or(uxInnerClass) .Select(uxAttrName => uxAttrName + " (" + name + ")").Or(name)), string.Empty); _scopeIntoClassCommand = Command.Create( ElementSwitch( el => elUxClass .CombineLatest(_depth, (uxClass, depth) => uxClass.Where(_ => depth > 0) /* disallow scope into for root */) .SelectPerElement(_ => (Action)(() => _tree._context.PushScope(el, el))))); _expandToggleCommand = Command.Create( ElementSwitch( el => _expandToggleEnabled.Select( canExpand => canExpand ? Optional.Some( (Action)(() => { if (_isDescendantSelected) { _tree._context.Select(el); } _tree.SetElementExpanded(el, !_isExpanded.Value); })) : Optional.None()), Optional.None <Action>())); _isFaded = _tree.HighlightSelectedElement.CombineLatest( _isSelected, _isAncestorSelected, (highlightSelectedElement, isSelected, isAncestorSelected) => highlightSelectedElement && !(isSelected | isAncestorSelected)); }
public MouthCellViewModel CreateAndSetUpMouthCellViewModel(int mouthIndex) { MouthCellModel model = stickerCustomizationPopupModel.GetDataWithIndex(mouthIndex); MouthCellViewModel mouthCellViewModel = new MouthCellViewModel(model, cachedResourcesLoader); mouthCellViewModel.SelectionIntent.Subscribe(_ => selectedMouthModel.OnNext(model)); selectedMouthModel.Select(x => x.Id == mouthIndex).Subscribe(mouthCellViewModel.MouthActiveObserver); return(mouthCellViewModel); }
public void RxSquare() { var inputs = new BehaviorSubject <int>(1); var inputSquared = inputs.Select(input => input * input); inputSquared.Subscribe(square => Console.WriteLine("square = " + square)); // Prints 'square = 1' inputs.OnNext(2); // Prints 'square = 4' inputs.OnNext(3); // Prints 'square = 9' }
public void Init() { Name = CreateNameProperty(Element.Name.LocalName); SourceReference = _textPosition .Select(Optional.Some) .DistinctUntilChanged() .Replay(1).RefCount(); Base = _metadata.Select(m => _getElement(m[_elementId.Value].FirstOr(ObjectIdentifier.None))).Switch(); }
public AttributeIntercepter(IEditorFactory editorFactory) { _editorFactory = editorFactory; AllReadOnly = _attributes .Select(attributes => attributes .Select(a => a.IsReadOnly) .Aggregate(Observable.Return(true), ObservableBooleanExtensions.And)) .Switch() .Replay(1).RefCount(); AnyHasValue = _attributes .Select(attributes => attributes .Select(a => a.HasValue) .Aggregate(Observable.Return(false), ObservableBooleanExtensions.Or)) .Switch() .Replay(1).RefCount(); }
public RatingViewModel( ITimeService timeService, ITogglDataSource dataSource, IRatingService ratingService, IAnalyticsService analyticsService, IOnboardingStorage onboardingStorage, IMvxNavigationService navigationService, ISchedulerProvider schedulerProvider) { Ensure.Argument.IsNotNull(dataSource, nameof(dataSource)); Ensure.Argument.IsNotNull(timeService, nameof(timeService)); Ensure.Argument.IsNotNull(ratingService, nameof(ratingService)); Ensure.Argument.IsNotNull(analyticsService, nameof(analyticsService)); Ensure.Argument.IsNotNull(onboardingStorage, nameof(onboardingStorage)); Ensure.Argument.IsNotNull(navigationService, nameof(navigationService)); Ensure.Argument.IsNotNull(schedulerProvider, nameof(schedulerProvider)); this.dataSource = dataSource; this.timeService = timeService; this.ratingService = ratingService; this.analyticsService = analyticsService; this.onboardingStorage = onboardingStorage; this.navigationService = navigationService; this.schedulerProvider = schedulerProvider; Impression = impressionSubject.AsDriver(this.schedulerProvider); CtaTitle = impressionSubject .Select(ctaTitle) .AsDriver(this.schedulerProvider); CtaDescription = impressionSubject .Select(ctaDescription) .AsDriver(this.schedulerProvider); CtaButtonTitle = impressionSubject .Select(ctaButtonTitle) .AsDriver(this.schedulerProvider); IsFeedbackSuccessViewShowing = isFeedbackSuccessViewShowing.AsDriver(this.schedulerProvider); }
public LogView(IObservable <string> mainLogStream, IObservable <IBinaryMessage> deviceMessages, ErrorView errorView) { var showLog = UserSettings.Bool("ShowLog").OrTrue(); IsExpanded = showLog; var logChanged = new Subject <Unit>(); var logTab = new LogViewTab("Log", CreateLogView(mainLogStream, deviceMessages, logChanged), logChanged.Select(_ => true)); var problemsTab = new LogViewTab("Problems", errorView.Create(), errorView.NotifyUser); var activeTab = new BehaviorSubject <LogViewTab>(logTab); TabHeader = LogViewHeader.CreateHeader(new[] { logTab, problemsTab }, activeTab, showLog); TabContent = activeTab .Select(tab => tab.Content) .Switch(); }
public static void Initialize(Dispatcher dispatcher) { var editingColorSubject = new BehaviorSubject <Optional <IProperty <Color> > >(Optional.None <IProperty <Color> >()); var editingColor = editingColorSubject .ReplaceNone(() => Property.AsProperty(Observable.Never <Color>())) .Switch() .PreventFeedback() .AutoInvalidate(TimeSpan.FromMilliseconds(200)); Fusion.Application.Desktop.CreateSingletonWindow( isVisible: editingColorSubject.Select(e => e.HasValue), window: window => new Window { Title = Observable.Return("Color"), Closed = editingColorSubject.Update(Optional.None <IProperty <Color> >()), Size = Optional.Some(Property.Constant(Optional.Some(new Size <Points>(560, 300)))), Background = Color.FromRgb(0xFCFCFC), Foreground = Color.FromRgb(0x676767), Border = Stroke.Create(1, Color.FromRgb(0xe0e0e0)), Content = Control .Create(self => { var dialog = new ColorPickerFullWithAlpha(); dialog.UserChangedColor .Select(_ => dialog.SelectedColor.ToFusion()) .Subscribe(editingColor); self.BindNativeProperty(dispatcher, "color", editingColor, c => dialog.SelectedColor = c.ToColor()); self.BindNativeDefaults(dialog, dispatcher); return(dialog); }) .WithPadding(new Thickness <Points>(10)) .WithBackground(Color.FromRgb(0xFCFCFC)), }); ColorPicker.Implementation.OpenCommand = (color) => editingColorSubject.Update( old => old == Optional.Some(color) ? Optional.None <IProperty <Color> >() : Optional.Some(color)); }
public void Test2() { IObservable <int> CreateRecursive() { var source = new BehaviorSubject <int>(0); var transfer = source.Select(x => ++ x); return(Observable.Create <int>(observer => new CompositeDisposable { source.Subscribe(observer), transfer.Subscribe(source) })); } var res = CreateRecursive().Take(5).ToEnumerable(); CollectionAssert.AreEqual(new [] { 0, 1, 2, 3, 4 }, res); //Stack overflow }
public static IObservable <T> RetryWhen <T, U>(this IObservable <T> source, Func <IObservable <Exception>, IObservable <U> > handler) { return(Observable.Defer(() => { var errorSignal = new Subject <Exception>(); var retrySignal = handler(errorSignal); var sources = new BehaviorSubject <IObservable <T> >(source); return Observable.Using( () => retrySignal.Select(s => source).Subscribe(sources), r => sources .Select(src => src.Do(v => { }, e => errorSignal.OnNext(e), () => errorSignal.OnCompleted()) .OnErrorResumeNext(Observable.Empty <T>()) ) .Concat() ); })); }
public StageController( ViewportFactory viewportFactory, PreviewDevices previewDevices, IProperty <bool> selectionEnabled) { _viewportFactory = viewportFactory; _previewDevices = previewDevices; _selectionEnabled = selectionEnabled; var fallbackDevice = previewDevices.DefaultDevice .Select(dev => new VirtualDevice(dev, dev.DefaultOrientation)) .AsProperty(); var device = _focusedViewport .Select(mv => mv.Select(v => v.VirtualDevice.AsProperty()).Or(fallbackDevice)) .Switch(); _latestDevice = device; }
public BalloonNotifier(NotifyIcon icon, System.Windows.Threading.Dispatcher scheduler) { _icon = icon; var clicked = DataBinding.ObservableFromNativeEvent <EventArgs>(_icon, "BalloonTipClicked"); var closed = DataBinding.ObservableFromNativeEvent <EventArgs>(_icon, "BalloonTipClosed"); var current = _notifications.Select(n => n.LastOrNone()).NotNone(); _subscriptions = new[] { current .ObserveOn(scheduler) .Subscribe(n => { var timeout = n.Notification.Timeout.Or(TimeSpan.FromHours(3)); _icon.ShowBalloonTip( (int)timeout.TotalMilliseconds, n.Notification.Title, n.Notification.Description, n.Notification.Type == NotifyType.Error ? ToolTipIcon.Error : n.Notification.Type == NotifyType.Info ? ToolTipIcon.Info : ToolTipIcon.None); }), clicked.WithLatestFromBuffered(current, (_, c) => c) .ObserveOn(TaskPoolScheduler.Default) .Subscribe(c => { _notifications.OnNext(_notifications.Value.Remove(c)); c.TaskCompletionSource.TrySetResult(NotificationFeedback.PrimaryActionTaken); }), closed.WithLatestFromBuffered(current, (_, c) => c) .ObserveOn(TaskPoolScheduler.Default) .Subscribe(c => { _notifications.OnNext(_notifications.Value.Remove(c)); c.TaskCompletionSource.TrySetResult(NotificationFeedback.Dismissed); }), }; }
public void Test3() { IObservable <int> CreateRecursive(int count) { var source = new BehaviorSubject <int>(0); var transfer = source.Select(x => ++ x); var guard = source.Skip(count).Subscribe(_ => source.OnCompleted()); return(Observable.Create <int>(observer => new CompositeDisposable { source.Subscribe(observer), transfer.Subscribe(source), guard })); } var res = CreateRecursive(5).ToEnumerable(); CollectionAssert.AreEqual(new [] { 0, 1, 2, 3, 4 }, res); }
public void Test1() { IObservable <int> CreateRecursive() { var one = new BehaviorSubject <int>(0); var other = new Subject <int>(); return(Observable.Create <int>(observer => new CompositeDisposable { one.Subscribe(observer), other.Subscribe(one), one.Select(x => ++ x).Subscribe(other), other, one } )); }; var res = CreateRecursive().Take(5).ToEnumerable(); CollectionAssert.AreEqual(new [] { 0, 1, 2, 3, 4 }, res); //Stack overflow }
public MainViewModel() { var anyExecuting = new BehaviorSubject <bool>(false); var noneExecuting = anyExecuting .Select(ae => !ae); this.command1 = ReactiveCommand.CreateFromObservable( () => this.Execute(), noneExecuting); this.command2 = ReactiveCommand.CreateFromObservable( () => this.Execute(), noneExecuting); this.command3 = ReactiveCommand.CreateFromObservable( () => this.Execute(), noneExecuting); Observable .Merge( this.command1.IsExecuting, this.command2.IsExecuting, this.command3.IsExecuting) .Subscribe(anyExecuting); }
IObservable <T> ElementSelect <T>(Func <ILiveElement, T> selector, T defaultValue) { return(_element.Select(el => el.Select(selector).Or(defaultValue))); }
public EditTimeEntryViewModel( ITimeService timeService, ITogglDataSource dataSource, ISyncManager syncManager, IInteractorFactory interactorFactory, IMvxNavigationService navigationService, IOnboardingStorage onboardingStorage, IDialogService dialogService, IAnalyticsService analyticsService, IStopwatchProvider stopwatchProvider, IRxActionFactory actionFactory, ISchedulerProvider schedulerProvider) { Ensure.Argument.IsNotNull(dataSource, nameof(dataSource)); Ensure.Argument.IsNotNull(syncManager, nameof(syncManager)); Ensure.Argument.IsNotNull(timeService, nameof(timeService)); Ensure.Argument.IsNotNull(dialogService, nameof(dialogService)); Ensure.Argument.IsNotNull(interactorFactory, nameof(interactorFactory)); Ensure.Argument.IsNotNull(onboardingStorage, nameof(onboardingStorage)); Ensure.Argument.IsNotNull(navigationService, nameof(navigationService)); Ensure.Argument.IsNotNull(analyticsService, nameof(analyticsService)); Ensure.Argument.IsNotNull(stopwatchProvider, nameof(stopwatchProvider)); Ensure.Argument.IsNotNull(schedulerProvider, nameof(schedulerProvider)); Ensure.Argument.IsNotNull(actionFactory, nameof(actionFactory)); this.dataSource = dataSource; this.syncManager = syncManager; this.timeService = timeService; this.dialogService = dialogService; this.interactorFactory = interactorFactory; this.navigationService = navigationService; this.analyticsService = analyticsService; this.stopwatchProvider = stopwatchProvider; this.schedulerProvider = schedulerProvider; this.actionFactory = actionFactory; OnboardingStorage = onboardingStorage; workspaceIdSubject .Where(id => id.HasValue) .Subscribe(id => workspaceId = id.Value) .DisposedBy(disposeBag); isEditingDescriptionSubject = new BehaviorSubject <bool>(false); Description = new BehaviorRelay <string>(string.Empty, CommonFunctions.Trim); projectClientTaskSubject = new BehaviorSubject <ProjectClientTaskInfo>(ProjectClientTaskInfo.Empty); ProjectClientTask = projectClientTaskSubject .AsDriver(ProjectClientTaskInfo.Empty, schedulerProvider); IsBillableAvailable = workspaceIdSubject .Where(id => id.HasValue) .SelectMany(workspaceId => interactorFactory.IsBillableAvailableForWorkspace(workspaceId.Value).Execute()) .DistinctUntilChanged() .AsDriver(false, schedulerProvider); isBillableSubject = new BehaviorSubject <bool>(false); IsBillable = isBillableSubject .DistinctUntilChanged() .AsDriver(false, schedulerProvider); startTimeSubject = new BehaviorSubject <DateTimeOffset>(DateTimeOffset.UtcNow); var startTimeObservable = startTimeSubject.DistinctUntilChanged(); StartTime = startTimeObservable .AsDriver(default(DateTimeOffset), schedulerProvider); var now = timeService.CurrentDateTimeObservable.StartWith(timeService.CurrentDateTime); durationSubject = new ReplaySubject <TimeSpan?>(bufferSize: 1); Duration = durationSubject .Select(duration => duration.HasValue ? Observable.Return(duration.Value) : now.CombineLatest( startTimeObservable, (currentTime, startTime) => currentTime - startTime)) .Switch() .DistinctUntilChanged() .AsDriver(TimeSpan.Zero, schedulerProvider); var stopTimeObservable = Observable.CombineLatest(startTimeObservable, durationSubject, calculateStopTime) .DistinctUntilChanged(); StopTime = stopTimeObservable .AsDriver(null, schedulerProvider); var isTimeEntryRunningObservable = stopTimeObservable .Select(stopTime => !stopTime.HasValue) .Do(value => isRunning = value) .DistinctUntilChanged(); IsTimeEntryRunning = isTimeEntryRunningObservable .AsDriver(false, schedulerProvider); tagsSubject = new BehaviorSubject <IEnumerable <IThreadSafeTag> >(Enumerable.Empty <IThreadSafeTag>()); Tags = tagsSubject .Select(tags => tags.Select(ellipsize).ToImmutableList()) .AsDriver(ImmutableList <string> .Empty, schedulerProvider); isInaccessibleSubject = new BehaviorSubject <bool>(false); IsInaccessible = isInaccessibleSubject .DistinctUntilChanged() .AsDriver(false, schedulerProvider); syncErrorMessageSubject = new BehaviorSubject <string>(string.Empty); SyncErrorMessage = syncErrorMessageSubject .Select(error => error ?? string.Empty) .DistinctUntilChanged() .AsDriver(string.Empty, schedulerProvider); IsSyncErrorMessageVisible = syncErrorMessageSubject .Select(error => !string.IsNullOrEmpty(error)) .DistinctUntilChanged() .AsDriver(false, schedulerProvider); Preferences = interactorFactory.GetPreferences().Execute() .AsDriver(null, schedulerProvider); // Actions Close = actionFactory.FromAsync(closeWithConfirmation); SelectProject = actionFactory.FromAsync(selectProject); SelectTags = actionFactory.FromAsync(selectTags); ToggleBillable = actionFactory.FromAction(toggleBillable); EditTimes = actionFactory.FromAsync <EditViewTapSource>(editTimes); SelectStartDate = actionFactory.FromAsync(selectStartDate); StopTimeEntry = actionFactory.FromAction(stopTimeEntry, isTimeEntryRunningObservable); DismissSyncErrorMessage = actionFactory.FromAction(dismissSyncErrorMessage); Save = actionFactory.FromAsync(save); Delete = actionFactory.FromAsync(delete); }
public void ThreadSwitching() { Console.WriteLine("Starting Thread " + Thread.CurrentThread.ManagedThreadId); BehaviorSubject<int> s1 = new BehaviorSubject<int>(2); BehaviorSubject<int> s2 = new BehaviorSubject<int>(3); BehaviorSubject<int> sum = new BehaviorSubject<int>(5); List<int> computeThreads = new List<int>(); List<int> receiveThreads = new List<int>(); IScheduler switchScheduler = new EventLoopScheduler(); IScheduler computeScheduler = new EventLoopScheduler(); IObservable<int> sumObservable = s1.Select(v => new Tuple<int, int>(v, s2.Value)).Merge(s2.Select(v => new Tuple<int, int>(s1.Value, v))).Throttle(TimeSpan.FromMilliseconds(100), switchScheduler).Select(v => { Console.WriteLine("Not yet switching computing value " + v.Item1 + " + " + v.Item2 + " = " + (v.Item1 + v.Item2) + " from Thread " + Thread.CurrentThread.ManagedThreadId + "."); return v; }).Select(v => { Console.WriteLine("Switching computing value " + v.Item1 + " + " + v.Item2 + " = " + (v.Item1 + v.Item2) + " from Thread " + Thread.CurrentThread.ManagedThreadId + "."); return v; }).ObserveOn(computeScheduler).Select(v => { Console.WriteLine("Already switched computing value " + v.Item1 + " + " + v.Item2 + " = " + (v.Item1 + v.Item2) + " to Thread " + Thread.CurrentThread.ManagedThreadId + "."); return v; }).Select(v => { Console.WriteLine("Computing value " + v.Item1 + " + " + v.Item2 + " = " + (v.Item1 + v.Item2) + " on Thread " + Thread.CurrentThread.ManagedThreadId + "."); computeThreads.Add(Thread.CurrentThread.ManagedThreadId); return v.Item1 + v.Item2; }); sumObservable.Subscribe(sum.OnNext); sum.ObserveOn(new EventLoopScheduler()).Subscribe(v => { Console.WriteLine("Received value " + v + " on Thread " + Thread.CurrentThread.ManagedThreadId + "."); receiveThreads.Add(Thread.CurrentThread.ManagedThreadId); }); Thread.Sleep(150); s2.OnNext(1); Thread.Sleep(50); s1.OnNext(4); Thread.Sleep(150); s2.OnNext(4); Thread.Sleep(250); s1.OnNext(1); Thread.Sleep(150); foreach (KeyValuePair<int, int> p in computeThreads.GroupBy(v => v).Select(g => new KeyValuePair<int, int>(g.Key, g.Count()))) { Console.WriteLine(p.Value + " computes on Thread " + p.Key); } foreach (KeyValuePair<int, int> p in receiveThreads.GroupBy(v => v).Select(g => new KeyValuePair<int, int>(g.Key, g.Count()))) { Console.WriteLine(p.Value + " receives on Thread " + p.Key); } }