public void TestInitialFalse() { var notifier = new BooleanNotifier(false); var recorder = new TestScheduler().CreateObserver<bool>(); notifier.Subscribe(recorder); notifier.Value.Is(false); notifier.TurnOn(); notifier.TurnOff(); notifier.Value = true; notifier.Value = true; notifier.Value = false; notifier.TurnOn(); notifier.SwitchValue(); notifier.SwitchValue(); recorder.Messages.Is( OnNext(0, true), OnNext(0, false), OnNext(0, true), OnNext(0, true), OnNext(0, false), OnNext(0, true), OnNext(0, false), OnNext(0, true)); recorder.Messages.Clear(); notifier.TurnOn(); recorder.Messages.Count.Is(0); }
public void TestInitialFalse() { var notifier = new BooleanNotifier(false); var recorder = new TestScheduler().CreateObserver <bool>(); notifier.Subscribe(recorder); notifier.Value.Is(false); notifier.TurnOn(); notifier.TurnOff(); notifier.Value = true; notifier.Value = true; notifier.Value = false; notifier.TurnOn(); notifier.SwitchValue(); notifier.SwitchValue(); recorder.Messages.Is( OnNext(0, true), OnNext(0, false), OnNext(0, true), OnNext(0, true), OnNext(0, false), OnNext(0, true), OnNext(0, false), OnNext(0, true)); recorder.Messages.Clear(); notifier.TurnOn(); recorder.Messages.Count.Is(0); }
public TimerStartCommandViewModel() { // ctorからカウント開始 var ctorDateTime = DateTime.Now; MyTimer1 = Observable.Interval(TimeSpan.FromSeconds(1)) .Select(_ => DateTime.Now - ctorDateTime) .ToReadOnlyReactivePropertySlim() .AddTo(CompositeDisposable); #if false // 1. DataTime.Now からの差分でカウント ◆もう少しかっちょよい実装ない? var clickDateTime = DateTime.MinValue; MyTimer2 = Observable.Interval(TimeSpan.FromSeconds(1)) .Where(_ => clickDateTime != DateTime.MinValue) .Select(_ => DateTime.Now - clickDateTime) .ToReadOnlyReactivePropertySlim() .AddTo(CompositeDisposable); StartCommand = new ReactiveCommand() .WithSubscribe(() => clickDateTime = DateTime.Now, CompositeDisposable.Add); StopCommand = new ReactiveCommand() .WithSubscribe(() => clickDateTime = DateTime.MinValue, CompositeDisposable.Add); #else // 2. BooleanNotifier で管理。Command.CanExecute も取れるので良い感じ var timerRunning = new BooleanNotifier(); // BooleanNotifier は IDisposable じゃないので Good! //var timerRunning = new ReactivePropertySlim<bool>(initialValue: false).AddTo(CompositeDisposable); MyTimer2 = Observable.Interval(TimeSpan.FromSeconds(1)) .TakeWhile(_ => timerRunning.Value) .Repeat() .Select(sec => TimeSpan.FromSeconds(sec)) .ToReadOnlyReactivePropertySlim() .AddTo(CompositeDisposable); StartCommand = timerRunning.Inverse() .ToReactiveCommand(!timerRunning.Value) .WithSubscribe(() => timerRunning.TurnOn(), CompositeDisposable.Add); // ◆BooleanNotifier は (Rpと違って) Subscribe 時に LatestValue を発行しないので初期値の指定が必要する StopCommand = timerRunning .ToReactiveCommand(timerRunning.Value) .WithSubscribe(() => timerRunning.TurnOff(), CompositeDisposable.Add); #endif }
internal async Task <bool> SetInputtedKeyAsync(Key actualKey, BooleanNotifier notMatchedKeyNotifier, BooleanNotifier keyMissingNotifier) { if (actualKey.TryToChar(out var actualChar)) { this.KeyInputtedCount.Value++; this.InputtedKey.Value = actualChar; if (actualKey == this.ExpectedKey.Value.ToKey()) { notMatchedKeyNotifier.TurnOff(); return(true); } this.KeyMistakedCount.Value++; notMatchedKeyNotifier.TurnOn(); keyMissingNotifier.TurnOn(); var task1 = AppContextService.BeepAsync(); var task2 = Task.Delay(TimeSpan.FromSeconds(0.2)); await Task.WhenAny(task1, task2); keyMissingNotifier.TurnOff(); } return(false); }
public DevicePageViewModel(UnconnectedImbleDevice unconnectedDevice) { this.Device = Observable.FromAsync(token => unconnectedDevice.Connect(token)) .CatchIgnore((Exception e) => { }) .ToReadOnlyReactiveProperty() .AddTo(this.disposables); this.IsConnected = this.Device.Select(device => device != null).ToReadOnlyReactiveProperty().AddTo(this.disposables); this.DeviceStatus = this.Device .Where(device => device != null) .Select(device => device.ObserveProperty(self => self.Status)) .Switch() .Do(value => Debug.WriteLine(value)) .ObserveOnUIDispatcher() .ToReadOnlyReactiveProperty() .AddTo(this.disposables); this.ReceivedMessage = this.Device .Where(device => device != null) .Select(device => Observable.FromEventPattern <DataArrivedEventArgs>(handler => device.DataArrived += handler, handler => device.DataArrived -= handler)) .Switch() .Select(args => new ReceivedMessageViewModel(args.EventArgs.Data, args.EventArgs.Timestamp)) .OnErrorRetry() .ToReadOnlyReactiveProperty() .AddTo(this.disposables); var notBusyNotifier = new BooleanNotifier(false); this.Name = new ReactiveProperty <string>("Fuga") .SetValidateNotifyError(value => value != null && Encoding.UTF8.GetByteCount(value) < 12 ? null : "Input short message") .AddTo(this.disposables); this.CanSendCommand = Observable.CombineLatest( this.DeviceStatus.Select(status => status == ImbleDeviceStatus.Running), this.Name.ObserveHasErrors, notBusyNotifier.Do(value => Debug.WriteLine(value)), (isRunning, hasErrors, notBusy) => isRunning && !hasErrors && notBusy) .ToReadOnlyReactiveProperty().AddTo(this.disposables); notBusyNotifier.TurnOn(); this.SendCommand = this.CanSendCommand.ToReactiveCommand().AddTo(this.disposables); this.SendCommand .Do(_ => notBusyNotifier.TurnOff()) .Select(_ => { var data = Encoding.UTF8.GetBytes(this.Name.Value); return(Observable.FromAsync(token => { using (var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5))) using (var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutTokenSource.Token)) { return this.Device.Value.SendAsync(data, 0, data.Length, linkedTokenSource.Token); } }) .Finally(() => notBusyNotifier.TurnOn())); }) .Switch() .OnErrorRetry((Exception e) => Debug.WriteLine(e)) .Subscribe() .AddTo(this.disposables); }
public DevicePageViewModel(UnconnectedImbleDevice unconnectedDevice) { this.Device = Observable.FromAsync(token => unconnectedDevice.Connect(token)) .CatchIgnore((Exception e) => { }) .ToReadOnlyReactiveProperty() .AddTo(this.disposables); this.IsConnected = this.Device.Select(device => device != null).ToReadOnlyReactiveProperty().AddTo(this.disposables); this.DeviceStatus = this.Device .Where(device => device != null) .Select(device => device.ObserveProperty(self => self.Status)) .Switch() .Do(value => Debug.WriteLine(value)) .ObserveOnUIDispatcher() .ToReadOnlyReactiveProperty() .AddTo(this.disposables); this.ReceivedMessage = this.Device .Where(device => device != null) .Select(device => Observable.FromEventPattern<DataArrivedEventArgs>(handler => device.DataArrived += handler, handler => device.DataArrived -= handler)) .Switch() .Select(args => new ReceivedMessageViewModel(args.EventArgs.Data, args.EventArgs.Timestamp)) .OnErrorRetry() .ToReadOnlyReactiveProperty() .AddTo(this.disposables); var notBusyNotifier = new BooleanNotifier(false); this.Name = new ReactiveProperty<string>("Fuga") .SetValidateNotifyError(value => value != null && Encoding.UTF8.GetByteCount(value) < 12 ? null : "Input short message") .AddTo(this.disposables); this.CanSendCommand = Observable.CombineLatest( this.DeviceStatus.Select(status => status == ImbleDeviceStatus.Running), this.Name.ObserveHasErrors, notBusyNotifier.Do(value => Debug.WriteLine(value)), (isRunning, hasErrors, notBusy) => isRunning && !hasErrors && notBusy) .ToReadOnlyReactiveProperty().AddTo(this.disposables); notBusyNotifier.TurnOn(); this.SendCommand = this.CanSendCommand.ToReactiveCommand().AddTo(this.disposables); this.SendCommand .Do(_ => notBusyNotifier.TurnOff()) .Select(_ => { var data = Encoding.UTF8.GetBytes(this.Name.Value); return Observable.FromAsync(token => { using (var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5))) using (var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutTokenSource.Token)) { return this.Device.Value.SendAsync(data, 0, data.Length, linkedTokenSource.Token); } }) .Finally(() => notBusyNotifier.TurnOn()); }) .Switch() .OnErrorRetry((Exception e) => Debug.WriteLine(e)) .Subscribe() .AddTo(this.disposables); }