package de.danoeh.antennapod.core.feed;
import android.os.Handler;
import android.util.Log;
import java.util.AbstractQueue;
import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* Notifies its observers about changes in the feed database. Observers can
* register by retrieving an instance of this class and registering an
* EventListener. When new events arrive, the EventDistributor will process the
* event queue in a handler that runs on the main thread. The observers will only
* be notified once if the event queue contains multiple elements.
*
* Events can be sent with the send* methods.
*/
public class EventDistributor extends Observable {
private static final String TAG = "EventDistributor";
public static final int FEED_LIST_UPDATE = 1;
public static final int UNREAD_ITEMS_UPDATE = 2;
public static final int DOWNLOADLOG_UPDATE = 8;
public static final int PLAYBACK_HISTORY_UPDATE = 16;
public static final int DOWNLOAD_HANDLED = 64;
public static final int PLAYER_STATUS_UPDATE = 128;
private Handler handler;
private AbstractQueue<Integer> events;
private static EventDistributor instance;
private EventDistributor() {
this.handler = new Handler();
events = new ConcurrentLinkedQueue<>();
}
public static synchronized EventDistributor getInstance() {
if (instance == null) {
instance = new EventDistributor();
}
return instance;
}
public void register(EventListener el) {
addObserver(el);
}
public void unregister(EventListener el) {
deleteObserver(el);
}
public void addEvent(Integer i) {
events.offer(i);
handler.post(EventDistributor.this::processEventQueue);
}
private void processEventQueue() {
Integer result = 0;
Log.d(TAG, "Processing event queue. Number of events: " + events.size());
for (Integer current = events.poll(); current != null; current = events
.poll()) {
result |= current;
}
if (result != 0) {
Log.d(TAG, "Notifying observers. Data: " + result);
setChanged();
notifyObservers(result);
} else {
Log.d(TAG, "Event queue didn't contain any new events. Observers will not be notified.");
}
}
@Override
public void addObserver(Observer observer) {
super.addObserver(observer);
}
public void sendUnreadItemsUpdateBroadcast() {
addEvent(UNREAD_ITEMS_UPDATE);
}
public void sendFeedUpdateBroadcast() {
addEvent(FEED_LIST_UPDATE);
}
public void sendPlaybackHistoryUpdateBroadcast() {
addEvent(PLAYBACK_HISTORY_UPDATE);
}
public void sendDownloadLogUpdateBroadcast() {
addEvent(DOWNLOADLOG_UPDATE);
}
public void sendPlayerStatusUpdateBroadcast() { addEvent(PLAYER_STATUS_UPDATE); }
public static abstract class EventListener implements Observer {
@Override
public void update(Observable observable, Object data) {
if (observable instanceof EventDistributor
&& data instanceof Integer) {
update((EventDistributor) observable, (Integer) data);
}
}
public abstract void update(EventDistributor eventDistributor,
Integer arg);
}
}