diff --git a/SSignalKit/SSignal+Timing.h b/SSignalKit/SSignal+Timing.h index 0d07dbbcb1..6bf464c8b7 100644 --- a/SSignalKit/SSignal+Timing.h +++ b/SSignalKit/SSignal+Timing.h @@ -5,5 +5,6 @@ @interface SSignal (Timing) - (SSignal *)delay:(NSTimeInterval)seconds onQueue:(SQueue *)queue; +- (SSignal *)timeout:(NSTimeInterval)seconds onQueue:(SQueue *)queue or:(SSignal *)signal; @end diff --git a/SSignalKit/SSignal+Timing.m b/SSignalKit/SSignal+Timing.m index ee002fccf1..f1a47fc155 100644 --- a/SSignalKit/SSignal+Timing.m +++ b/SSignalKit/SSignal+Timing.m @@ -1,6 +1,7 @@ #import "SSignal+Timing.h" #import "SMetaDisposable.h" +#import "SDisposableSet.h" #import "SBlockDisposable.h" #import "STimer.h" @@ -38,4 +39,43 @@ }]; } +- (SSignal *)timeout:(NSTimeInterval)seconds onQueue:(SQueue *)queue or:(SSignal *)signal +{ + return [[SSignal alloc] initWithGenerator:^id (SSubscriber *subscriber) + { + SMetaDisposable *disposable = [[SMetaDisposable alloc] init]; + + STimer *timer = [[STimer alloc] initWithTimeout:seconds repeat:false completion:^ + { + [disposable setDisposable:[signal startWithNext:^(id next) + { + [subscriber putNext:next]; + } error:^(id error) + { + [subscriber putError:error]; + } completed:^ + { + [subscriber putCompletion]; + }]]; + } queue:queue]; + [timer start]; + + [disposable setDisposable:[self startWithNext:^(id next) + { + [timer invalidate]; + [subscriber putNext:next]; + } error:^(id error) + { + [timer invalidate]; + [subscriber putError:error]; + } completed:^ + { + [timer invalidate]; + [subscriber putCompletion]; + }]]; + + return disposable; + }]; +} + @end