mirror of
https://github.com/androidx/media.git
synced 2025-05-11 09:39:52 +08:00
Give EventDispatcher more predictable behavior
If EventDispatcher.removeListener is called to remove a listener, and if the call is made from the same thread that said listener handles events on, then it should be guaranteed that the listener will not be subsequently invoked on that thread. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=218331427
This commit is contained in:
parent
5ae60a6f18
commit
13e0513ea3
@ -39,22 +39,23 @@ public final class EventDispatcher<T> {
|
||||
/** The list of listeners and handlers. */
|
||||
private final CopyOnWriteArrayList<HandlerAndListener<T>> listeners;
|
||||
|
||||
/** Creates event dispatcher. */
|
||||
/** Creates an event dispatcher. */
|
||||
public EventDispatcher() {
|
||||
listeners = new CopyOnWriteArrayList<>();
|
||||
}
|
||||
|
||||
/** Adds listener to event dispatcher. */
|
||||
/** Adds a listener to the event dispatcher. */
|
||||
public void addListener(Handler handler, T eventListener) {
|
||||
Assertions.checkArgument(handler != null && eventListener != null);
|
||||
removeListener(eventListener);
|
||||
listeners.add(new HandlerAndListener<>(handler, eventListener));
|
||||
}
|
||||
|
||||
/** Removes listener from event dispatcher. */
|
||||
/** Removes a listener from the event dispatcher. */
|
||||
public void removeListener(T eventListener) {
|
||||
for (HandlerAndListener<T> handlerAndListener : listeners) {
|
||||
if (handlerAndListener.listener == eventListener) {
|
||||
handlerAndListener.release();
|
||||
listeners.remove(handlerAndListener);
|
||||
}
|
||||
}
|
||||
@ -67,19 +68,33 @@ public final class EventDispatcher<T> {
|
||||
*/
|
||||
public void dispatch(Event<T> event) {
|
||||
for (HandlerAndListener<T> handlerAndListener : listeners) {
|
||||
T eventListener = handlerAndListener.listener;
|
||||
handlerAndListener.handler.post(() -> event.sendTo(eventListener));
|
||||
handlerAndListener.dispatch(event);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class HandlerAndListener<T> {
|
||||
|
||||
public final Handler handler;
|
||||
public final T listener;
|
||||
private final Handler handler;
|
||||
private final T listener;
|
||||
|
||||
private boolean released;
|
||||
|
||||
public HandlerAndListener(Handler handler, T eventListener) {
|
||||
this.handler = handler;
|
||||
this.listener = eventListener;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
released = true;
|
||||
}
|
||||
|
||||
public void dispatch(Event<T> event) {
|
||||
handler.post(
|
||||
() -> {
|
||||
if (!released) {
|
||||
event.sendTo(listener);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user