/// <summary> /// A timer that is capable of being paused and resumed. It does not maintain the long value of the sequence /// between pauses because i have never found use for this value ;) /// /// limitation: when the timer is paused and resumed, it starts producing values again straight away, if even if the period has not elpased yet /// </summary> /// <param name="dueTime"></param> /// <param name="period"></param> /// <param name="isPaused"></param> /// <param name="scheduler"></param> /// <returns></returns> public static IObservable <long> TimerWithPause(DateTimeOffset dueTime, TimeSpan period, IObservable <bool> isPaused, IScheduler scheduler = null) { return(RxObservable.DfrCreate <long>(o => { var isFirst = true; IDisposable timer = null; Func <bool, IObservable <long> > createTimer = (isInital) => { return Observable.Timer(isInital ? dueTime : DateTimeOffset.MinValue, period, scheduler ?? Scheduler.Default).Do(v => o.OnNext(v), error => o.OnError(error)); }; var playPauser = isPaused.If(paused => paused, _ => { if (timer != null) { timer.Dispose(); } }) .If(paused => !paused, _ => { timer = createTimer(isFirst).Subscribe(); isFirst = false; }) .Subscribe(); return new CompositeDisposable(timer, playPauser); })); }
//todo: convert to Run syntax public override IObservable <CommandResult> Start(string @from = null, string options = null) { return(RxObservable.Create(() => { var @default = GetOrCreate(DefaultReactorName); if (@default.Connection != null) { return CommandResult.Success(); } @default.Connection = @default.Reactor.Chain(_rxnManager); return CommandResult.Success(); })); }
/// <summary> /// Sets up a new reaction pipeline on a component that implements INotifyPropertyChanged. This is /// /// This method is provided for interop on platforms that dont support the ExpandoObject (dynamic) ie. Xamarin.iOS /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="observeInitial">If the subscription will be alerted as soon as its made, no property change is required</param> /// <param name="scheduler"></param> /// <param name="properties">The properties to watch for changes to</param> /// <returns>A dictionary with the propertName as the key, and property value which u will need to cast to whatever type they are supposed to be</returns> public static IObservable <Dictionary <string, object> > OnReaction <T>(this T source, bool observeInitial, IScheduler scheduler, params Expression <Func <T, object> >[] properties) where T : INotifyPropertyChanged { return(RxObservable.DfrCreate <Dictionary <string, object> >(o => { try { var propertyNames = new Dictionary <string, Func <T, object> >(); Func <Dictionary <string, object> > GetValues = () => { var d = new Dictionary <string, object>(); foreach (var p in propertyNames) { d[p.Key] = p.Value.Invoke(source); } return d; }; foreach (var property in properties) { propertyNames.Add(property.GetPropertyInfo().Name, property.Compile()); } var sub = IObservableExtensions .FromPropertyChanged <PropertyChangedEventHandler, PropertyChangedEventArgs>( handler => handler.Invoke, h => source.PropertyChanged += h, h => source.PropertyChanged -= h) .Where(e => propertyNames.ContainsKey(e.EventArgs.PropertyName)) .Select(e => GetValues()); if (observeInitial) { sub = sub.StartWith(GetValues()); } return sub.Subscribe(o); } catch (Exception e) { o.OnError(e); return Disposable.Empty; } }) .ObserveOn(scheduler) .SubscribeOn(scheduler)); }