@@ -79,7 +79,7 @@ public interface IterationFinishedEvent<T> {
7979
8080 private final Clock clock ;
8181 private final HandlerWrapper handler ;
82- private final IterationFinishedEvent <T > iterationFinishedEvent ;
82+ @ Nullable private final IterationFinishedEvent <T > iterationFinishedEvent ;
8383 private final CopyOnWriteArraySet <ListenerHolder <T >> listeners ;
8484 private final ArrayDeque <Runnable > flushingEvents ;
8585 private final ArrayDeque <Runnable > queuedEvents ;
@@ -90,16 +90,37 @@ public interface IterationFinishedEvent<T> {
9090
9191 private boolean throwsWhenUsingWrongThread ;
9292
93+ /**
94+ * Creates a new listener set.
95+ *
96+ * <p>This listener set will not send an {@link IterationFinishedEvent} when all other events sent
97+ * during one {@link Looper} message queue iteration were handled by the listeners.
98+ *
99+ * @param looper A {@link Looper} used to call listeners on. The same {@link Looper} must be used
100+ * to call all other methods of this class unless indicated otherwise.
101+ * @param clock A {@link Clock}.
102+ */
103+ public ListenerSet (Looper looper , Clock clock ) {
104+ this (
105+ /* listeners= */ new CopyOnWriteArraySet <>(),
106+ looper ,
107+ clock ,
108+ /* iterationFinishedEvent= */ null ,
109+ /* throwsWhenUsingWrongThread= */ true );
110+ }
111+
93112 /**
94113 * Creates a new listener set.
95114 *
96115 * @param looper A {@link Looper} used to call listeners on. The same {@link Looper} must be used
97116 * to call all other methods of this class unless indicated otherwise.
98117 * @param clock A {@link Clock}.
99118 * @param iterationFinishedEvent An {@link IterationFinishedEvent} sent when all other events sent
100- * during one {@link Looper} message queue iteration were handled by the listeners.
119+ * during one {@link Looper} message queue iteration were handled by the listeners, or null if
120+ * no such event is needed.
101121 */
102- public ListenerSet (Looper looper , Clock clock , IterationFinishedEvent <T > iterationFinishedEvent ) {
122+ public ListenerSet (
123+ Looper looper , Clock clock , @ Nullable IterationFinishedEvent <T > iterationFinishedEvent ) {
103124 this (
104125 /* listeners= */ new CopyOnWriteArraySet <>(),
105126 looper ,
@@ -112,7 +133,7 @@ private ListenerSet(
112133 CopyOnWriteArraySet <ListenerHolder <T >> listeners ,
113134 Looper looper ,
114135 Clock clock ,
115- IterationFinishedEvent <T > iterationFinishedEvent ,
136+ @ Nullable IterationFinishedEvent <T > iterationFinishedEvent ,
116137 boolean throwsWhenUsingWrongThread ) {
117138 this .clock = clock ;
118139 this .listeners = listeners ;
@@ -134,14 +155,42 @@ private ListenerSet(
134155 *
135156 * @param looper The new {@link Looper} for the copied listener set.
136157 * @param iterationFinishedEvent The new {@link IterationFinishedEvent} sent when all other events
137- * sent during one {@link Looper} message queue iteration were handled by the listeners.
158+ * sent during one {@link Looper} message queue iteration were handled by the listeners, or
159+ * null if no such event is needed.
160+ * @return The copied listener set.
161+ */
162+ @ CheckResult
163+ public ListenerSet <T > copy (
164+ Looper looper , @ Nullable IterationFinishedEvent <T > iterationFinishedEvent ) {
165+ return copy (looper , clock , iterationFinishedEvent );
166+ }
167+
168+ /**
169+ * Copies the listener set.
170+ *
171+ * <p>This method can be called from any thread.
172+ *
173+ * @param looper The new {@link Looper} for the copied listener set.
138174 * @return The copied listener set.
139175 */
140176 @ CheckResult
141- public ListenerSet <T > copy (Looper looper , IterationFinishedEvent < T > iterationFinishedEvent ) {
177+ public ListenerSet <T > copy (Looper looper ) {
142178 return copy (looper , clock , iterationFinishedEvent );
143179 }
144180
181+ /**
182+ * Copies the listener set.
183+ *
184+ * <p>This method can be called from any thread.
185+ *
186+ * @param clock The new {@link Clock} for the copied listener set.
187+ * @return The copied listener set.
188+ */
189+ @ CheckResult
190+ public ListenerSet <T > copy (Clock clock ) {
191+ return copy (handler .getLooper (), clock , iterationFinishedEvent );
192+ }
193+
145194 /**
146195 * Copies the listener set.
147196 *
@@ -150,12 +199,13 @@ public ListenerSet<T> copy(Looper looper, IterationFinishedEvent<T> iterationFin
150199 * @param looper The new {@link Looper} for the copied listener set.
151200 * @param clock The new {@link Clock} for the copied listener set.
152201 * @param iterationFinishedEvent The new {@link IterationFinishedEvent} sent when all other events
153- * sent during one {@link Looper} message queue iteration were handled by the listeners.
202+ * sent during one {@link Looper} message queue iteration were handled by the listeners, or
203+ * null if no such event is needed.
154204 * @return The copied listener set.
155205 */
156206 @ CheckResult
157207 public ListenerSet <T > copy (
158- Looper looper , Clock clock , IterationFinishedEvent <T > iterationFinishedEvent ) {
208+ Looper looper , Clock clock , @ Nullable IterationFinishedEvent <T > iterationFinishedEvent ) {
159209 return new ListenerSet <>(
160210 listeners , looper , clock , iterationFinishedEvent , throwsWhenUsingWrongThread );
161211 }
@@ -214,8 +264,20 @@ public int size() {
214264 /**
215265 * Adds an event that is sent to the listeners when {@link #flushEvents} is called.
216266 *
217- * @param eventFlag An integer indicating the type of the event, or {@link C#INDEX_UNSET} to
218- * report this event without flag.
267+ * <p>This call does not set an integer flag for this event to be reported in the {@link
268+ * IterationFinishedEvent}. Use {@link #queueEvent(int, Event)} instead if this is required.
269+ *
270+ * @param event The event.
271+ */
272+ public void queueEvent (Event <T > event ) {
273+ queueEvent (/* eventFlag= */ C .INDEX_UNSET , event );
274+ }
275+
276+ /**
277+ * Adds an event that is sent to the listeners when {@link #flushEvents} is called.
278+ *
279+ * @param eventFlag An integer indicating the type of the event to be reported in the {@link
280+ * IterationFinishedEvent}, or {@link C#INDEX_UNSET} to report this event without flag.
219281 * @param event The event.
220282 */
221283 public void queueEvent (int eventFlag , Event <T > event ) {
@@ -235,7 +297,7 @@ public void flushEvents() {
235297 if (queuedEvents .isEmpty ()) {
236298 return ;
237299 }
238- if (!handler .hasMessages (MSG_ITERATION_FINISHED )) {
300+ if (iterationFinishedEvent != null && !handler .hasMessages (MSG_ITERATION_FINISHED )) {
239301 handler .sendMessageAtFrontOfQueue (handler .obtainMessage (MSG_ITERATION_FINISHED ));
240302 }
241303 boolean recursiveFlushInProgress = !flushingEvents .isEmpty ();
@@ -251,12 +313,25 @@ public void flushEvents() {
251313 }
252314 }
253315
316+ /**
317+ * {@link #queueEvent(Event) Queues} a single event and immediately {@link #flushEvents() flushes}
318+ * the event queue to notify all listeners.
319+ *
320+ * <p>This call does not set an integer flag for this event to be reported in the {@link
321+ * IterationFinishedEvent}. Use {@link #sendEvent(int, Event)} instead if this is required.
322+ *
323+ * @param event The event.
324+ */
325+ public void sendEvent (Event <T > event ) {
326+ sendEvent (/* eventFlag= */ C .INDEX_UNSET , event );
327+ }
328+
254329 /**
255330 * {@link #queueEvent(int, Event) Queues} a single event and immediately {@link #flushEvents()
256331 * flushes} the event queue to notify all listeners.
257332 *
258- * @param eventFlag An integer flag indicating the type of the event, or {@link C#INDEX_UNSET} to
259- * report this event without flag.
333+ * @param eventFlag An integer flag indicating the type of the event to be reported in the {@link
334+ * IterationFinishedEvent}, or {@link C#INDEX_UNSET} to report this event without flag.
260335 * @param event The event.
261336 */
262337 public void sendEvent (int eventFlag , Event <T > event ) {
@@ -294,8 +369,9 @@ public void setThrowsWhenUsingWrongThread(boolean throwsWhenUsingWrongThread) {
294369 }
295370
296371 private boolean handleMessage (Message message ) {
372+ IterationFinishedEvent <T > event = checkNotNull (iterationFinishedEvent );
297373 for (ListenerHolder <T > holder : listeners ) {
298- holder .iterationFinished (iterationFinishedEvent );
374+ holder .iterationFinished (event );
299375 if (handler .hasMessages (MSG_ITERATION_FINISHED )) {
300376 // The invocation above triggered new events (and thus scheduled a new message). We need
301377 // to stop here because this new message will take care of informing every listener about
@@ -326,9 +402,9 @@ public ListenerHolder(T listener) {
326402 this .flagsBuilder = new FlagSet .Builder ();
327403 }
328404
329- public void release (IterationFinishedEvent <T > event ) {
405+ private void release (@ Nullable IterationFinishedEvent <T > event ) {
330406 released = true ;
331- if (needsIterationFinishedEvent ) {
407+ if (event != null && needsIterationFinishedEvent ) {
332408 needsIterationFinishedEvent = false ;
333409 event .invoke (listener , flagsBuilder .build ());
334410 }
0 commit comments