100 lines
2.5 KiB
Java
Raw Normal View History

package com.topjohnwu.magisk.utils;
import java.lang.ref.WeakReference;
2018-06-02 22:00:52 +08:00
import java.util.ArrayList;
import java.util.List;
public class Topic {
2018-03-17 20:20:05 +08:00
private static final int NON_INIT = 0;
private static final int PENDING = 1;
private static final int PUBLISHED = 2;
private int state = NON_INIT;
private List<WeakReference<Subscriber>> subscribers;
2018-03-17 20:20:05 +08:00
private Object[] results;
2018-06-02 22:00:52 +08:00
public Topic() {
subscribers = new SyncArrayList<>();
}
public synchronized void subscribe(Subscriber sub) {
subscribers.add(new WeakReference<>(sub));
}
2018-06-02 22:00:52 +08:00
public synchronized void unsubscribe() {
subscribers = new SyncArrayList<>();
}
2018-06-02 22:00:52 +08:00
public synchronized void unsubscribe(Subscriber sub) {
List<WeakReference<Subscriber>> subs = subscribers;
subscribers = new ArrayList<>();
for (WeakReference<Subscriber> subscriber : subs) {
if (subscriber.get() != null && subscriber.get() != sub)
subscribers.add(subscriber);
}
}
2018-03-17 20:20:05 +08:00
public void reset() {
state = NON_INIT;
results = null;
}
public boolean isPublished() {
return state == PUBLISHED;
}
2018-03-17 20:20:05 +08:00
public void publish() {
publish(true);
2017-10-07 17:12:36 +08:00
}
2018-03-17 20:20:05 +08:00
public void publish(boolean record, Object... results) {
if (record)
state = PUBLISHED;
this.results = results;
2018-06-02 22:00:52 +08:00
// Snapshot
List<WeakReference<Subscriber>> subs = subscribers;
for (WeakReference<Subscriber> subscriber : subs) {
if (subscriber != null && subscriber.get() != null)
subscriber.get().onTopicPublished(this);
}
}
2018-03-17 20:20:05 +08:00
public Object[] getResults() {
return results;
}
public boolean isPending() {
return state == PENDING;
}
public void setPending() {
state = PENDING;
}
public interface Subscriber {
default void subscribeTopics() {
for (Topic topic : getSubscription()) {
2018-03-17 20:20:05 +08:00
if (topic.isPublished()) {
onTopicPublished(topic);
}
topic.subscribe(this);
}
}
default void unsubscribeTopics() {
for (Topic event : getSubscription()) {
event.unsubscribe(this);
}
}
2018-03-17 20:20:05 +08:00
void onTopicPublished(Topic topic);
Topic[] getSubscription();
}
2018-06-02 22:00:52 +08:00
private static class SyncArrayList<E> extends ArrayList<E> {
@Override
public synchronized boolean add(E e) {
return super.add(e);
}
}
}