protected IObservable <CommandResult> Run(Action work) { return(RxObservable.DfrCreate(() => { try { work(); } catch (Exception e) { return CommandResult.Failure(e.Message); } return CommandResult.Success(); }) .Catch <CommandResult, Exception>(e => CommandResult.Failure(e.Message).ToObservable())); }
public IObservable <bool> AutomateUserActions(Page page, RxnPageModel model, IObservable <IRxn> actions, Action <IRxn> publish) { return(RxObservable.DfrCreate <bool>(o => { var state = new InterceptState(model, actions, publish); var resources = new CompositeDisposable(new DisposableAction(() => { Debug.WriteLine("<<<<Disposing of {0}>>>>>", model.GetType().Name); })); if (page is ContentPage) { Observable.FromEventPattern(e => page.LayoutChanged += e, e => page.LayoutChanged -= e) .Select(_ => new Unit()) .StartWith(new Unit()) .BufferFirstLast(TimeSpan.FromMilliseconds(70), false) .Do(_ => o.OnNext(false)) .Do(_ => _dialog.ShowLoading("Loading...")) .Do(_ => Debug.WriteLine("Intercepting>>> {0}", model.GetType().Name)) .Select(_ => { return Observable.Defer(() => RxObservable.Create(() => { var timer = Stopwatch.StartNew(); var r = FindAllCommandHolder(((ContentPage)page).Content as IViewContainer <View>, state); timer.Stop(); Debug.WriteLine("Interception took: {0}", timer.Elapsed); if (r != null) { resources.Add(r); } })); }) .Switch() .Do(_ => _dialog.HideLoading()) .FinallyR(() => _dialog.HideLoading()) .Subscribe(_ => o.OnNext(true)) .DisposedBy(resources); return resources; } ; return Disposable.Empty; })); }
public IObservable <TValue> GetOrLookup(TKey key, Func <TKey, TValue> lookupFunc) { var keyLock = _expiryTimes.GetOrAdd(key, new ExpireyLock()); return(RxObservable.DfrCreate(() => { //keyLock.Lock.Wait(_lockTime); if (!_exists(_decorated, key)) { var newValue = lookupFunc(key); Set(key, newValue); return newValue; } return _getter(_decorated, key); })); // .FinallyR(() => keyLock.Lock.Release()); }
public IObservable <TValue> GetOrLookup(TKey key, Func <TKey, IObservable <TValue> > lookupFunc) { var keyLock = _expiryTimes.GetOrAdd(key, new ExpireyLock()); //we need to defer create so people who wont subscribe wont deadlock the cache. //because they will take a lock but never release it because finally isnt called return(RxObservable.DfrCreate <TValue>(o => { // keyLock.Lock.Wait(); if (_exists(_decorated, key)) { o.OnNext(_getter(_decorated, key)); o.OnCompleted(); return Disposable.Empty; } return lookupFunc(key).Subscribe(newValue => { try { Set(key, newValue); o.OnNext(newValue); } catch (Exception e) { o.OnError(e); } finally { o.OnCompleted(); } }, o.OnError); })); //.FinallyR(() => keyLock.Lock.Release()); }
public override IObservable <IRxn> Setup(IDeliveryScheme <IRxn> postman) { return(RxObservable.DfrCreate <IRxn>(o => { var localStream = base.Setup(postman).Subscribe(o); MessagingCenter.Subscribe <Bridge, string>(Bridge.Instance, Bridge.WrappedMsg, (sender, objAsJson) => { var wrapped = objAsJson.FromJson <Bridge.MsgWrapper>(); if (wrapped != null) { o.OnNext(wrapped.Msg); } }); var xamStream = new DisposableAction(() => { MessagingCenter.Unsubscribe <Bridge, string>(Bridge.Instance, Bridge.WrappedMsg); o.OnCompleted(); }); return new CompositeDisposable(localStream, xamStream); })); }
public PlaybackStream Play(ITapeStuff tape, PlaybackSettings settings = null) { settings = settings ?? new PlaybackSettings(); var playBackStream = new Subject <IRxn>(); var position = new Subject <TimeSpan>(); //todo: join buffers up using a gate to stop more actions buffering before they //have been played var sourceEventBuffer = RxObservable.DfrCreate <ICapturedRxn>(o => { return(tape.Source .Contents .ToObservableSequence() .Buffer(settings.ActionBuffer) .Do(events => { @events.ForEach(e => o.OnNext(e)); }) .FinallyR(() => { Debug.WriteLine("End of tape"); o.OnCompleted(); }) .Subscribe(_ => { }, e => o.OnError(e))); }); var isPaused = new BehaviorSubject <bool>(false); var setupOnPlayBack = RxObservable.DfrCreate <IRxn>(o => { var sincePlay = TimeSpan.Zero; var playbackBuffer = new Queue <ICapturedRxn>(); var playbackQueue = sourceEventBuffer.Do(buffered => { playbackBuffer.Enqueue(buffered); }) .Subscribe(_ => { }, () => { Debug.WriteLine("finsihed playbackQueue"); }); var realTimeClock = RxObservable.TimerWithPause(DateTimeOffset.MinValue, TimeSpan.FromSeconds(settings.TickSpeed), isPaused, _playbackScheduler) .Skip(1) //so we can buffer the stream. need a better mechanism!? .Do(tick => { //pause sincePlay = sincePlay.Add(TimeSpan.FromSeconds(settings.Speed)); CurrentThreadScheduler.Instance.Run(() => position.OnNext(sincePlay)); if (playbackBuffer.Count < 1) //todo: improve this when better buffreing mechanism implemented { o.OnCompleted(); return; } //finally play any events that have occoured based on the offset info while (playbackBuffer.Count > 0 && playbackBuffer.Peek().Offset < sincePlay) { playBackStream.OnNext(playbackBuffer.Dequeue().Recorded); } }) .Subscribe(_ => { }, o.OnError, () => { Debug.WriteLine("Finished position"); }); return(new CompositeDisposable(realTimeClock, playbackQueue, position, playBackStream.Subscribe(o), isPaused)); }); return(new PlaybackStream(tape.Name, setupOnPlayBack, position, isPaused)); }
protected virtual IObservable <IRxn> ProcessQueueItem(TQueueItem item) { return(RxObservable.DfrCreate(() => ProcessQueueItemSync(item))); }
public static IObservable <T> DoBuffered <T>(this IObservable <T> source, Action <T> @do, TimeSpan doEvery) { return(RxObservable.DfrCreate <T>(o => source.Subscribe(o)) .Throttle(doEvery) .Do(@do)); }