Commit da2b637f authored by Robert Smith's avatar Robert Smith
Browse files

Began work on notification management system



Created a class to manage observer pattern notifications, filtering them
based on which event type each listener is subscribed to receive.
Signed-off-by: Robert Smith's avatarRobert Smith <SmithRW@ornl.gov>
parent c9529b0e
......@@ -11,6 +11,7 @@
package org.eclipse.ice.viz.service.geometry.shapes;
import org.eclipse.ice.viz.service.datastructures.VizObject.IVizUpdateable;
import org.eclipse.ice.viz.service.datastructures.VizObject.UpdateableSubscription;
import org.eclipse.ice.viz.service.javafx.internal.Util;
import org.eclipse.ice.viz.service.javafx.internal.scene.TransformGizmo;
import org.eclipse.ice.viz.service.modeling.AbstractController;
......@@ -298,7 +299,8 @@ public class FXShapeView extends AbstractView {
}
// Notify own listeners of the change
notifyListeners();
UpdateableSubscription[] eventTypes = {UpdateableSubscription.All};
updateManager.notifyListeners(eventTypes);;
}
}
......@@ -11,6 +11,7 @@
package org.eclipse.ice.viz.service.mesh.datastructures;
import org.eclipse.ice.viz.service.datastructures.VizObject.IVizUpdateable;
import org.eclipse.ice.viz.service.datastructures.VizObject.UpdateableSubscription;
import org.eclipse.ice.viz.service.javafx.internal.Util;
import org.eclipse.ice.viz.service.modeling.AbstractController;
import org.eclipse.ice.viz.service.modeling.AbstractMeshComponent;
......@@ -227,6 +228,7 @@ public class FXLinearEdgeView extends AbstractView {
}
// Notify own listeners of the change
notifyListeners();
UpdateableSubscription[] eventTypes = {UpdateableSubscription.All};
updateManager.notifyListeners(eventTypes);
}
}
......@@ -11,6 +11,7 @@
package org.eclipse.ice.viz.service.mesh.datastructures;
import org.eclipse.ice.viz.service.datastructures.VizObject.IVizUpdateable;
import org.eclipse.ice.viz.service.datastructures.VizObject.UpdateableSubscription;
import org.eclipse.ice.viz.service.javafx.internal.Util;
import org.eclipse.ice.viz.service.modeling.AbstractController;
import org.eclipse.ice.viz.service.modeling.AbstractMeshComponent;
......@@ -192,6 +193,7 @@ public class FXVertexView extends AbstractView {
}
// Notify own listeners of the change
notifyListeners();
UpdateableSubscription[] eventTypes = {UpdateableSubscription.All};
updateManager.notifyListeners(eventTypes);
}
}
/*******************************************************************************
* Copyright (c) 2011, 2014, 2015 UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Initial API and implementation and/or initial documentation - Jay Jay
* Billings
*******************************************************************************/
package org.eclipse.ice.viz.service.datastructures.VizObject;
import java.util.ArrayList;
/**
* An extension of IVizUpdateableListener which can receive the type of event that triggered the update.
*
* @author Robert Smith
*
*/
public interface IManagedVizUpdateableListener extends IVizUpdateableListener{
/**
* Receive an update, including the source component and type of event that triggered the update.
*
* @param component The updateable component the update is coming from
* @param type The event type that of the update
*/
public void update(IVizUpdateable component, UpdateableSubscription[] type);
}
/*******************************************************************************
* Copyright (c) 2013, 2014 UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Robert Smith
*******************************************************************************/
package org.eclipse.ice.viz.service.datastructures.VizObject;
/**
* A enumeration of the types of events for which an IVizUpdateableListener can
* subscribe to listen for.
*
* @author r8s
*
*/
public enum UpdateableSubscription {
/**
* A special value denoting that a listener should be update upon any kind
* of event.
*/
All,
/**
* Selection events are fired when an object is selected or deselected.
*/
Selection,
/**
* Property events are fired when an object's properties are changed,
* disregarding properties which are covered by another event type on this
* list.
*/
Property,
/**
* Child events are fired when an object has a child object added or removed from it.
*/
Child,
/**
* Transformation events are fired when an object's graphical transformation is changed.
*/
Transformation,
/**
* Location events are fired when an object moves.
*/
Location,
/**
* Boundary events are fired when an object's boundary conditions are changed.
*/
Boundary
}
/*******************************************************************************
* Copyright (c) 2015 UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Initial API and implementation and/or initial documentation - Jay Jay Billings,
* Jordan H. Deyton, Dasha Gorin, Alexander J. McCaskey, Taylor Patterson,
* Claire Saunders, Matthew Wang, Anna Wojtowicz
*******************************************************************************/
package org.eclipse.ice.viz.service.datastructures.VizObject;
import java.util.ArrayList;
import java.util.HashMap;
/**
* A class which manages a list of IVizUpdateable listeners and filters updates
* by matching types of events to listeners which have subscribed to the
* corresponding event type(s).
*
* @author Robert Smith
*
*/
public class UpdateableSubscriptionManager {
/**
* The updateable object the manager is controlling the message passing for.
*/
IVizUpdateable source;
/**
* A map of registered listeners associated with the event types they are registered to receive.
*/
HashMap<IVizUpdateableListener, ArrayList<UpdateableSubscription>> subscriptionMap;
/**
* The default constructor.
*
* @param source The object whose listeners this manager will control communications for.
*/
public UpdateableSubscriptionManager(IVizUpdateable source){
this.source = source;
}
/**
* Send an update to each listener
*
* @param source
* @param eventTypes
*/
public void notifyListeners(UpdateableSubscription[] eventTypes){
//Check each listener in the map
for(IVizUpdateableListener listener :subscriptionMap.keySet()){
//Get the event types the listener is subscribed for.
ArrayList<UpdateableSubscription> types = subscriptionMap.get(listener);
//If the listener is subscribed for all events, fire an update
if(types.contains(UpdateableSubscription.All)){
listener.update(source);
}
else{
//Check each of the types for the event. If any match, fire the update
for(UpdateableSubscription type : eventTypes){
if(type == UpdateableSubscription.All || types.contains(type)){
listener.update(source);
break;
}
}
}
}
}
/**
* Register a listener to receive updates from the given lift of event types.
*
* @param listener The listener which is being registered
* @param types The list of event types the listener will receive
*/
public void register(IVizUpdateableListener listener, ArrayList<UpdateableSubscription> types){
subscriptionMap.put(listener, types);
}
/**
* Unregister a listener so that it will receive no new updates.
*
* @param listener The listener to be unregistered
*/
public void unregister(IVizUpdateableListener listener){
subscriptionMap.remove(listener);
}
}
......@@ -17,8 +17,11 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.ice.viz.service.datastructures.VizObject.IManagedVizUpdateableListener;
import org.eclipse.ice.viz.service.datastructures.VizObject.IVizUpdateable;
import org.eclipse.ice.viz.service.datastructures.VizObject.IVizUpdateableListener;
import org.eclipse.ice.viz.service.datastructures.VizObject.UpdateableSubscription;
import org.eclipse.ice.viz.service.datastructures.VizObject.UpdateableSubscriptionManager;
/**
* A component of the model. All models are built from collections of components
......@@ -28,7 +31,7 @@ import org.eclipse.ice.viz.service.datastructures.VizObject.IVizUpdateableListen
* @author Robert Smith
*/
public class AbstractMeshComponent
implements IVizUpdateableListener, IVizUpdateable {
implements IManagedVizUpdateableListener, IVizUpdateable {
/**
* The mesh's type, which defines how the part internally stores its data.
......@@ -54,7 +57,7 @@ public class AbstractMeshComponent
/**
* The listeners registered for updates from this object.
*/
private List<IVizUpdateableListener> listeners;
protected UpdateableSubscriptionManager updateManager;
/**
* The controller which manages this component
......@@ -78,7 +81,7 @@ public class AbstractMeshComponent
properties = new HashMap<String, String>();
type = MeshType.SIMPLE;
updateLock = new AtomicBoolean();
listeners = new ArrayList<IVizUpdateableListener>();
updateManager = new UpdateableSubscriptionManager(this);
notifyLock = new AtomicBoolean();
}
......@@ -115,7 +118,7 @@ public class AbstractMeshComponent
properties = new HashMap<String, String>();
type = MeshType.SIMPLE;
updateLock = new AtomicBoolean();
listeners = new ArrayList<IVizUpdateableListener>();
updateManager = new UpdateableSubscriptionManager(this);
}
/**
......@@ -137,7 +140,7 @@ public class AbstractMeshComponent
properties = new HashMap<String, String>();
this.type = type;
updateLock = new AtomicBoolean();
listeners = new ArrayList<IVizUpdateableListener>();
updateManager = new UpdateableSubscriptionManager(this);
}
/**
......@@ -195,44 +198,10 @@ public class AbstractMeshComponent
*/
public void setType(MeshType type) {
this.type = type;
notifyListeners();
UpdateableSubscription[] eventTypes = {UpdateableSubscription.Property};
updateManager.notifyListeners(eventTypes);
}
/**
* Send a notification to all listeners.
*/
public void notifyListeners() {
if (!notifyLock.get()) {
// If the listeners are empty, return
if (this.listeners == null || this.listeners.isEmpty()) {
return;
}
// Get a reference to self
final AbstractMeshComponent self = this;
final List<IVizUpdateableListener> localListeners = new ArrayList<IVizUpdateableListener>(
listeners);
// // Create a thread object that notifies all listeners
//
// Thread notifyThread = new Thread() {
//
// @Override
// public void run() {
// Loop over all listeners and update them
for (int i = 0; i < localListeners.size(); i++) {
localListeners.get(i).update(self);
}
// }
// };
//
// // Start the thread
// notifyThread.start();
}
}
/**
* Returns a list of all related entities.
......@@ -289,7 +258,8 @@ public class AbstractMeshComponent
notifyLock.set(true);
properties.put(property, value);
notifyLock.set(false);
notifyListeners();
UpdateableSubscription[] eventTypes = {UpdateableSubscription.Property};
updateManager.notifyListeners(eventTypes);
}
/**
......@@ -339,7 +309,8 @@ public class AbstractMeshComponent
notifyLock.set(false);
if (found) {
notifyListeners();
UpdateableSubscription[] eventTypes = {UpdateableSubscription.Child};
updateManager.notifyListeners(eventTypes);
}
}
......@@ -375,7 +346,8 @@ public class AbstractMeshComponent
// Send notification that entities have been changed
notifyLock.set(false);
notifyListeners();
UpdateableSubscription[] eventTypes = {UpdateableSubscription.Child};
updateManager.notifyListeners(eventTypes);
}
/*
......@@ -399,10 +371,9 @@ public class AbstractMeshComponent
*/
@Override
public void register(IVizUpdateableListener listener) {
if (listener != null && !listeners.contains(listener)) {
listeners.add(listener);
}
ArrayList<UpdateableSubscription> eventTypes = new ArrayList<UpdateableSubscription>();
eventTypes.add(UpdateableSubscription.All);
updateManager.register(listener, eventTypes);
}
......@@ -415,7 +386,7 @@ public class AbstractMeshComponent
*/
@Override
public void unregister(IVizUpdateableListener listener) {
listeners.remove(listener);
updateManager.unregister(listener);
}
......@@ -430,9 +401,28 @@ public class AbstractMeshComponent
public void update(IVizUpdateable component) {
// Notify own listeners that an update has occurred.
notifyListeners();
UpdateableSubscription[] eventTypes = {UpdateableSubscription.All};
updateManager.notifyListeners(eventTypes);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ice.viz.service.datastructures.VizObject.
* IManagedVizUpdateableListener#update(org.eclipse.ice.viz.service.
* datastructures.VizObject.IVizUpdateable,
* org.eclipse.ice.viz.service.datastructures.VizObject.
* UpdateableSubscription)
*/
@Override
public void update(IVizUpdateable component, UpdateableSubscription[] type) {
// Pass the update to own listeners
updateManager.notifyListeners(type);
}
/*
* (non-Javadoc)
*
......@@ -460,7 +450,8 @@ public class AbstractMeshComponent
properties = new HashMap<String, String>(otherObject.properties);
// Notify listeners of the change
notifyListeners();
UpdateableSubscription[] eventTypes = {UpdateableSubscription.All};
updateManager.notifyListeners(eventTypes);
}
/**
......@@ -481,4 +472,5 @@ public class AbstractMeshComponent
public void setController(AbstractController controller) {
this.controller = controller;
}
}
......@@ -12,8 +12,11 @@ package org.eclipse.ice.viz.service.modeling;
import java.util.ArrayList;
import org.eclipse.ice.viz.service.datastructures.VizObject.IManagedVizUpdateableListener;
import org.eclipse.ice.viz.service.datastructures.VizObject.IVizUpdateable;
import org.eclipse.ice.viz.service.datastructures.VizObject.IVizUpdateableListener;
import org.eclipse.ice.viz.service.datastructures.VizObject.UpdateableSubscription;
import org.eclipse.ice.viz.service.datastructures.VizObject.UpdateableSubscriptionManager;
/**
* The view of an AbstractMeshComponent shown to the user. The view is
......@@ -23,7 +26,7 @@ import org.eclipse.ice.viz.service.datastructures.VizObject.IVizUpdateableListen
*
* @author Robert Smith
*/
public class AbstractView implements IVizUpdateableListener, IVizUpdateable {
public class AbstractView implements IManagedVizUpdateableListener, IVizUpdateable {
/**
* The transformation representing the part's intended state. This may not
......@@ -41,6 +44,11 @@ public class AbstractView implements IVizUpdateableListener, IVizUpdateable {
* The list of listeners observing this object.
*/
private ArrayList<IVizUpdateableListener> listeners;
/**
* The listeners registered for updates from this object.
*/
protected UpdateableSubscriptionManager updateManager;
/**
* The default constructor.
......@@ -77,38 +85,39 @@ public class AbstractView implements IVizUpdateableListener, IVizUpdateable {
update(transformation);
// Notify own listeners of the change
notifyListeners();
UpdateableSubscription[] eventTypes = {UpdateableSubscription.Transformation};
updateManager.notifyListeners(eventTypes);
}
/**
* Notify all listeners of an update.
*/
public void notifyListeners() {
// If the listeners are empty, return
if (this.listeners == null || this.listeners.isEmpty()) {
return;
}
// Get a reference to self
final AbstractView self = this;
// // Create a thread object that notifies all listeners
//
// Thread notifyThread = new Thread() {
//
// @Override
// public void run() {
// Loop over all listeners and update them
for (int i = 0; i < listeners.size(); i++) {
listeners.get(i).update(self);
}
// }
// };
//
// // Start the thread
// notifyThread.start();
}
// /**
// * Notify all listeners of an update.
// */
// public void notifyListeners() {
//
// // If the listeners are empty, return
// if (this.listeners == null || this.listeners.isEmpty()) {
// return;
// }
//
// // Get a reference to self
// final AbstractView self = this;
//
// // // Create a thread object that notifies all listeners
// //
// // Thread notifyThread = new Thread() {
// //
// // @Override
// // public void run() {
// // Loop over all listeners and update them
// for (int i = 0; i < listeners.size(); i++) {
// listeners.get(i).update(self);
// }
// // }
// // };
// //
// // // Start the thread
// // notifyThread.start();
// }
/**
* Getter for the part's previous transformation.
......@@ -197,7 +206,22 @@ public class AbstractView implements IVizUpdateableListener, IVizUpdateable {
*/
@Override
public void update(IVizUpdateable component) {
notifyListeners();
// Notify own listeners of the change
UpdateableSubscription[] eventTypes = {UpdateableSubscription.All};
updateManager.notifyListeners(eventTypes);
}
/*
* (non-Javadoc)
* @see org.eclipse.ice.viz.service.datastructures.VizObject.IManagedVizUpdateableListener#update(org.eclipse.ice.viz.service.datastructures.VizObject.IVizUpdateable, org.eclipse.ice.viz.service.datastructures.VizObject.UpdateableSubscription[])
*/
@Override
public void update(IVizUpdateable component, UpdateableSubscription[] type) {
// Pass the update to own listeners
updateManager.notifyListeners(type);
}
......@@ -223,7 +247,8 @@ public class AbstractView implements IVizUpdateableListener, IVizUpdateable {
previousTransformation = (Transformation) otherObject.previousTransformation
.clone();
// Notify listeners of the change
notifyListeners();
// Notify own listeners of the change
UpdateableSubscription[] eventTypes = {UpdateableSubscription.All};
updateManager.notifyListeners(eventTypes);
}
}
......@@ -13,6 +13,8 @@ package org.eclipse.ice.viz.service.modeling;
import java.util.ArrayList;