rx.subjects.PublishSubject Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rxjava-core Show documentation
Show all versions of rxjava-core Show documentation
rxjava-core developed by Netflix
/**
* Copyright 2014 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package rx.subjects;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicReference;
import rx.Notification;
import rx.Observer;
import rx.functions.Action1;
import rx.subjects.SubjectSubscriptionManager.SubjectObserver;
/**
* Subject that, once and {@link Observer} has subscribed, publishes all subsequent events to the subscriber.
*
*
*
* Example usage:
*
*
{@code
* PublishSubject
*
* @param
*/
public final class PublishSubject extends Subject {
public static PublishSubject create() {
final SubjectSubscriptionManager subscriptionManager = new SubjectSubscriptionManager();
// set a default value so subscriptions will immediately receive this until a new notification is received
final AtomicReference> lastNotification = new AtomicReference>();
OnSubscribe onSubscribe = subscriptionManager.getOnSubscribeFunc(
/**
* This function executes at beginning of subscription.
*
* This will always run, even if Subject is in terminal state.
*/
new Action1>() {
@Override
public void call(SubjectObserver super T> o) {
// nothing onSubscribe unless in terminal state which is the next function
}
},
/**
* This function executes if the Subject is terminated before subscription occurs.
*/
new Action1>() {
@Override
public void call(SubjectObserver super T> o) {
/*
* If we are already terminated, or termination happens while trying to subscribe
* this will be invoked and we emit whatever the last terminal value was.
*/
lastNotification.get().accept(o);
}
}, null);
return new PublishSubject(onSubscribe, subscriptionManager, lastNotification);
}
private final SubjectSubscriptionManager subscriptionManager;
final AtomicReference> lastNotification;
protected PublishSubject(OnSubscribe onSubscribe, SubjectSubscriptionManager subscriptionManager, AtomicReference> lastNotification) {
super(onSubscribe);
this.subscriptionManager = subscriptionManager;
this.lastNotification = lastNotification;
}
@Override
public void onCompleted() {
subscriptionManager.terminate(new Action1>>() {
@Override
public void call(Collection> observers) {
lastNotification.set(Notification. createOnCompleted());
for (Observer super T> o : observers) {
o.onCompleted();
}
}
});
}
@Override
public void onError(final Throwable e) {
subscriptionManager.terminate(new Action1>>() {
@Override
public void call(Collection> observers) {
lastNotification.set(Notification.createOnError(e));
for (Observer super T> o : observers) {
o.onError(e);
}
}
});
}
@Override
public void onNext(T v) {
for (Observer super T> o : subscriptionManager.rawSnapshot()) {
o.onNext(v);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy