2017-08-04 00:12:11 +08:00
|
|
|
package com.topjohnwu.magisk.utils;
|
|
|
|
|
|
|
|
import java.lang.ref.WeakReference;
|
2018-06-02 22:00:52 +08:00
|
|
|
import java.util.ArrayList;
|
2017-08-04 00:12:11 +08:00
|
|
|
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;
|
2017-08-04 00:12:11 +08:00
|
|
|
private List<WeakReference<Subscriber>> subscribers;
|
2018-03-17 20:20:05 +08:00
|
|
|
private Object[] results;
|
2017-08-04 00:12:11 +08:00
|
|
|
|
2018-06-02 22:00:52 +08:00
|
|
|
public Topic() {
|
|
|
|
subscribers = new SyncArrayList<>();
|
|
|
|
}
|
|
|
|
|
|
|
|
public synchronized void subscribe(Subscriber sub) {
|
2017-08-04 00:12:11 +08:00
|
|
|
subscribers.add(new WeakReference<>(sub));
|
|
|
|
}
|
|
|
|
|
2018-06-02 22:00:52 +08:00
|
|
|
public synchronized void unsubscribe() {
|
|
|
|
subscribers = new SyncArrayList<>();
|
2017-08-04 00:12:11 +08:00
|
|
|
}
|
|
|
|
|
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);
|
2017-08-04 00:12:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-17 20:20:05 +08:00
|
|
|
public void reset() {
|
|
|
|
state = NON_INIT;
|
|
|
|
results = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isPublished() {
|
|
|
|
return state == PUBLISHED;
|
2017-08-04 00:12:11 +08:00
|
|
|
}
|
|
|
|
|
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);
|
2017-08-04 00:12:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-17 20:20:05 +08:00
|
|
|
public Object[] getResults() {
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isPending() {
|
|
|
|
return state == PENDING;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setPending() {
|
|
|
|
state = PENDING;
|
|
|
|
}
|
2017-08-04 00:12:11 +08:00
|
|
|
|
|
|
|
public interface Subscriber {
|
|
|
|
default void subscribeTopics() {
|
|
|
|
for (Topic topic : getSubscription()) {
|
2018-03-17 20:20:05 +08:00
|
|
|
if (topic.isPublished()) {
|
2017-08-04 00:12:11 +08:00
|
|
|
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);
|
2017-08-04 00:12:11 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2017-08-04 00:12:11 +08:00
|
|
|
}
|