Skip to content

Commit bb403a3

Browse files
committed
Autoremove EventHandler from parent
Signed-off-by: Ivan Santiago Paunovic <ivanpauno@ekumenlabs.com>
1 parent 257ed8b commit bb403a3

File tree

4 files changed

+38
-7
lines changed

4 files changed

+38
-7
lines changed

rcljava/src/main/java/org/ros2/rcljava/events/EventHandlerImpl.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.ros2.rcljava.common.JNIUtils;
2222
import org.ros2.rcljava.consumers.Consumer;
23+
import org.ros2.rcljava.consumers.Consumer;
2324
import org.ros2.rcljava.events.EventHandler;
2425
import org.ros2.rcljava.events.EventStatus;
2526
import org.ros2.rcljava.interfaces.Disposable;
@@ -64,16 +65,19 @@ public class EventHandlerImpl<
6465
* @param eventStatusFactory Factory of an event status.
6566
* @param callback The callback function that will be called when the event
6667
* is triggered.
68+
* @param removeCallback Callback that will be called when this object is being disposed.
6769
*/
6870
public EventHandlerImpl(
6971
final WeakReference<ParentT> parentReference,
7072
final long handle,
7173
final Supplier<T> eventStatusFactory,
72-
final Consumer<T> callback) {
74+
final Consumer<T> callback,
75+
final Consumer<EventHandler> removeCallback) {
7376
this.parentReference = parentReference;
7477
this.handle = handle;
7578
this.eventStatusFactory = eventStatusFactory;
7679
this.callback = callback;
80+
this.removeCallback = removeCallback;
7781
}
7882

7983
/**
@@ -102,9 +106,11 @@ public final long getHandle() {
102106
* {@inheritDoc}
103107
*/
104108
public synchronized final void dispose() {
105-
if (this.handle != 0) {
106-
nativeDispose(this.handle);
109+
if (this.handle == 0) {
110+
return;
107111
}
112+
this.removeCallback.accept(this);
113+
nativeDispose(this.handle);
108114
this.handle = 0;
109115
}
110116

@@ -126,11 +132,12 @@ public synchronized final void executeCallback() {
126132
nativeTake(this.handle, nativeEventStatusHandle);
127133
eventStatus.fromRCLEvent(nativeEventStatusHandle);
128134
eventStatus.deallocateRCLStatusEvent(nativeEventStatusHandle);
129-
callback.accept(eventStatus);
135+
this.callback.accept(eventStatus);
130136
}
131137

132138
private final Supplier<T> eventStatusFactory;
133139
private final WeakReference<ParentT> parentReference;
134140
private long handle;
135141
private final Consumer<T> callback;
142+
private final Consumer<EventHandler> removeCallback;
136143
}

rcljava/src/main/java/org/ros2/rcljava/publisher/PublisherImpl.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,20 @@ public final WeakReference<Node> getNodeReference() {
117117
public final
118118
<T extends PublisherEventStatus> EventHandler<T, Publisher>
119119
createEventHandler(Supplier<T> factory, Consumer<T> callback) {
120+
final WeakReference<Collection<EventHandler>> weakEventHandlers = new WeakReference(
121+
this.eventHandlers);
122+
Consumer<EventHandler> removeCallback = new Consumer<EventHandler>() {
123+
public void accept(EventHandler eventHandler) {
124+
Collection<EventHandler> eventHandlers = weakEventHandlers.get();
125+
if (eventHandlers != null) {
126+
eventHandlers.remove(eventHandler);
127+
}
128+
}
129+
};
120130
T status = factory.get();
121131
long eventHandle = nativeCreateEvent(this.handle, status.getPublisherEventType());
122132
EventHandler<T, Publisher> eventHandler = new EventHandlerImpl(
123-
new WeakReference<Publisher>(this), eventHandle, factory, callback);
133+
new WeakReference<Publisher>(this), eventHandle, factory, callback, removeCallback);
124134
this.eventHandlers.add(eventHandler);
125135
return eventHandler;
126136
}

rcljava/src/main/java/org/ros2/rcljava/subscription/SubscriptionImpl.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import org.ros2.rcljava.RCLJava;
2424
import org.ros2.rcljava.common.JNIUtils;
25+
import org.ros2.rcljava.consumers.BiConsumer;
2526
import org.ros2.rcljava.consumers.Consumer;
2627
import org.ros2.rcljava.events.EventHandler;
2728
import org.ros2.rcljava.events.EventHandlerImpl;
@@ -128,10 +129,20 @@ public final WeakReference<Node> getNodeReference() {
128129
public final
129130
<T extends SubscriptionEventStatus> EventHandler<T, Subscription>
130131
createEventHandler(Supplier<T> factory, Consumer<T> callback) {
132+
final WeakReference<Collection<EventHandler>> weakEventHandlers = new WeakReference(
133+
this.eventHandlers);
134+
Consumer<EventHandler> removeCallback = new Consumer<EventHandler>() {
135+
public void accept(EventHandler eventHandler) {
136+
Collection<EventHandler> eventHandlers = weakEventHandlers.get();
137+
if (eventHandlers != null) {
138+
eventHandlers.remove(eventHandler);
139+
}
140+
}
141+
};
131142
T status = factory.get();
132143
long eventHandle = nativeCreateEvent(this.handle, status.getSubscriptionEventType());
133144
EventHandler<T, Subscription> eventHandler = new EventHandlerImpl(
134-
new WeakReference<Subscription>(this), eventHandle, factory, callback);
145+
new WeakReference<Subscription>(this), eventHandle, factory, callback, removeCallback);
135146
this.eventHandlers.add(eventHandler);
136147
return eventHandler;
137148
}

rcljava/src/test/java/org/ros2/rcljava/publisher/PublisherTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,12 @@ public void accept(final OfferedQosIncompatible status) {
9090
}
9191
);
9292
assertNotEquals(0, eventHandler.getHandle());
93+
assertEquals(1, publisher.getEventHandlers().size());
9394
// force executing the callback, so we check that taking an event works
9495
eventHandler.executeCallback();
95-
RCLJava.shutdown();
96+
eventHandler.dispose();
9697
assertEquals(0, eventHandler.getHandle());
98+
assertEquals(0, publisher.getEventHandlers().size());
99+
RCLJava.shutdown();
97100
}
98101
}

0 commit comments

Comments
 (0)