diff --git a/core/src/main/java/io/github/mmm/event/AbstractEventSender.java b/core/src/main/java/io/github/mmm/event/AbstractEventSender.java index 8d55ad7..5601be5 100644 --- a/core/src/main/java/io/github/mmm/event/AbstractEventSender.java +++ b/core/src/main/java/io/github/mmm/event/AbstractEventSender.java @@ -42,8 +42,8 @@ public boolean removeListener(L listener) { } /** - * @return {@code true} if at least one {@link EventListener} is {@link #addListener(EventListener, boolean) - * registered}, {@code false} otherwise. + * @return {@code true} if at least one {@link EventListener} is {@link #addListener(EventListener) registered}, + * {@code false} otherwise. */ protected boolean hasListeners() { diff --git a/core/src/main/java/io/github/mmm/event/AbstractEventSource.java b/core/src/main/java/io/github/mmm/event/AbstractEventSource.java index 7b8ee87..da4f740 100644 --- a/core/src/main/java/io/github/mmm/event/AbstractEventSource.java +++ b/core/src/main/java/io/github/mmm/event/AbstractEventSource.java @@ -2,8 +2,6 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ package io.github.mmm.event; -import io.github.mmm.event.impl.WeakEventListener; - /** * Implementation of {@link EventSource}. * @@ -21,58 +19,15 @@ public AbstractEventSource() { super(); } - /** - * @param listener the {@link EventListener} to wrap (potentially). - * @param weak - {@code true} to wrap as {@link WeakEventListener}, {@code false} otherwise. - * @return the given {@link EventListener} or a {@link WeakEventListener} wrapping it in case {@code weak} is - * {@code true}. - * @see EventSource#addListener(EventListener, boolean) - */ - protected final EventListener wrap(EventListener listener, boolean weak) { - - if (weak) { - return new WeakEventListener<>(this, listener); - } - return listener; - } - - /** - * @param type of the event. - * @param listener the {@link EventListener} to unwrap (potentially). - * @return the given {@link EventListener} or the unwrapped {@link EventListener} if a {@link WeakEventListener} was - * given. - */ - protected static EventListener unwrap(EventListener listener) { - - if (listener == null) { - return null; - } else if (listener instanceof WeakEventListener) { - return ((WeakEventListener) listener).ref.get(); - } - return listener; - } - - /** - * @param listener2remove the {@link EventListener} to {@link #removeListener(EventListener) remove}. - * @param registeredListener the {@link #addListener(EventListener) registered} {@link EventListener} to match with. - * @return {@code true} if the given {@link EventListener}s match, {@code false} otherwise. - */ - protected static boolean matches(EventListener listener2remove, EventListener registeredListener) { - - registeredListener = AbstractEventSource.unwrap(registeredListener); - if (listener2remove == registeredListener) { - return true; - } else if ((registeredListener.isMatchedUsingEquals()) && registeredListener.equals(listener2remove)) { - return true; - } - return false; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings("unchecked") @Override public void addListener(L listener, boolean weak) { - doAddListener(wrap((EventListener) listener, weak)); + EventListener l = (EventListener) listener; + if (weak) { + l = l.weak(this); + } + doAddListener(l); } /** diff --git a/core/src/main/java/io/github/mmm/event/EventListener.java b/core/src/main/java/io/github/mmm/event/EventListener.java index 956a9cb..084d2a9 100644 --- a/core/src/main/java/io/github/mmm/event/EventListener.java +++ b/core/src/main/java/io/github/mmm/event/EventListener.java @@ -2,6 +2,8 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ package io.github.mmm.event; +import io.github.mmm.event.impl.WeakEventListener; + /** * Interface for a generic event listener. * @@ -35,4 +37,38 @@ default boolean isMatchedUsingEquals() { */ void onEvent(E event); + /** + * @param source the {@link EventSource}. + * @return an instance of {@link EventListener} using a {@link java.lang.ref.WeakReference} so that this original + * {@link EventListener} can be gargabe collected without being + * {@link EventSource#removeListener(EventListener) removed} manually. + */ + default EventListener weak(EventSource source) { + + return new WeakEventListener<>(source, this); + } + + /** + * @return the raw {@link EventListener} that may be wrapped (e.g. via {@link #weak(EventSource)}). + */ + default EventListener unwrap() { + + return this; + } + + /** + * @param listener the registered {@link EventListener} to match with. + * @return {@code true} if this {@link EventListener} matches the given {@link EventListener}, {@code false} + * otherwise. + */ + default boolean matches(EventListener listener) { + + listener = listener.unwrap(); + if (this == listener) { + return true; + } else if ((listener.isMatchedUsingEquals()) && listener.equals(this)) { + return true; + } + return false; + } } diff --git a/core/src/main/java/io/github/mmm/event/EventSourceAdapter.java b/core/src/main/java/io/github/mmm/event/EventSourceAdapter.java index 6f9c842..fd39674 100644 --- a/core/src/main/java/io/github/mmm/event/EventSourceAdapter.java +++ b/core/src/main/java/io/github/mmm/event/EventSourceAdapter.java @@ -167,7 +167,7 @@ public EventSourceAdapter addListener(EventListener eventListen @Override public EventSourceAdapter removeListener(EventListener eventListener) { - if (AbstractEventSource.matches(eventListener, this.listener)) { + if (eventListener.matches(this.listener)) { return EMPTY; } return null; @@ -196,7 +196,7 @@ public int getListenerCount() { public L getListener(int index) { if (index == 0) { - return (L) AbstractEventSource.unwrap(this.listener); + return (L) this.listener.unwrap(); } return null; } @@ -249,7 +249,7 @@ public EventSourceAdapter addListener(EventListener listener) { public EventSourceAdapter removeListener(EventListener listener) { for (int i = 0; i < this.listenerCount; i++) { - if (AbstractEventSource.matches(listener, this.listeners[i])) { + if (listener.matches(this.listeners[i])) { if (this.listenerCount == 2) { return new Single<>(this.listeners[1 - i]); } else { @@ -307,7 +307,7 @@ public int getListenerCount() { public L getListener(int index) { if ((index >= 0) && (index < this.listenerCount)) { - return (L) AbstractEventSource.unwrap(this.listeners[index]); + return (L) this.listeners[index].unwrap(); } return null; } diff --git a/core/src/main/java/io/github/mmm/event/impl/WeakEventListener.java b/core/src/main/java/io/github/mmm/event/impl/WeakEventListener.java index c9da5bd..ea671ff 100644 --- a/core/src/main/java/io/github/mmm/event/impl/WeakEventListener.java +++ b/core/src/main/java/io/github/mmm/event/impl/WeakEventListener.java @@ -58,6 +58,19 @@ public void onEvent(E event) { } } + @Override + public EventListener weak(EventSource eventSource) { + + assert (eventSource == this.source); + return this; + } + + @Override + public EventListener unwrap() { + + return this.ref.get(); + } + /** * @param count the current size of listeners. Has to be less or equal to the length of the given {@code listeners} * array.