Skip to content

Commit

Permalink
[util][sre] Remove the list of listeners in the internal event bus sk…
Browse files Browse the repository at this point in the history
…ill.

This list is used only for unregistering the listeners from the event
bus. Add the function unregisterAll on the event bus doing this task.

Signed-off-by: Stéphane Galland <galland@arakhne.org>
  • Loading branch information
gallandarakhneorg committed Nov 26, 2016
1 parent 3971ce0 commit ccb5a50
Show file tree
Hide file tree
Showing 11 changed files with 295 additions and 185 deletions.
Expand Up @@ -27,7 +27,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;

import com.google.common.base.MoreObjects;
Expand All @@ -53,7 +52,7 @@
* This class has been inspired by the com.google.common.eventbus.SuscriberRegistry class of Google Guava library.
*
* @author $Author: ngaud$
* @author $Author: ssgalland$
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
Expand Down Expand Up @@ -95,14 +94,34 @@ public ImmutableList<Method> load(Class<?> concreteClass) throws Exception {
* {@code BehaviorGuardEvaluator}s to an event without any locking.
* </p>
*/
private final ConcurrentMap<Class<? extends Event>, CopyOnWriteArraySet<BehaviorGuardEvaluator>> behaviorGuardEvaluators = Maps
.newConcurrentMap();
private final Map<Class<? extends Event>, CopyOnWriteArraySet<BehaviorGuardEvaluator>> behaviorGuardEvaluators;

/**
* Instanciates a new registry linked with the {@link PerceptGuardEvaluator} annotation.
*
* <p>The registry will use concurrent data structures.
*/
public BehaviorGuardEvaluatorRegistry() {
//
this(true);
}

/**
* Instanciates a new registry linked with the {@link PerceptGuardEvaluator} annotation.
*
* @param concurrent indicates if the internal data structures must support thread concurrency, or not.
*/
public BehaviorGuardEvaluatorRegistry(boolean concurrent) {
this(concurrent ? Maps.newConcurrentMap() : Maps.newHashMap());
}

/**
* Instanciates a new registry linked with the {@link PerceptGuardEvaluator} annotation.
*
* @param buffer the buffer to be used for storing the behavior guard evaluators.
*/
public BehaviorGuardEvaluatorRegistry(Map<Class<? extends Event>, CopyOnWriteArraySet<BehaviorGuardEvaluator>> buffer) {
assert buffer != null;
this.behaviorGuardEvaluators = buffer;
}

/**
Expand All @@ -129,6 +148,13 @@ public void register(Object listener) {
}
}

/**
* Unregisters all BehaviorGuardEvaluators on all the listener objects.
*/
public void unregisterAll() {
this.behaviorGuardEvaluators.clear();
}

/**
* Unregisters all BehaviorGuardEvaluators on the given listener object.
*
Expand Down
Expand Up @@ -21,8 +21,6 @@

package io.janusproject.kernel.bic;

import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
Expand Down Expand Up @@ -87,11 +85,6 @@ public class InternalEventBusSkill extends BuiltinSkill implements InternalEvent
*/
private final Address agentAddressInInnerDefaultSpace;

/**
* Collection of objects that are listening the event bus, except the owner of this skill.
*/
private List<Object> eventListeners;

/**
* @param agent - reference to the owner of this skill.
* @param addressInInnerDefaultSpace - address of the owner of this skill in its inner default space.
Expand Down Expand Up @@ -134,35 +127,17 @@ protected void install() {

@Override
protected void uninstall() {
this.eventDispatcher.unregister(getOwner());
// TODO: dispose eventBus => remove any registered objects, but without a list in this skill
final List<Object> list = this.eventListeners;
this.eventListeners = null;
if (list != null) {
for (final Object o : list) {
this.eventDispatcher.unregister(o);
}
}
this.eventDispatcher.unregisterAll();
}

@Override
public void registerEventListener(Object listener) {
this.eventDispatcher.register(listener);
if (this.eventListeners == null) {
this.eventListeners = new ArrayList<>();
}
this.eventListeners.add(listener);
}

@Override
public void unregisterEventListener(Object listener) {
this.eventDispatcher.unregister(listener);
if (this.eventListeners != null) {
this.eventListeners.remove(listener);
if (this.eventListeners.isEmpty()) {
this.eventListeners = null;
}
}
}

@Override
Expand Down
Expand Up @@ -121,6 +121,17 @@ public void unregister(Object object) {
}
}

/**
* Unregisters all {@code PerceptGuardEvaluator} methods on all registered objects.
*
* @throws IllegalArgumentException if the object was not previously registered.
*/
public void unregisterAll() {
synchronized (this.behaviorGuardEvaluatorRegistry) {
this.behaviorGuardEvaluatorRegistry.unregisterAll();
}
}

/**
* Posts an event to all registered {@code BehaviorGuardEvaluator}, the dispatch of this event will be done synchronously.
* This method will return successfully after the event has been posted to all {@code BehaviorGuardEvaluator}, and regardless
Expand Down
Expand Up @@ -106,14 +106,9 @@ public void install() throws Exception {
@Test
public void uninstall() throws Exception {
this.reflect.invoke(this.skill, "install");
EventListener eventListener = Mockito.mock(EventListener.class);
this.skill.registerEventListener(eventListener);
//
this.reflect.invoke(this.skill, "uninstall");
ArgumentCaptor<Object> argument = ArgumentCaptor.forClass(Object.class);
Mockito.verify(this.eventBus, new Times(2)).unregister(argument.capture());
assertSame(this.agent, argument.getAllValues().get(0));
assertSame(eventListener, argument.getAllValues().get(1));
Mockito.verify(this.eventBus, Mockito.times(1)).unregisterAll();
}

@Test
Expand Down
Expand Up @@ -151,6 +151,17 @@ public void unregister() {
Mockito.verify(this.executorService, Mockito.never()).execute(argument.capture());
}

@Test
public void unregisterAll() {
this.dispatcher.register(new MyAgent());
this.dispatcher.register(new MyAgent2());
this.dispatcher.register(new MyAgent2());
this.dispatcher.unregisterAll();
this.dispatcher.immediateDispatch(new Event() { });
ArgumentCaptor<Runnable> argument = ArgumentCaptor.forClass(Runnable.class);
Mockito.verify(this.executorService, Mockito.never()).execute(argument.capture());
}

public static class MyEvent extends Event {
public final int n;
public MyEvent(int n) {
Expand Down Expand Up @@ -184,4 +195,28 @@ public MyAgent() {

}

public static class MyAgent2 extends Agent {

public MyAgent2() {
super(null, UUID.randomUUID(), UUID.randomUUID());
}

@PerceptGuardEvaluator
private void $perception$guard$evaluator1(Event event, Collection<Runnable> runners) {
runners.add(() -> $perception$guard$callback1(event, event));
}

private void $perception$guard$callback1(Event occurrence, Event it) {
}

@PerceptGuardEvaluator
private void $perception$guard$evaluator2(MyEvent event, Collection<Runnable> runners) {
runners.add(() -> $perception$guard$callback2(event, event));
}

private void $perception$guard$callback2(MyEvent occurrence, MyEvent it) {
}

}

}
6 changes: 3 additions & 3 deletions tests/io.sarl.util.tests/META-INF/MANIFEST.MF
Expand Up @@ -8,7 +8,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Require-Bundle: io.sarl.util;bundle-version="0.5.0",
io.sarl.tests.api;bundle-version="0.5.0",
org.mockito.mockito-core;bundle-version="2.0.111"
Export-Package: io.sarl.eventdispatching.tests,
io.sarl.sarlspecification.tests,
io.sarl.util.tests
Export-Package: io.sarl.util.tests.eventdispatching,
io.sarl.util.tests.sarlspecification,
io.sarl.util.tests.util

This file was deleted.

0 comments on commit ccb5a50

Please sign in to comment.