summaryrefslogtreecommitdiff
path: root/src/de/danoeh/antennapod/feed/EventDistributor.java
blob: 1fc7e2c354456c74a0700b4ad24351e8ddcc1d95 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package de.danoeh.antennapod.feed;

import java.util.AbstractQueue;
import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.ConcurrentLinkedQueue;

import android.os.Handler;
import android.util.Log;
import de.danoeh.antennapod.AppConfig;

/**
 * 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 QUEUE_UPDATE = 4;
	public static final int DOWNLOADLOG_UPDATE = 8;
	public static final int PLAYBACK_HISTORY_UPDATE = 16;
	public static final int DOWNLOAD_QUEUED = 32;
	public static final int DOWNLOAD_HANDLED = 64;

	private Handler handler;
	private AbstractQueue<Integer> events;

	private static EventDistributor instance;

	private EventDistributor() {
		this.handler = new Handler();
		events = new ConcurrentLinkedQueue<Integer>();
	}

	public static 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(new Runnable() {

			@Override
			public void run() {
				processEventQueue();
			}
		});
	}

	private void processEventQueue() {
		Integer result = 0;
		if (AppConfig.DEBUG)
			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) {
			if (AppConfig.DEBUG)
				Log.d(TAG, "Notifying observers. Data: " + result);
			setChanged();
			notifyObservers(result);
		} else {
			if (AppConfig.DEBUG)
				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);
		if (!(observer instanceof EventListener)) {
			throw new IllegalArgumentException(
					"Observer must be instance of FeedManager.EventListener");
		}
	}

	public void sendDownloadQueuedBroadcast() {
		addEvent(DOWNLOAD_QUEUED);
	}

	public void sendUnreadItemsUpdateBroadcast() {
		addEvent(UNREAD_ITEMS_UPDATE);
	}

	public void sendQueueUpdateBroadcast() {
		addEvent(QUEUE_UPDATE);
	}

	public void sendFeedUpdateBroadcast() {
		addEvent(FEED_LIST_UPDATE);
	}

	public void sendPlaybackHistoryUpdateBroadcast() {
		addEvent(PLAYBACK_HISTORY_UPDATE);
	}

	public void sendDownloadLogUpdateBroadcast() {
		addEvent(DOWNLOADLOG_UPDATE);
	}

	public void sendDownloadHandledBroadcast() {
		addEvent(DOWNLOAD_HANDLED);
	}

	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);
	}
}