Skip to content

Commit

Permalink
proper solution
Browse files Browse the repository at this point in the history
  • Loading branch information
hohwille committed Oct 4, 2023
1 parent 957fced commit 095c078
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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() {

Expand Down
57 changes: 6 additions & 51 deletions core/src/main/java/io/github/mmm/event/AbstractEventSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -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}.
*
Expand All @@ -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<E> wrap(EventListener<E> listener, boolean weak) {

if (weak) {
return new WeakEventListener<>(this, listener);
}
return listener;
}

/**
* @param <E> 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 <E> EventListener<E> unwrap(EventListener<E> listener) {

if (listener == null) {
return null;
} else if (listener instanceof WeakEventListener) {
return ((WeakEventListener<E>) 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<E> l = (EventListener<E>) listener;
if (weak) {
l = l.weak(this);
}
doAddListener(l);
}

/**
Expand Down
36 changes: 36 additions & 0 deletions core/src/main/java/io/github/mmm/event/EventListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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<E> weak(EventSource<E, ?> source) {

return new WeakEventListener<>(source, this);
}

/**
* @return the raw {@link EventListener} that may be wrapped (e.g. via {@link #weak(EventSource)}).
*/
default EventListener<E> 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public EventSourceAdapter<E, L> addListener(EventListener<? super E> eventListen
@Override
public EventSourceAdapter<E, L> removeListener(EventListener<? super E> eventListener) {

if (AbstractEventSource.matches(eventListener, this.listener)) {
if (eventListener.matches(this.listener)) {
return EMPTY;
}
return null;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -249,7 +249,7 @@ public EventSourceAdapter<E, L> addListener(EventListener<? super E> listener) {
public EventSourceAdapter<E, L> removeListener(EventListener<? super E> 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 {
Expand Down Expand Up @@ -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;
}
Expand Down
13 changes: 13 additions & 0 deletions core/src/main/java/io/github/mmm/event/impl/WeakEventListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ public void onEvent(E event) {
}
}

@Override
public EventListener<E> weak(EventSource<E, ?> eventSource) {

assert (eventSource == this.source);
return this;
}

@Override
public EventListener<E> 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.
Expand Down

0 comments on commit 095c078

Please sign in to comment.