Commit 902b0174 authored by Robert Smith's avatar Robert Smith
Browse files

Added UpdateableSubscriptionManager test



Added a test class for the UpdateableSubscriptionManager, which has been
changed so that it will pass on only message types listeners are
subscribed for, rather than send all messages to everything which is
subscribed to any of them. 
Signed-off-by: Robert Smith's avatarRobert Smith <SmithRW@ornl.gov>
parent 93e00594
......@@ -145,7 +145,7 @@ public class TestComponentListener implements IManagedUpdateableListener, IUpdat
@Override
public ArrayList<UpdateableSubscriptionType> getSubscriptions(IManagedUpdateable source) {
ArrayList<UpdateableSubscriptionType> types = new ArrayList<UpdateableSubscriptionType>();
types.add(UpdateableSubscriptionType.All);
types.add(UpdateableSubscriptionType.ALL);
return types;
}
......
......@@ -382,7 +382,7 @@ public class GeometryComponent extends ICEObject implements Component,
// Register for all event types
ArrayList<UpdateableSubscriptionType> types = new ArrayList<UpdateableSubscriptionType>();
types.add(UpdateableSubscriptionType.All);
types.add(UpdateableSubscriptionType.ALL);
return types;
}
}
\ No newline at end of file
......@@ -334,7 +334,7 @@ public class MeshComponent extends ICEObject
// Only pass on updates for the root part's list of children changing,
// in order to refresh the tree view of components.
for (UpdateableSubscriptionType type : types) {
if (type == UpdateableSubscriptionType.Child) {
if (type == UpdateableSubscriptionType.CHILD) {
notifyListeners();
}
}
......@@ -354,7 +354,7 @@ public class MeshComponent extends ICEObject
// Register for all event types
ArrayList<UpdateableSubscriptionType> types = new ArrayList<UpdateableSubscriptionType>();
types.add(UpdateableSubscriptionType.All);
types.add(UpdateableSubscriptionType.ALL);
return types;
}
......
......@@ -154,7 +154,7 @@ public class PipeMesh extends TubeMesh {
// Notify listeners of the new child
UpdateableSubscriptionType[] eventTypes = {
UpdateableSubscriptionType.Child };
UpdateableSubscriptionType.CHILD };
updateManager.notifyListeners(eventTypes);
}
......
......@@ -318,18 +318,18 @@ public class FXShapeController extends ShapeController
// Listen only to new child events from the model
if (source == model) {
types.add(UpdateableSubscriptionType.Child);
types.add(UpdateableSubscriptionType.Selection);
types.add(UpdateableSubscriptionType.CHILD);
types.add(UpdateableSubscriptionType.SELECTION);
}
// Listen only to transformation events from the view
else if (source == view) {
types.add(UpdateableSubscriptionType.Transformation);
types.add(UpdateableSubscriptionType.TRANSFORMATION);
}
// For other objects, register for everything
else {
types.add(UpdateableSubscriptionType.All);
types.add(UpdateableSubscriptionType.ALL);
}
return types;
}
......
......@@ -442,7 +442,7 @@ public class FXShapeView extends AbstractView implements IWireFramePart {
// Notify listeners of the change
UpdateableSubscriptionType[] eventTypes = {
UpdateableSubscriptionType.Wireframe };
UpdateableSubscriptionType.WIREFRAME };
updateManager.notifyListeners(eventTypes);
}
......
......@@ -63,7 +63,7 @@ public class FXHeatExchangerController extends HeatExchangerController {
// Refresh the view, ignoring wireframe events from anything except this
// object's view
if (type[0] != UpdateableSubscriptionType.Wireframe
if (type[0] != UpdateableSubscriptionType.WIREFRAME
|| component == view) {
view.refresh(model);
}
......
......@@ -448,7 +448,7 @@ public class FXHeatExchangerView extends AbstractView
// Notify listeners of the change
UpdateableSubscriptionType[] eventTypes = {
UpdateableSubscriptionType.Wireframe };
UpdateableSubscriptionType.WIREFRAME };
updateManager.notifyListeners(eventTypes);
}
......
......@@ -71,7 +71,7 @@ public class FXPlantViewRootController extends AbstractController
// Fire update for the added child
UpdateableSubscriptionType[] eventTypes = new UpdateableSubscriptionType[] {
UpdateableSubscriptionType.Child };
UpdateableSubscriptionType.CHILD };
updateManager.notifyListeners(eventTypes);
}
......@@ -91,7 +91,7 @@ public class FXPlantViewRootController extends AbstractController
// Fire update for the added child
UpdateableSubscriptionType[] eventTypes = new UpdateableSubscriptionType[] {
UpdateableSubscriptionType.Child };
UpdateableSubscriptionType.CHILD };
updateManager.notifyListeners(eventTypes);
}
......
......@@ -67,8 +67,8 @@ public class FXVertexController extends VertexController {
// Only property or selection changes will change the view
for (UpdateableSubscriptionType type : types) {
if (type == UpdateableSubscriptionType.Property
|| type == UpdateableSubscriptionType.Selection) {
if (type == UpdateableSubscriptionType.PROPERTY
|| type == UpdateableSubscriptionType.SELECTION) {
view.refresh(model);
break;
}
......
......@@ -163,7 +163,7 @@ public class FXAttachment extends AbstractAttachment {
// Register to receive all updates
ArrayList<UpdateableSubscriptionType> types = new ArrayList<UpdateableSubscriptionType>();
types.add(UpdateableSubscriptionType.All);
types.add(UpdateableSubscriptionType.ALL);
return types;
}
});
......
......@@ -128,7 +128,7 @@ public class TestComponentListener
// Get all events
ArrayList<UpdateableSubscriptionType> subs = new ArrayList<UpdateableSubscriptionType>();
subs.add(UpdateableSubscriptionType.All);
subs.add(UpdateableSubscriptionType.ALL);
return subs;
}
......
......@@ -141,7 +141,7 @@ public class NekPolygonController extends FaceController implements IVizUpdateab
// Notify listeners of the change.
UpdateableSubscriptionType[] eventType = new UpdateableSubscriptionType[1];
eventType[0] = UpdateableSubscriptionType.Property;
eventType[0] = UpdateableSubscriptionType.PROPERTY;
updateManager.notifyListeners(eventType);
}
}
......@@ -199,7 +199,7 @@ public class NekPolygonController extends FaceController implements IVizUpdateab
// Notify listeners of the change.
UpdateableSubscriptionType[] eventType = new UpdateableSubscriptionType[1];
eventType[0] = UpdateableSubscriptionType.Property;
eventType[0] = UpdateableSubscriptionType.PROPERTY;
updateManager.notifyListeners(eventType);
}
}
......@@ -263,7 +263,7 @@ public class NekPolygonController extends FaceController implements IVizUpdateab
// Notify listeners of the change.
UpdateableSubscriptionType[] eventType = new UpdateableSubscriptionType[1];
eventType[0] = UpdateableSubscriptionType.Property;
eventType[0] = UpdateableSubscriptionType.PROPERTY;
updateManager.notifyListeners(eventType);
}
}
......@@ -368,7 +368,7 @@ public class NekPolygonController extends FaceController implements IVizUpdateab
// triggered by boundary conditions. Thus, this should trigger a
// Property type update for the part's own listeners
UpdateableSubscriptionType[] eventType = new UpdateableSubscriptionType[1];
eventType[0] = UpdateableSubscriptionType.Property;
eventType[0] = UpdateableSubscriptionType.PROPERTY;
updateManager.notifyListeners(eventType);
}
......
......@@ -42,17 +42,17 @@ public class UpdateableSubscriptionManagerTester {
// Create a listener for the object
ArrayList<UpdateableSubscriptionType> allList = new ArrayList<UpdateableSubscriptionType>();
allList.add(UpdateableSubscriptionType.All);
allList.add(UpdateableSubscriptionType.ALL);
TestListener listener = new TestListener(allList);
source.register(listener);
// Create a list containing the CHILD type
ArrayList<UpdateableSubscriptionType> list = new ArrayList<UpdateableSubscriptionType>();
list.add(UpdateableSubscriptionType.Child);
list.add(UpdateableSubscriptionType.CHILD);
// Create a list containing the PROPERTY type
ArrayList<UpdateableSubscriptionType> propertyList = new ArrayList<UpdateableSubscriptionType>();
propertyList.add(UpdateableSubscriptionType.Property);
propertyList.add(UpdateableSubscriptionType.PROPERTY);
// Check that the listener receives updates normally
source.sendUpdate(list);
......@@ -71,7 +71,61 @@ public class UpdateableSubscriptionManagerTester {
manager.flushQueue();
assertTrue(listener.gotChild());
// Check that every message
// Check that every message type is queued
manager.enqueue();
source.sendUpdate(propertyList);
source.sendUpdate(list);
manager.flushQueue();
assertTrue(listener.gotChild());
assertTrue(listener.gotProperty());
assertFalse(listener.gotAll());
// Check that the queue is not flushed until the manager receives a
// number of flush requests equal to the number of queue requests it has
// received
manager.enqueue();
manager.enqueue();
source.sendUpdate(propertyList);
assertFalse(listener.gotProperty());
// Flushing the queue once should not release the manager's messages
manager.flushQueue();
assertFalse(listener.gotProperty());
// Flushing it again should release them
manager.flushQueue();
assertTrue(listener.gotProperty());
// Add a parent manager
TestUpdateable parentSource = new TestUpdateable();
UpdateableSubscriptionManager parent = parentSource.getManager();
manager.setParent(parent);
// Create a listener for the object
TestListener parentListener = new TestListener(allList);
parentSource.register(parentListener);
// Queuing the child should block the parent's messages
manager.enqueue();
parentSource.sendUpdate(propertyList);
assertFalse(parentListener.gotProperty());
// Flushing the child should flush the parent
manager.flushQueue();
assertTrue(parentListener.gotProperty());
// Flushing the child should be equivalent to invoking flushQueue() on
// the parent once. Thus it should not automatically release the queued
// state if other queueing requests have come in.
parent.enqueue();
manager.enqueue();
parentSource.sendUpdate(propertyList);
manager.flushQueue();
assertFalse(parentListener.gotProperty());
// Releasing the parent's queue afterwards should send the messages
parent.flushQueue();
assertTrue(parentListener.gotProperty());
}
/**
......@@ -79,30 +133,31 @@ public class UpdateableSubscriptionManagerTester {
*/
@Test
public void checkMessageTypes() {
// Create an object to listen to
TestUpdateable source = new TestUpdateable();
// A list that specifies all subscription types
ArrayList<UpdateableSubscriptionType> allList = new ArrayList<UpdateableSubscriptionType>();
allList.add(UpdateableSubscriptionType.All);
allList.add(UpdateableSubscriptionType.ALL);
// A list that specifies the child and property subscription types
ArrayList<UpdateableSubscriptionType> childPropertyList = new ArrayList<UpdateableSubscriptionType>();
childPropertyList.add(UpdateableSubscriptionType.Child);
childPropertyList.add(UpdateableSubscriptionType.Property);
childPropertyList.add(UpdateableSubscriptionType.CHILD);
childPropertyList.add(UpdateableSubscriptionType.PROPERTY);
// A list that specifies the child and transformation subscription types
ArrayList<UpdateableSubscriptionType> childTransformationList = new ArrayList<UpdateableSubscriptionType>();
childTransformationList.add(UpdateableSubscriptionType.Child);
childTransformationList.add(UpdateableSubscriptionType.Property);
childTransformationList.add(UpdateableSubscriptionType.CHILD);
childTransformationList.add(UpdateableSubscriptionType.TRANSFORMATION);
// A list that specifies the child subscription type
ArrayList<UpdateableSubscriptionType> childList = new ArrayList<UpdateableSubscriptionType>();
childList.add(UpdateableSubscriptionType.Child);
childList.add(UpdateableSubscriptionType.CHILD);
// A list that specifies the property subscription type
ArrayList<UpdateableSubscriptionType> propertyList = new ArrayList<UpdateableSubscriptionType>();
propertyList.add(UpdateableSubscriptionType.Property);
propertyList.add(UpdateableSubscriptionType.PROPERTY);
// Create a listener that will receive all updates
TestListener listener = new TestListener(allList);
......@@ -110,6 +165,7 @@ public class UpdateableSubscriptionManagerTester {
// Create a listener that will only receive CHILD type updates
TestListener childListener = new TestListener(childList);
source.register(childListener);
// Send a child update and check that it was received.
source.sendUpdate(childList);
......@@ -139,25 +195,71 @@ public class UpdateableSubscriptionManagerTester {
assertFalse(childListener.gotProperty());
assertFalse(childListener.gotAll());
// Send child and property updates, and check that bother were received
// Send child and property updates, and check that both were received
source.sendUpdate(childPropertyList);
assertFalse(listener.gotChild());
assertTrue(listener.gotChild());
assertTrue(listener.gotProperty());
assertFalse(listener.gotAll());
assertFalse(childListener.gotChild());
assertTrue(childListener.gotChild());
assertFalse(childListener.gotProperty());
assertFalse(childListener.gotAll());
// Send an ALL update, and check that nothing was received, as ALL is
// not a valid type for a message to send.
source.sendUpdate(allList);
assertFalse(listener.gotChild());
}
/**
* Check that listeners are registered and unregistered correctly.
*/
@Test
public void checkRegistration() {
// Create an object to listen to
TestUpdateable source = new TestUpdateable();
// A list that specifies the property subscription type
ArrayList<UpdateableSubscriptionType> propertyList = new ArrayList<UpdateableSubscriptionType>();
propertyList.add(UpdateableSubscriptionType.PROPERTY);
// Create two listeners that will receive property updates
TestListener listener = new TestListener(propertyList);
source.register(listener);
// Check that the listener receives updates
source.sendUpdate(propertyList);
assertTrue(listener.gotProperty());
// Remove the listener and check that it no longer receives updates
source.unregister(listener);
source.sendUpdate(propertyList);
assertFalse(listener.gotProperty());
assertFalse(listener.gotAll());
assertFalse(childListener.gotChild());
assertFalse(childListener.gotProperty());
assertFalse(childListener.gotAll());
// Add two listeners and check that both receive updates
TestListener listener2 = new TestListener(propertyList);
source.register(listener);
source.register(listener2);
source.sendUpdate(propertyList);
assertTrue(listener.gotProperty());
assertTrue(listener2.gotProperty());
// Remove them both and check that neither receives updates
source.unregister(listener);
source.unregister(listener2);
source.sendUpdate(propertyList);
assertFalse(listener.gotProperty());
assertFalse(listener2.gotProperty());
// Check that listeners are notified based on the manager's state at the
// time the queue is flushed, rather than when messages are sent
source.register(listener);
source.register(listener2);
source.getManager().enqueue();
source.sendUpdate(propertyList);
source.unregister(listener);
source.getManager().flushQueue();
// Listener2 should have received the update. Listener, which was
// unregistered before the queue was flushed, should not
assertFalse(listener.gotProperty());
assertTrue(listener2.gotProperty());
}
/**
......@@ -229,15 +331,15 @@ public class UpdateableSubscriptionManagerTester {
// true if it matches one of the checked types
for (UpdateableSubscriptionType type : types) {
if (type == UpdateableSubscriptionType.Property) {
if (type == UpdateableSubscriptionType.PROPERTY) {
propertyNotified = true;
}
else if (type == UpdateableSubscriptionType.Child) {
else if (type == UpdateableSubscriptionType.CHILD) {
childNotified = true;
}
else if (type == UpdateableSubscriptionType.All) {
else if (type == UpdateableSubscriptionType.ALL) {
allNotified = true;
}
}
......@@ -255,7 +357,7 @@ public class UpdateableSubscriptionManagerTester {
public boolean gotAll() {
boolean temp = allNotified;
allNotified = false;
return allNotified;
return temp;
}
/**
......@@ -270,7 +372,7 @@ public class UpdateableSubscriptionManagerTester {
public boolean gotChild() {
boolean temp = childNotified;
childNotified = false;
return childNotified;
return temp;
}
/**
......@@ -285,7 +387,7 @@ public class UpdateableSubscriptionManagerTester {
public boolean gotProperty() {
boolean temp = propertyNotified;
propertyNotified = false;
return propertyNotified;
return temp;
}
}
......@@ -315,8 +417,12 @@ public class UpdateableSubscriptionManagerTester {
}
public void sendUpdate(ArrayList<UpdateableSubscriptionType> types) {
manager.notifyListeners(
(UpdateableSubscriptionType[]) types.toArray());
// Convert the array list to an array and send it to the manager
UpdateableSubscriptionType[] temp = new UpdateableSubscriptionType[types
.size()];
temp = types.toArray(temp);
manager.notifyListeners(temp);
}
/*
......
......@@ -13,6 +13,7 @@
package org.eclipse.ice.viz.service.datastructures.VizObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
/**
......@@ -150,6 +151,18 @@ public class UpdateableSubscriptionManager {
// If not in queue mode, notify the listeners
else {
// A map from a temporary identification number to the listener
// associated with it
HashMap<Integer, IManagedUpdateableListener> listenerMap = new HashMap<Integer, IManagedUpdateableListener>();
// A map from a temporary identification number to the a list of
// subscription types
HashMap<Integer, ArrayList<UpdateableSubscriptionType>> messageMap = new HashMap<Integer, ArrayList<UpdateableSubscriptionType>>();
// The next ID number to use when a new listener is encountered in
// the below search
int nextID = 0;
// Check each event type with registered listeners in the map
for (UpdateableSubscriptionType listenerType : subscriptionMap
.keySet()) {
......@@ -158,7 +171,7 @@ public class UpdateableSubscriptionManager {
boolean match = false;
// Listeners for all events are automatically updated
if (listenerType == UpdateableSubscriptionType.All) {
if (listenerType == UpdateableSubscriptionType.ALL) {
match = true;
}
......@@ -166,7 +179,8 @@ public class UpdateableSubscriptionManager {
// Check each event type to see if one matches
for (UpdateableSubscriptionType eventType : eventTypes) {
if (listenerType == eventType) {
if (listenerType == eventType
&& eventType != UpdateableSubscriptionType.ALL) {
match = true;
break;
}
......@@ -180,15 +194,69 @@ public class UpdateableSubscriptionManager {
ArrayList<IManagedUpdateableListener> listeners = subscriptionMap
.get(listenerType);
// Update each listener, providing event types if it can
// handle that kind of input
// Place each listener and the correct event types in the
// maps, assigning each a temporary matching ID.
for (IManagedUpdateableListener listener : listeners) {
listener.update(source, eventTypes);
// If the listener is already in the map...
if (listenerMap.containsValue(listener)) {
// Search for the ID value for the listener
for (Integer i : listenerMap.keySet()) {
// When a match is found, add the new type to
// the map of messages for that ID
if (listenerMap.get(i) == listener) {
ArrayList<UpdateableSubscriptionType> list = messageMap
.get(i);
list.add(listenerType);
messageMap.put(i, list);
}
}
}
// If the listener is not already in the map, place it
// there
else {
// Put the listener in the listener map
listenerMap.put(nextID, listener);
// Create a list of subscription types
ArrayList<UpdateableSubscriptionType> list;
// If the type isn't ALL, initialize the list with
// the current message type
if (listenerType != UpdateableSubscriptionType.ALL) {
list = new ArrayList<UpdateableSubscriptionType>();