17
17
18
18
import java .util .List ;
19
19
import java .util .concurrent .TimeUnit ;
20
+ import java .util .concurrent .atomic .AtomicBoolean ;
20
21
21
22
import rx .Observable ;
22
23
import rx .Observable .OnSubscribeFunc ;
23
24
import rx .Observer ;
24
25
import rx .Scheduler ;
25
26
import rx .Subscription ;
26
27
import rx .concurrency .Schedulers ;
28
+ import rx .subscriptions .CompositeSubscription ;
27
29
import rx .util .functions .Func0 ;
28
30
import rx .util .functions .Func1 ;
29
31
@@ -65,11 +67,14 @@ public static <T, TClosing> OnSubscribeFunc<List<T>> buffer(final Observable<T>
65
67
public Subscription onSubscribe (Observer <? super List <T >> observer ) {
66
68
NonOverlappingChunks <T , List <T >> buffers = new NonOverlappingChunks <T , List <T >>(observer , OperationBuffer .<T > bufferMaker ());
67
69
ChunkCreator creator = new ObservableBasedSingleChunkCreator <T , List <T >, TClosing >(buffers , bufferClosingSelector );
68
- return source .subscribe (new ChunkObserver <T , List <T >>(buffers , observer , creator ));
70
+ return new CompositeSubscription (
71
+ new ChunkToSubscription (creator ),
72
+ source .subscribe (new ChunkObserver <T , List <T >>(buffers , observer , creator ))
73
+ );
69
74
}
70
75
};
71
76
}
72
-
77
+
73
78
/**
74
79
* <p>This method creates a {@link Func1} object which represents the buffer operation. This operation takes
75
80
* values from the specified {@link Observable} source and stores them in the currently active chunks. Initially
@@ -101,7 +106,10 @@ public static <T, TOpening, TClosing> OnSubscribeFunc<List<T>> buffer(final Obse
101
106
public Subscription onSubscribe (final Observer <? super List <T >> observer ) {
102
107
OverlappingChunks <T , List <T >> buffers = new OverlappingChunks <T , List <T >>(observer , OperationBuffer .<T > bufferMaker ());
103
108
ChunkCreator creator = new ObservableBasedMultiChunkCreator <T , List <T >, TOpening , TClosing >(buffers , bufferOpenings , bufferClosingSelector );
104
- return source .subscribe (new ChunkObserver <T , List <T >>(buffers , observer , creator ));
109
+ return new CompositeSubscription (
110
+ new ChunkToSubscription (creator ),
111
+ source .subscribe (new ChunkObserver <T , List <T >>(buffers , observer , creator ))
112
+ );
105
113
}
106
114
};
107
115
}
@@ -156,7 +164,10 @@ public static <T> OnSubscribeFunc<List<T>> buffer(final Observable<T> source, fi
156
164
public Subscription onSubscribe (final Observer <? super List <T >> observer ) {
157
165
Chunks <T , List <T >> chunks = new SizeBasedChunks <T , List <T >>(observer , OperationBuffer .<T > bufferMaker (), count );
158
166
ChunkCreator creator = new SkippingChunkCreator <T , List <T >>(chunks , skip );
159
- return source .subscribe (new ChunkObserver <T , List <T >>(chunks , observer , creator ));
167
+ return new CompositeSubscription (
168
+ new ChunkToSubscription (creator ),
169
+ source .subscribe (new ChunkObserver <T , List <T >>(chunks , observer , creator ))
170
+ );
160
171
}
161
172
};
162
173
}
@@ -211,7 +222,10 @@ public static <T> OnSubscribeFunc<List<T>> buffer(final Observable<T> source, fi
211
222
public Subscription onSubscribe (final Observer <? super List <T >> observer ) {
212
223
NonOverlappingChunks <T , List <T >> buffers = new NonOverlappingChunks <T , List <T >>(observer , OperationBuffer .<T > bufferMaker ());
213
224
ChunkCreator creator = new TimeBasedChunkCreator <T , List <T >>(buffers , timespan , unit , scheduler );
214
- return source .subscribe (new ChunkObserver <T , List <T >>(buffers , observer , creator ));
225
+ return new CompositeSubscription (
226
+ new ChunkToSubscription (creator ),
227
+ source .subscribe (new ChunkObserver <T , List <T >>(buffers , observer , creator ))
228
+ );
215
229
}
216
230
};
217
231
}
@@ -270,9 +284,13 @@ public static <T> OnSubscribeFunc<List<T>> buffer(final Observable<T> source, fi
270
284
return new OnSubscribeFunc <List <T >>() {
271
285
@ Override
272
286
public Subscription onSubscribe (final Observer <? super List <T >> observer ) {
273
- Chunks <T , List <T >> chunks = new TimeAndSizeBasedChunks <T , List <T >>(observer , OperationBuffer .<T > bufferMaker (), count , timespan , unit , scheduler );
287
+ TimeAndSizeBasedChunks <T , List <T >> chunks = new TimeAndSizeBasedChunks <T , List <T >>(observer , OperationBuffer .<T > bufferMaker (), count , timespan , unit , scheduler );
274
288
ChunkCreator creator = new SingleChunkCreator <T , List <T >>(chunks );
275
- return source .subscribe (new ChunkObserver <T , List <T >>(chunks , observer , creator ));
289
+ return new CompositeSubscription (
290
+ chunks ,
291
+ new ChunkToSubscription (creator ),
292
+ source .subscribe (new ChunkObserver <T , List <T >>(chunks , observer , creator ))
293
+ );
276
294
}
277
295
};
278
296
}
@@ -331,9 +349,13 @@ public static <T> OnSubscribeFunc<List<T>> buffer(final Observable<T> source, fi
331
349
return new OnSubscribeFunc <List <T >>() {
332
350
@ Override
333
351
public Subscription onSubscribe (final Observer <? super List <T >> observer ) {
334
- OverlappingChunks <T , List <T >> buffers = new TimeBasedChunks <T , List <T >>(observer , OperationBuffer .<T > bufferMaker (), timespan , unit , scheduler );
352
+ TimeBasedChunks <T , List <T >> buffers = new TimeBasedChunks <T , List <T >>(observer , OperationBuffer .<T > bufferMaker (), timespan , unit , scheduler );
335
353
ChunkCreator creator = new TimeBasedChunkCreator <T , List <T >>(buffers , timeshift , unit , scheduler );
336
- return source .subscribe (new ChunkObserver <T , List <T >>(buffers , observer , creator ));
354
+ return new CompositeSubscription (
355
+ buffers ,
356
+ new ChunkToSubscription (creator ),
357
+ source .subscribe (new ChunkObserver <T , List <T >>(buffers , observer , creator ))
358
+ );
337
359
}
338
360
};
339
361
}
@@ -355,4 +377,24 @@ public List<T> getContents() {
355
377
return contents ;
356
378
}
357
379
}
380
+
381
+ /**
382
+ * Converts a chunk creator into a subscription which stops the chunk.
383
+ */
384
+ private static class ChunkToSubscription implements Subscription {
385
+ private ChunkCreator cc ;
386
+ private final AtomicBoolean done ;
387
+ public ChunkToSubscription (ChunkCreator cc ) {
388
+ this .cc = cc ;
389
+ this .done = new AtomicBoolean ();
390
+ }
391
+ @ Override
392
+ public void unsubscribe () {
393
+ if (done .compareAndSet (false , true )) {
394
+ ChunkCreator cc0 = cc ;
395
+ cc = null ;
396
+ cc0 .stop ();
397
+ }
398
+ }
399
+ }
358
400
}
0 commit comments