Skip to content

Commit 5e43558

Browse files
Merge pull request #467 from benjchristensen/amb-merge
Merge Amb Operator in PR #460
2 parents 069ae42 + 4b9ca57 commit 5e43558

File tree

3 files changed

+539
-0
lines changed

3 files changed

+539
-0
lines changed

rxjava-core/src/main/java/rx/Observable.java

+191
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import rx.observables.ConnectableObservable;
3030
import rx.observables.GroupedObservable;
3131
import rx.operators.OperationAll;
32+
import rx.operators.OperationAmb;
3233
import rx.operators.OperationAny;
3334
import rx.operators.OperationAverage;
3435
import rx.operators.OperationBuffer;
@@ -4576,6 +4577,196 @@ public Observable<TimeInterval<T>> timeInterval(Scheduler scheduler) {
45764577
return create(OperationTimeInterval.timeInterval(this, scheduler));
45774578
}
45784579

4580+
/**
4581+
* Propagates the observable sequence that reacts first.
4582+
*
4583+
* @param o1
4584+
* an observable competing to react first.
4585+
* @param o2
4586+
* an observable competing to react first.
4587+
* @return
4588+
* an observable sequence that surfaces any of the given sequences, whichever reacted first.
4589+
* @see <a href="http://msdn.microsoft.com/en-us/library/hh229733(v=vs.103).aspx">MSDN: Observable.Amb</a>
4590+
*/
4591+
public static <T> Observable<T> amb(Observable<? extends T> o1, Observable<? extends T> o2) {
4592+
return create(OperationAmb.amb(o1, o2));
4593+
}
4594+
4595+
/**
4596+
* Propagates the observable sequence that reacts first.
4597+
*
4598+
* @param o1
4599+
* an observable competing to react first.
4600+
* @param o2
4601+
* an observable competing to react first.
4602+
* @param o3
4603+
* an observable competing to react first.
4604+
* @return
4605+
* an observable sequence that surfaces any of the given sequences, whichever reacted first.
4606+
* @see <a href="http://msdn.microsoft.com/en-us/library/hh229733(v=vs.103).aspx">MSDN: Observable.Amb</a>
4607+
*/
4608+
public static <T> Observable<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3) {
4609+
return create(OperationAmb.amb(o1, o2, o3));
4610+
}
4611+
4612+
/**
4613+
* Propagates the observable sequence that reacts first.
4614+
*
4615+
* @param o1
4616+
* an observable competing to react first.
4617+
* @param o2
4618+
* an observable competing to react first.
4619+
* @param o3
4620+
* an observable competing to react first.
4621+
* @param o4
4622+
* an observable competing to react first.
4623+
* @return
4624+
* an observable sequence that surfaces any of the given sequences, whichever reacted first.
4625+
* @see <a href="http://msdn.microsoft.com/en-us/library/hh229733(v=vs.103).aspx">MSDN: Observable.Amb</a>
4626+
*/
4627+
public static <T> Observable<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3, Observable<? extends T> o4) {
4628+
return create(OperationAmb.amb(o1, o2, o3, o4));
4629+
}
4630+
4631+
/**
4632+
* Propagates the observable sequence that reacts first.
4633+
*
4634+
* @param o1
4635+
* an observable competing to react first.
4636+
* @param o2
4637+
* an observable competing to react first.
4638+
* @param o3
4639+
* an observable competing to react first.
4640+
* @param o4
4641+
* an observable competing to react first.
4642+
* @param o5
4643+
* an observable competing to react first.
4644+
* @return
4645+
* an observable sequence that surfaces any of the given sequences, whichever reacted first.
4646+
* @see <a href="http://msdn.microsoft.com/en-us/library/hh229733(v=vs.103).aspx">MSDN: Observable.Amb</a>
4647+
*/
4648+
public static <T> Observable<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3, Observable<? extends T> o4, Observable<? extends T> o5) {
4649+
return create(OperationAmb.amb(o1, o2, o3, o4, o5));
4650+
}
4651+
4652+
/**
4653+
* Propagates the observable sequence that reacts first.
4654+
*
4655+
* @param o1
4656+
* an observable competing to react first.
4657+
* @param o2
4658+
* an observable competing to react first.
4659+
* @param o3
4660+
* an observable competing to react first.
4661+
* @param o4
4662+
* an observable competing to react first.
4663+
* @param o5
4664+
* an observable competing to react first.
4665+
* @param o6
4666+
* an observable competing to react first.
4667+
* @return
4668+
* an observable sequence that surfaces any of the given sequences, whichever reacted first.
4669+
* @see <a href="http://msdn.microsoft.com/en-us/library/hh229733(v=vs.103).aspx">MSDN: Observable.Amb</a>
4670+
*/
4671+
public static <T> Observable<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3, Observable<? extends T> o4, Observable<? extends T> o5, Observable<? extends T> o6) {
4672+
return create(OperationAmb.amb(o1, o2, o3, o4, o5, o6));
4673+
}
4674+
4675+
/**
4676+
* Propagates the observable sequence that reacts first.
4677+
*
4678+
* @param o1
4679+
* an observable competing to react first.
4680+
* @param o2
4681+
* an observable competing to react first.
4682+
* @param o3
4683+
* an observable competing to react first.
4684+
* @param o4
4685+
* an observable competing to react first.
4686+
* @param o5
4687+
* an observable competing to react first.
4688+
* @param o6
4689+
* an observable competing to react first.
4690+
* @param o7
4691+
* an observable competing to react first.
4692+
* @return
4693+
* an observable sequence that surfaces any of the given sequences, whichever reacted first.
4694+
* @see <a href="http://msdn.microsoft.com/en-us/library/hh229733(v=vs.103).aspx">MSDN: Observable.Amb</a>
4695+
*/
4696+
public static <T> Observable<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3, Observable<? extends T> o4, Observable<? extends T> o5, Observable<? extends T> o6, Observable<? extends T> o7) {
4697+
return create(OperationAmb.amb(o1, o2, o3, o4, o5, o6, o7));
4698+
}
4699+
4700+
/**
4701+
* Propagates the observable sequence that reacts first.
4702+
*
4703+
* @param o1
4704+
* an observable competing to react first.
4705+
* @param o2
4706+
* an observable competing to react first.
4707+
* @param o3
4708+
* an observable competing to react first.
4709+
* @param o4
4710+
* an observable competing to react first.
4711+
* @param o5
4712+
* an observable competing to react first.
4713+
* @param o6
4714+
* an observable competing to react first.
4715+
* @param o7
4716+
* an observable competing to react first.
4717+
* @param o8
4718+
* an observable competing to react first.
4719+
* @return
4720+
* an observable sequence that surfaces any of the given sequences, whichever reacted first.
4721+
* @see <a href="http://msdn.microsoft.com/en-us/library/hh229733(v=vs.103).aspx">MSDN: Observable.Amb</a>
4722+
*/
4723+
public static <T> Observable<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3, Observable<? extends T> o4, Observable<? extends T> o5, Observable<? extends T> o6, Observable<? extends T> o7, Observable<? extends T> o8) {
4724+
return create(OperationAmb.amb(o1, o2, o3, o4, o5, o6, o7, o8));
4725+
}
4726+
4727+
/**
4728+
* Propagates the observable sequence that reacts first.
4729+
*
4730+
* @param o1
4731+
* an observable competing to react first.
4732+
* @param o2
4733+
* an observable competing to react first.
4734+
* @param o3
4735+
* an observable competing to react first.
4736+
* @param o4
4737+
* an observable competing to react first.
4738+
* @param o5
4739+
* an observable competing to react first.
4740+
* @param o6
4741+
* an observable competing to react first.
4742+
* @param o7
4743+
* an observable competing to react first.
4744+
* @param o8
4745+
* an observable competing to react first.
4746+
* @param o9
4747+
* an observable competing to react first.
4748+
* @return
4749+
* an observable sequence that surfaces any of the given sequences, whichever reacted first.
4750+
* @see <a href="http://msdn.microsoft.com/en-us/library/hh229733(v=vs.103).aspx">MSDN: Observable.Amb</a>
4751+
*/
4752+
public static <T> Observable<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3, Observable<? extends T> o4, Observable<? extends T> o5, Observable<? extends T> o6, Observable<? extends T> o7, Observable<? extends T> o8, Observable<? extends T> o9) {
4753+
return create(OperationAmb.amb(o1, o2, o3, o4, o5, o6, o7, o8, o9));
4754+
}
4755+
4756+
/**
4757+
* Propagates the observable sequence that reacts first.
4758+
*
4759+
* @param sources
4760+
* observable sources competing to react first.
4761+
*
4762+
* @return
4763+
* an observable sequence that surfaces any of the given sequences, whichever reacted first.
4764+
* @see <a href="http://msdn.microsoft.com/en-us/library/hh229115(v=vs.103).aspx">MSDN: Observable.Amb</a>
4765+
*/
4766+
public static <T> Observable<T> amb(Iterable<? extends Observable<? extends T>> sources) {
4767+
return create(OperationAmb.amb(sources));
4768+
}
4769+
45794770
/**
45804771
* Whether a given {@link Function} is an internal implementation inside rx.* packages or not.
45814772
* <p>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
/**
2+
* Copyright 2013 Netflix, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package rx.operators;
17+
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
import java.util.concurrent.atomic.AtomicInteger;
21+
22+
import rx.Observable;
23+
import rx.Observable.OnSubscribeFunc;
24+
import rx.Observer;
25+
import rx.Subscription;
26+
import rx.subscriptions.CompositeSubscription;
27+
28+
/**
29+
* Propagates the observable sequence that reacts first.
30+
*/
31+
public class OperationAmb {
32+
33+
public static <T> OnSubscribeFunc<T> amb(Observable<? extends T> o1, Observable<? extends T> o2) {
34+
List<Observable<? extends T>> sources = new ArrayList<Observable<? extends T>>();
35+
sources.add(o1);
36+
sources.add(o2);
37+
return amb(sources);
38+
}
39+
40+
public static <T> OnSubscribeFunc<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3) {
41+
List<Observable<? extends T>> sources = new ArrayList<Observable<? extends T>>();
42+
sources.add(o1);
43+
sources.add(o2);
44+
sources.add(o3);
45+
return amb(sources);
46+
}
47+
48+
public static <T> OnSubscribeFunc<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3, Observable<? extends T> o4) {
49+
List<Observable<? extends T>> sources = new ArrayList<Observable<? extends T>>();
50+
sources.add(o1);
51+
sources.add(o2);
52+
sources.add(o3);
53+
sources.add(o4);
54+
return amb(sources);
55+
}
56+
57+
public static <T> OnSubscribeFunc<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3, Observable<? extends T> o4, Observable<? extends T> o5) {
58+
List<Observable<? extends T>> sources = new ArrayList<Observable<? extends T>>();
59+
sources.add(o1);
60+
sources.add(o2);
61+
sources.add(o3);
62+
sources.add(o4);
63+
sources.add(o5);
64+
return amb(sources);
65+
}
66+
67+
public static <T> OnSubscribeFunc<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3, Observable<? extends T> o4, Observable<? extends T> o5, Observable<? extends T> o6) {
68+
List<Observable<? extends T>> sources = new ArrayList<Observable<? extends T>>();
69+
sources.add(o1);
70+
sources.add(o2);
71+
sources.add(o3);
72+
sources.add(o4);
73+
sources.add(o5);
74+
sources.add(o6);
75+
return amb(sources);
76+
}
77+
78+
public static <T> OnSubscribeFunc<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3, Observable<? extends T> o4, Observable<? extends T> o5, Observable<? extends T> o6, Observable<? extends T> o7) {
79+
List<Observable<? extends T>> sources = new ArrayList<Observable<? extends T>>();
80+
sources.add(o1);
81+
sources.add(o2);
82+
sources.add(o3);
83+
sources.add(o4);
84+
sources.add(o5);
85+
sources.add(o6);
86+
sources.add(o7);
87+
return amb(sources);
88+
}
89+
90+
public static <T> OnSubscribeFunc<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3, Observable<? extends T> o4, Observable<? extends T> o5, Observable<? extends T> o6, Observable<? extends T> o7, Observable<? extends T> o8) {
91+
List<Observable<? extends T>> sources = new ArrayList<Observable<? extends T>>();
92+
sources.add(o1);
93+
sources.add(o2);
94+
sources.add(o3);
95+
sources.add(o4);
96+
sources.add(o5);
97+
sources.add(o6);
98+
sources.add(o7);
99+
sources.add(o8);
100+
return amb(sources);
101+
}
102+
103+
public static <T> OnSubscribeFunc<T> amb(Observable<? extends T> o1, Observable<? extends T> o2, Observable<? extends T> o3, Observable<? extends T> o4, Observable<? extends T> o5, Observable<? extends T> o6, Observable<? extends T> o7, Observable<? extends T> o8, Observable<? extends T> o9) {
104+
List<Observable<? extends T>> sources = new ArrayList<Observable<? extends T>>();
105+
sources.add(o1);
106+
sources.add(o2);
107+
sources.add(o3);
108+
sources.add(o4);
109+
sources.add(o5);
110+
sources.add(o6);
111+
sources.add(o7);
112+
sources.add(o8);
113+
sources.add(o9);
114+
return amb(sources);
115+
}
116+
117+
public static <T> OnSubscribeFunc<T> amb(
118+
final Iterable<? extends Observable<? extends T>> sources) {
119+
return new OnSubscribeFunc<T>() {
120+
121+
@Override
122+
public Subscription onSubscribe(final Observer<? super T> observer) {
123+
AtomicInteger choice = new AtomicInteger(AmbObserver.NONE);
124+
int index = 0;
125+
CompositeSubscription parentSubscription = new CompositeSubscription();
126+
for (Observable<? extends T> source : sources) {
127+
SafeObservableSubscription subscription = new SafeObservableSubscription();
128+
AmbObserver<T> ambObserver = new AmbObserver<T>(
129+
subscription, observer, index, choice);
130+
parentSubscription.add(subscription.wrap(source
131+
.subscribe(ambObserver)));
132+
index++;
133+
}
134+
return parentSubscription;
135+
}
136+
};
137+
}
138+
139+
private static class AmbObserver<T> implements Observer<T> {
140+
141+
private static final int NONE = -1;
142+
143+
private Subscription subscription;
144+
private Observer<? super T> observer;
145+
private int index;
146+
private AtomicInteger choice;
147+
148+
private AmbObserver(Subscription subscription,
149+
Observer<? super T> observer, int index, AtomicInteger choice) {
150+
this.subscription = subscription;
151+
this.observer = observer;
152+
this.choice = choice;
153+
this.index = index;
154+
}
155+
156+
@Override
157+
public void onNext(T args) {
158+
if (!isSelected()) {
159+
subscription.unsubscribe();
160+
return;
161+
}
162+
observer.onNext(args);
163+
}
164+
165+
@Override
166+
public void onCompleted() {
167+
if (!isSelected()) {
168+
subscription.unsubscribe();
169+
return;
170+
}
171+
observer.onCompleted();
172+
}
173+
174+
@Override
175+
public void onError(Throwable e) {
176+
if (!isSelected()) {
177+
subscription.unsubscribe();
178+
return;
179+
}
180+
observer.onError(e);
181+
}
182+
183+
private boolean isSelected() {
184+
if (choice.get() == NONE) {
185+
return choice.compareAndSet(NONE, index);
186+
}
187+
return choice.get() == index;
188+
}
189+
}
190+
191+
}

0 commit comments

Comments
 (0)