Skip to content

Commit 71511ac

Browse files
committed
Autoremove EventHandler from parent entity (#16)
Signed-off-by: Ivan Santiago Paunovic <ivanpauno@ekumenlabs.com>
1 parent 1666b0f commit 71511ac

File tree

4 files changed

+37
-7
lines changed

4 files changed

+37
-7
lines changed

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,19 @@ public class EventHandlerImpl<
6464
* @param eventStatusFactory Factory of an event status.
6565
* @param callback The callback function that will be called when the event
6666
* is triggered.
67+
* @param disposeCallback Callback that will be called when this object is disposed.
6768
*/
6869
public EventHandlerImpl(
6970
final WeakReference<ParentT> parentReference,
7071
final long handle,
7172
final Supplier<T> eventStatusFactory,
72-
final Consumer<T> callback) {
73+
final Consumer<T> callback,
74+
final Consumer<EventHandler> disposeCallback) {
7375
this.parentReference = parentReference;
7476
this.handle = handle;
7577
this.eventStatusFactory = eventStatusFactory;
7678
this.callback = callback;
79+
this.disposeCallback = disposeCallback;
7780
}
7881

7982
/**
@@ -102,9 +105,11 @@ public final long getHandle() {
102105
* {@inheritDoc}
103106
*/
104107
public synchronized final void dispose() {
105-
if (this.handle != 0) {
106-
nativeDispose(this.handle);
108+
if (this.handle == 0) {
109+
return;
107110
}
111+
this.disposeCallback.accept(this);
112+
nativeDispose(this.handle);
108113
this.handle = 0;
109114
}
110115

@@ -126,11 +131,12 @@ public synchronized final void executeCallback() {
126131
nativeTake(this.handle, nativeEventStatusHandle);
127132
eventStatus.fromRCLEvent(nativeEventStatusHandle);
128133
eventStatus.deallocateRCLStatusEvent(nativeEventStatusHandle);
129-
callback.accept(eventStatus);
134+
this.callback.accept(eventStatus);
130135
}
131136

132137
private final Supplier<T> eventStatusFactory;
133138
private final WeakReference<ParentT> parentReference;
134139
private long handle;
135140
private final Consumer<T> callback;
141+
private final Consumer<EventHandler> disposeCallback;
136142
}

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> disposeCallback = 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, disposeCallback);
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> disposeCallback = 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, disposeCallback);
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
@@ -91,10 +91,13 @@ public void accept(final OfferedQosIncompatible status) {
9191
}
9292
);
9393
assertNotEquals(0, eventHandler.getHandle());
94+
assertEquals(1, publisher.getEventHandlers().size());
9495
// force executing the callback, so we check that taking an event works
9596
eventHandler.executeCallback();
96-
RCLJava.shutdown();
97+
eventHandler.dispose();
9798
assertEquals(0, eventHandler.getHandle());
99+
assertEquals(0, publisher.getEventHandlers().size());
100+
RCLJava.shutdown();
98101
}
99102

100103
@Test

0 commit comments

Comments
 (0)