Merge "Issue #1638 Fixed localization feature dependencies. Updated plugin data object resource to be thread safe. Moved common legend operations to DefaultLegendResource." into development
Former-commit-id:c7868a028e
[formerly9a3f855a1a
] [formerly39543d7ee0
] [formerly6ef214f1b8
[formerly39543d7ee0
[formerly 75de1f5405d24d0eb63d366c4da73a56f4c9d947]]] Former-commit-id:6ef214f1b8
Former-commit-id: 45406f4e5394c5620f8f9c11ae40ea432dc3982e [formerlyffa74c3bdb
] Former-commit-id:7f58e8a568
This commit is contained in:
commit
8ff1aae296
4 changed files with 344 additions and 95 deletions
|
@ -27,6 +27,7 @@ import org.eclipse.jface.action.IMenuManager;
|
||||||
|
|
||||||
import com.raytheon.uf.viz.core.DrawableString;
|
import com.raytheon.uf.viz.core.DrawableString;
|
||||||
import com.raytheon.uf.viz.core.IDisplayPane;
|
import com.raytheon.uf.viz.core.IDisplayPane;
|
||||||
|
import com.raytheon.uf.viz.core.IDisplayPaneContainer;
|
||||||
import com.raytheon.uf.viz.core.IExtent;
|
import com.raytheon.uf.viz.core.IExtent;
|
||||||
import com.raytheon.uf.viz.core.IGraphicsTarget;
|
import com.raytheon.uf.viz.core.IGraphicsTarget;
|
||||||
import com.raytheon.uf.viz.core.drawables.IDescriptor;
|
import com.raytheon.uf.viz.core.drawables.IDescriptor;
|
||||||
|
@ -37,10 +38,12 @@ import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
import com.raytheon.uf.viz.core.legend.ILegendDecorator;
|
import com.raytheon.uf.viz.core.legend.ILegendDecorator;
|
||||||
import com.raytheon.uf.viz.core.rsc.AbstractResourceData;
|
import com.raytheon.uf.viz.core.rsc.AbstractResourceData;
|
||||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||||
|
import com.raytheon.uf.viz.core.rsc.IInputHandler.InputPriority;
|
||||||
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
||||||
import com.raytheon.uf.viz.core.rsc.RenderingOrderFactory.ResourceOrder;
|
import com.raytheon.uf.viz.core.rsc.RenderingOrderFactory.ResourceOrder;
|
||||||
import com.raytheon.viz.ui.cmenu.ContextMenuManager;
|
import com.raytheon.viz.ui.cmenu.ContextMenuManager;
|
||||||
import com.raytheon.viz.ui.cmenu.IContextMenuProvider;
|
import com.raytheon.viz.ui.cmenu.IContextMenuProvider;
|
||||||
|
import com.raytheon.viz.ui.input.InputAdapter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base legend resource class, does majority of work for drawing legends.
|
* Base legend resource class, does majority of work for drawing legends.
|
||||||
|
@ -68,6 +71,56 @@ public abstract class AbstractLegendResource<T extends AbstractResourceData>
|
||||||
|
|
||||||
private static final int RIGHT_OFFSET_IN_PIXELS = 18;
|
private static final int RIGHT_OFFSET_IN_PIXELS = 18;
|
||||||
|
|
||||||
|
private InputAdapter resourceClickedHandler = new InputAdapter() {
|
||||||
|
|
||||||
|
private boolean moved = false;
|
||||||
|
|
||||||
|
private ResourcePair mouseDownRsc;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMouseDown(int x, int y, int mouseButton) {
|
||||||
|
boolean handle = moved = false;
|
||||||
|
IDisplayPaneContainer container = getResourceContainer();
|
||||||
|
IDisplayPane active = container.getActiveDisplayPane();
|
||||||
|
if (active.getDescriptor() == getDescriptor()) {
|
||||||
|
mouseDownRsc = checkLabelSpace(getDescriptor(),
|
||||||
|
active.getTarget(), x, y);
|
||||||
|
if (mouseDownRsc != null) {
|
||||||
|
handle = AbstractLegendResource.this.checkResourceClick(
|
||||||
|
mouseDownRsc, mouseButton);
|
||||||
|
if (!handle) {
|
||||||
|
mouseDownRsc = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMouseDownMove(int x, int y, int mouseButton) {
|
||||||
|
if (mouseDownRsc != null) {
|
||||||
|
moved = true;
|
||||||
|
}
|
||||||
|
return moved;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handleMouseUp(int x, int y, int mouseButton) {
|
||||||
|
if (mouseDownRsc != null) {
|
||||||
|
try {
|
||||||
|
if (!moved) {
|
||||||
|
resourceClicked(mouseDownRsc, mouseButton);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
mouseDownRsc = null;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resourceData
|
* @param resourceData
|
||||||
* @param loadProperties
|
* @param loadProperties
|
||||||
|
@ -84,7 +137,10 @@ public abstract class AbstractLegendResource<T extends AbstractResourceData>
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void disposeInternal() {
|
protected void disposeInternal() {
|
||||||
|
IDisplayPaneContainer container = getResourceContainer();
|
||||||
|
if (container != null) {
|
||||||
|
container.unregisterMouseHandler(resourceClickedHandler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -148,7 +204,11 @@ public abstract class AbstractLegendResource<T extends AbstractResourceData>
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void initInternal(IGraphicsTarget target) throws VizException {
|
protected void initInternal(IGraphicsTarget target) throws VizException {
|
||||||
|
IDisplayPaneContainer container = getResourceContainer();
|
||||||
|
if (container != null) {
|
||||||
|
container.registerMouseHandler(resourceClickedHandler,
|
||||||
|
InputPriority.SYSTEM_RESOURCE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ResourcePair checkLabelSpace(IDescriptor descriptor,
|
protected ResourcePair checkLabelSpace(IDescriptor descriptor,
|
||||||
|
@ -289,4 +349,14 @@ public abstract class AbstractLegendResource<T extends AbstractResourceData>
|
||||||
ContextMenuManager.fillContextMenu(menuManager, selectedResource,
|
ContextMenuManager.fillContextMenu(menuManager, selectedResource,
|
||||||
getResourceContainer());
|
getResourceContainer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean checkResourceClick(ResourcePair mouseDownRsc,
|
||||||
|
int mouseButton) {
|
||||||
|
// Do nothing
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void resourceClicked(ResourcePair resource, int mouseButton) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,10 +30,16 @@ import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||||
import com.raytheon.uf.viz.core.rsc.GenericResourceData;
|
import com.raytheon.uf.viz.core.rsc.GenericResourceData;
|
||||||
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
||||||
import com.raytheon.uf.viz.core.rsc.ResourceList;
|
import com.raytheon.uf.viz.core.rsc.ResourceList;
|
||||||
|
import com.raytheon.uf.viz.core.rsc.capabilities.BlendableCapability;
|
||||||
|
import com.raytheon.uf.viz.core.rsc.capabilities.BlendedCapability;
|
||||||
import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability;
|
import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability;
|
||||||
|
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
|
||||||
|
import com.raytheon.viz.ui.input.EditableManager;
|
||||||
|
import com.raytheon.viz.ui.input.preferences.MousePreferenceManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO Add Description
|
* Default legend resource, handles visibility toggling and editableness
|
||||||
|
* toggling. TODO: Make D2DLegendResource extend it
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
|
@ -52,6 +58,13 @@ import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability;
|
||||||
public class DefaultLegendResource extends
|
public class DefaultLegendResource extends
|
||||||
AbstractLegendResource<GenericResourceData> {
|
AbstractLegendResource<GenericResourceData> {
|
||||||
|
|
||||||
|
private static final String HIDE_RESOURCE_PREF = "com.raytheon.viz.d2d.ui.hide.resource";
|
||||||
|
|
||||||
|
private static final String EDIT_RESOURCE_PREF = "com.raytheon.viz.ui.input.resource.edit";
|
||||||
|
|
||||||
|
private MousePreferenceManager prefManager = MousePreferenceManager
|
||||||
|
.getInstance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resourceData
|
* @param resourceData
|
||||||
* @param loadProperties
|
* @param loadProperties
|
||||||
|
@ -94,6 +107,12 @@ public class DefaultLegendResource extends
|
||||||
} else {
|
} else {
|
||||||
legend.label = rsc.getName();
|
legend.label = rsc.getName();
|
||||||
legend.resource = resourcePair;
|
legend.resource = resourcePair;
|
||||||
|
|
||||||
|
if (rsc.hasCapability(EditableCapability.class)
|
||||||
|
&& rsc.getCapability(EditableCapability.class)
|
||||||
|
.isEditable()) {
|
||||||
|
legend.label += " (Editable)";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vis) {
|
if (!vis) {
|
||||||
|
@ -115,4 +134,82 @@ public class DefaultLegendResource extends
|
||||||
}
|
}
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean checkResourceClick(ResourcePair mouseDownRsc,
|
||||||
|
int mouseButton) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void resourceClicked(ResourcePair resource, int mouseButton) {
|
||||||
|
if (prefManager.handleClick(EDIT_RESOURCE_PREF, mouseButton)
|
||||||
|
&& resource.getResource().hasCapability(
|
||||||
|
EditableCapability.class)) {
|
||||||
|
// Editable case
|
||||||
|
toggleEditability(resource);
|
||||||
|
} else {
|
||||||
|
// Visibility case
|
||||||
|
toggleVisibility(resource);
|
||||||
|
}
|
||||||
|
issueRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle visibility of resource taking blended/blendable resources into
|
||||||
|
* account.
|
||||||
|
*
|
||||||
|
* If resource to toggle is blended, 1st check to see if parent resource is
|
||||||
|
* visible. If not visible then make parent and all children visible.
|
||||||
|
*
|
||||||
|
* @param rp
|
||||||
|
*/
|
||||||
|
protected boolean toggleVisibility(ResourcePair rp) {
|
||||||
|
AbstractVizResource<?, ?> rsc = rp.getResource();
|
||||||
|
if (rsc != null) {
|
||||||
|
if (rsc.hasCapability(BlendedCapability.class)) {
|
||||||
|
ResourcePair parentRsc = rsc.getCapability(
|
||||||
|
BlendedCapability.class).getBlendableResource();
|
||||||
|
ResourceList children = parentRsc.getResource()
|
||||||
|
.getCapability(BlendableCapability.class)
|
||||||
|
.getResourceList();
|
||||||
|
if (parentRsc.getProperties().isVisible() == false) {
|
||||||
|
parentRsc.getProperties().setVisible(true);
|
||||||
|
for (ResourcePair child : children) {
|
||||||
|
child.getProperties().setVisible(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// topmost resource is visible, toggle us and other
|
||||||
|
// rsc
|
||||||
|
if (rp.getProperties().isVisible() == false) {
|
||||||
|
rp.getProperties().setVisible(true);
|
||||||
|
parentRsc
|
||||||
|
.getResource()
|
||||||
|
.getCapability(BlendableCapability.class)
|
||||||
|
.setAlphaStep(BlendableCapability.BLEND_MAX / 2);
|
||||||
|
} else {
|
||||||
|
parentRsc.getResource()
|
||||||
|
.getCapability(BlendableCapability.class)
|
||||||
|
.toggle(rp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rp.getProperties().isVisible();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rp.getProperties().setVisible(!rp.getProperties().isVisible());
|
||||||
|
return rp.getProperties().isVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the editable flag on the resource
|
||||||
|
*
|
||||||
|
* @param rp
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected boolean toggleEditability(ResourcePair rp) {
|
||||||
|
EditableManager.makeEditable(rp.getResource(), !rp.getResource()
|
||||||
|
.getCapability(EditableCapability.class).isEditable());
|
||||||
|
return rp.getResource().getCapability(EditableCapability.class)
|
||||||
|
.isEditable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ package com.raytheon.uf.viz.core.rsc;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -58,14 +57,48 @@ public abstract class AbstractPluginDataObjectResource<T extends AbstractResourc
|
||||||
extends AbstractVizResource<T, D> {
|
extends AbstractVizResource<T, D> {
|
||||||
|
|
||||||
private static class Frame {
|
private static class Frame {
|
||||||
|
boolean disposed = false;
|
||||||
|
|
||||||
|
Object lock = new Object();
|
||||||
|
|
||||||
List<PluginDataObject> records = new ArrayList<PluginDataObject>();
|
List<PluginDataObject> records = new ArrayList<PluginDataObject>();
|
||||||
|
|
||||||
IRenderable renderable;
|
IRenderable renderable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<DataTime, Frame> frames = new HashMap<DataTime, Frame>();
|
private IResourceDataChanged dataChangedListener = new IResourceDataChanged() {
|
||||||
|
@Override
|
||||||
|
public void resourceChanged(ChangeType type, Object object) {
|
||||||
|
if (type == ChangeType.DATA_UPDATE) {
|
||||||
|
if (object instanceof PluginDataObject) {
|
||||||
|
addDataObject((PluginDataObject) object);
|
||||||
|
} else if (object instanceof PluginDataObject[]) {
|
||||||
|
addDataObject((PluginDataObject[]) object);
|
||||||
|
} else if (object instanceof Object[]) {
|
||||||
|
List<PluginDataObject> pdos = new ArrayList<PluginDataObject>();
|
||||||
|
for (Object obj : (Object[]) object) {
|
||||||
|
if (obj instanceof PluginDataObject) {
|
||||||
|
pdos.add((PluginDataObject) obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pdos.size() > 0) {
|
||||||
|
addDataObject(pdos.toArray(new PluginDataObject[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (type == ChangeType.CAPABILITY) {
|
||||||
|
if (object instanceof AbstractCapability) {
|
||||||
|
AbstractCapability capability = (AbstractCapability) object;
|
||||||
|
for (Frame frame : frames.values()) {
|
||||||
|
if (frame.renderable != null) {
|
||||||
|
capabilityChanged(frame.renderable, capability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private Object lock = new Object();
|
private Map<DataTime, Frame> frames = new HashMap<DataTime, Frame>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resourceData
|
* @param resourceData
|
||||||
|
@ -75,35 +108,6 @@ public abstract class AbstractPluginDataObjectResource<T extends AbstractResourc
|
||||||
LoadProperties loadProperties) {
|
LoadProperties loadProperties) {
|
||||||
super(resourceData, loadProperties);
|
super(resourceData, loadProperties);
|
||||||
dataTimes = new ArrayList<DataTime>();
|
dataTimes = new ArrayList<DataTime>();
|
||||||
resourceData.addChangeListener(new IResourceDataChanged() {
|
|
||||||
@Override
|
|
||||||
public void resourceChanged(ChangeType type, Object object) {
|
|
||||||
if (type == ChangeType.DATA_UPDATE) {
|
|
||||||
if (object instanceof PluginDataObject) {
|
|
||||||
addDataObject((PluginDataObject) object);
|
|
||||||
} else if (object instanceof PluginDataObject[]) {
|
|
||||||
for (PluginDataObject pdo : (PluginDataObject[]) object) {
|
|
||||||
addDataObject((PluginDataObject) pdo);
|
|
||||||
}
|
|
||||||
} else if (object instanceof Object[]) {
|
|
||||||
for (Object obj : (Object[]) object) {
|
|
||||||
if (obj instanceof PluginDataObject) {
|
|
||||||
addDataObject((PluginDataObject) obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (type == ChangeType.CAPABILITY) {
|
|
||||||
if (object instanceof AbstractCapability) {
|
|
||||||
AbstractCapability capability = (AbstractCapability) object;
|
|
||||||
for (Frame frame : frames.values()) {
|
|
||||||
if (frame.renderable != null) {
|
|
||||||
capabilityChanged(frame.renderable, capability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,30 +116,50 @@ public abstract class AbstractPluginDataObjectResource<T extends AbstractResourc
|
||||||
*
|
*
|
||||||
* @param pdo
|
* @param pdo
|
||||||
*/
|
*/
|
||||||
protected final void addDataObject(PluginDataObject pdo) {
|
protected final void addDataObject(PluginDataObject... pdos) {
|
||||||
synchronized (lock) {
|
// Organize PDOs by time
|
||||||
if (frames == null) {
|
Map<DataTime, List<PluginDataObject>> pdoMap = new HashMap<DataTime, List<PluginDataObject>>();
|
||||||
// Check for null in case we were waiting for lock from
|
for (PluginDataObject pdo : pdos) {
|
||||||
// disposeInternal in which case we shouldn't process add
|
DataTime time = getDataObjectTime(pdo);
|
||||||
|
List<PluginDataObject> list = pdoMap.get(time);
|
||||||
|
if (list == null) {
|
||||||
|
list = new ArrayList<PluginDataObject>();
|
||||||
|
pdoMap.put(time, list);
|
||||||
|
}
|
||||||
|
list.add(pdo);
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
if (getStatus() == ResourceStatus.DISPOSED) {
|
||||||
|
// Don't process if disposed
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DataTime time = getDataObjectTime(pdo);
|
|
||||||
Frame frame = frames.get(time);
|
for (DataTime time : pdoMap.keySet()) {
|
||||||
if (frame == null) {
|
Frame frame = frames.get(time);
|
||||||
frame = new Frame();
|
if (frame == null) {
|
||||||
frames.put(time, frame);
|
frame = new Frame();
|
||||||
}
|
frames.put(time, frame);
|
||||||
if (frame.records.contains(pdo)) {
|
}
|
||||||
frame.records.remove(pdo);
|
synchronized (frame.lock) {
|
||||||
}
|
List<PluginDataObject> pdoList = pdoMap.get(time);
|
||||||
frame.records.add(pdo);
|
for (PluginDataObject pdo : pdoList) {
|
||||||
if (frame.renderable != null) {
|
if (frame.records.contains(pdo)) {
|
||||||
if (updateRenderable(frame.renderable, pdo) == false) {
|
frame.records.remove(pdo);
|
||||||
dispose(frame.renderable);
|
}
|
||||||
|
frame.records.add(pdo);
|
||||||
|
}
|
||||||
|
if (frame.renderable != null) {
|
||||||
|
if (updateRenderable(frame.renderable,
|
||||||
|
pdoList.toArray(new PluginDataObject[0])) == false) {
|
||||||
|
dispose(frame.renderable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dataTimes.contains(dataTimes)) {
|
||||||
|
dataTimes.add(time);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!dataTimes.contains(dataTimes)) {
|
|
||||||
dataTimes.add(time);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,9 +183,14 @@ public abstract class AbstractPluginDataObjectResource<T extends AbstractResourc
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected List<PluginDataObject> getPluginDataObjects(DataTime time) {
|
protected List<PluginDataObject> getPluginDataObjects(DataTime time) {
|
||||||
Frame frame = frames.get(time);
|
Frame frame = null;
|
||||||
|
synchronized (this) {
|
||||||
|
frame = frames.get(time);
|
||||||
|
}
|
||||||
if (frame != null) {
|
if (frame != null) {
|
||||||
return frame.records;
|
synchronized (frame.lock) {
|
||||||
|
return new ArrayList<PluginDataObject>(frame.records);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return new ArrayList<PluginDataObject>();
|
return new ArrayList<PluginDataObject>();
|
||||||
}
|
}
|
||||||
|
@ -185,14 +214,13 @@ public abstract class AbstractPluginDataObjectResource<T extends AbstractResourc
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public final void remove(DataTime dataTime) {
|
public final void remove(DataTime dataTime) {
|
||||||
synchronized (lock) {
|
Frame frame = null;
|
||||||
|
synchronized (this) {
|
||||||
super.remove(dataTime);
|
super.remove(dataTime);
|
||||||
Frame frame = frames.remove(dataTime);
|
frame = frames.remove(dataTime);
|
||||||
if (frame != null && frame.renderable != null) {
|
}
|
||||||
IRenderable dispose = frame.renderable;
|
if (frame != null) {
|
||||||
frame.renderable = null;
|
disposeFrame(frame);
|
||||||
dispose(dispose);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,19 +241,39 @@ public abstract class AbstractPluginDataObjectResource<T extends AbstractResourc
|
||||||
@Override
|
@Override
|
||||||
public final void project(CoordinateReferenceSystem crs)
|
public final void project(CoordinateReferenceSystem crs)
|
||||||
throws VizException {
|
throws VizException {
|
||||||
Iterator<Frame> iter = frames.values().iterator();
|
Map<DataTime, Frame> frames = null;
|
||||||
while (iter.hasNext()) {
|
synchronized (this) {
|
||||||
Frame frame = iter.next();
|
frames = new HashMap<DataTime, Frame>(this.frames);
|
||||||
IRenderable renderable = frame.renderable;
|
}
|
||||||
if (renderable != null) {
|
|
||||||
if (!projectRenderable(renderable, crs)) {
|
for (Frame frame : frames.values()) {
|
||||||
frame.renderable = null;
|
synchronized (frame.lock) {
|
||||||
dispose(renderable);
|
IRenderable renderable = frame.renderable;
|
||||||
|
if (renderable != null) {
|
||||||
|
if (!projectRenderable(renderable, crs)) {
|
||||||
|
frame.renderable = null;
|
||||||
|
dispose(renderable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final void initInternal(IGraphicsTarget target)
|
||||||
|
throws VizException {
|
||||||
|
resourceData.addChangeListener(dataChangedListener);
|
||||||
|
initResource(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init method for the resource to initialize any data needed for rendering
|
||||||
|
* which is not tied to a renderable.
|
||||||
|
*/
|
||||||
|
protected void initResource(IGraphicsTarget target) throws VizException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
@ -240,16 +288,28 @@ public abstract class AbstractPluginDataObjectResource<T extends AbstractResourc
|
||||||
DataTime time = paintProps.getDataTime();
|
DataTime time = paintProps.getDataTime();
|
||||||
if (time == null) {
|
if (time == null) {
|
||||||
time = getTimeForResource();
|
time = getTimeForResource();
|
||||||
}
|
if (time == null) {
|
||||||
Frame currFrame = frames.get(time);
|
return;
|
||||||
if (currFrame != null) {
|
|
||||||
IRenderable renderable = currFrame.renderable;
|
|
||||||
if (renderable == null) {
|
|
||||||
currFrame.renderable = renderable = constructRenderable(currFrame.records);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Frame currFrame = null;
|
||||||
|
synchronized (this) {
|
||||||
|
currFrame = frames.get(time);
|
||||||
|
}
|
||||||
|
if (currFrame != null) {
|
||||||
|
synchronized (currFrame.lock) {
|
||||||
|
if (currFrame.disposed == false) {
|
||||||
|
IRenderable renderable = currFrame.renderable;
|
||||||
|
if (renderable == null) {
|
||||||
|
currFrame.renderable = renderable = constructRenderable(
|
||||||
|
time, new ArrayList<PluginDataObject>(
|
||||||
|
currFrame.records));
|
||||||
|
}
|
||||||
|
|
||||||
if (renderable != null) {
|
if (renderable != null) {
|
||||||
renderable.paint(target, paintProps);
|
renderable.paint(target, paintProps);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,18 +321,39 @@ public abstract class AbstractPluginDataObjectResource<T extends AbstractResourc
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected final void disposeInternal() {
|
protected final void disposeInternal() {
|
||||||
synchronized (lock) {
|
Map<DataTime, Frame> frames = null;
|
||||||
for (Frame frame : frames.values()) {
|
synchronized (this) {
|
||||||
if (frame.renderable != null) {
|
// Copy Frames and clear member
|
||||||
disposeRenderable(frame.renderable);
|
frames = new HashMap<DataTime, Frame>(this.frames);
|
||||||
}
|
this.frames.clear();
|
||||||
}
|
|
||||||
frames.clear();
|
|
||||||
frames = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dispose frame one by one
|
||||||
|
for (Frame frame : frames.values()) {
|
||||||
|
disposeFrame(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceData.removeChangeListener(dataChangedListener);
|
||||||
disposeResource();
|
disposeResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes the Frame object by disposing the renderable and marking
|
||||||
|
* disposed
|
||||||
|
*
|
||||||
|
* @param frame
|
||||||
|
*/
|
||||||
|
private void disposeFrame(Frame frame) {
|
||||||
|
synchronized (frame.lock) {
|
||||||
|
if (frame.renderable != null) {
|
||||||
|
disposeRenderable(frame.renderable);
|
||||||
|
frame.renderable = null;
|
||||||
|
}
|
||||||
|
frame.records.clear();
|
||||||
|
frame.disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispose method for the resource to dispose any data not tied to a
|
* Dispose method for the resource to dispose any data not tied to a
|
||||||
* renderable. Called after all renderables have been disposed. Default impl
|
* renderable. Called after all renderables have been disposed. Default impl
|
||||||
|
@ -320,21 +401,22 @@ public abstract class AbstractPluginDataObjectResource<T extends AbstractResourc
|
||||||
* NOTE: The size of the pdo list will only grow so it can be used to
|
* NOTE: The size of the pdo list will only grow so it can be used to
|
||||||
* determine if new data has arrived since last call
|
* determine if new data has arrived since last call
|
||||||
*
|
*
|
||||||
|
* @param time
|
||||||
* @param records
|
* @param records
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected abstract IRenderable constructRenderable(
|
protected abstract IRenderable constructRenderable(DataTime time,
|
||||||
List<PluginDataObject> records) throws VizException;
|
List<PluginDataObject> records) throws VizException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the renderable with the new pdo, if the renderable is updatable,
|
* Update the renderable with the new pdos, if the renderable is updatable,
|
||||||
* return true. If the renderable needs to be recreated from scratch, return
|
* return true. If the renderable needs to be recreated from scratch, return
|
||||||
* false
|
* false
|
||||||
*
|
*
|
||||||
* @param renderable
|
* @param renderable
|
||||||
* @param pdo
|
* @param pdos
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
protected abstract boolean updateRenderable(IRenderable renderable,
|
protected abstract boolean updateRenderable(IRenderable renderable,
|
||||||
PluginDataObject pdo);
|
PluginDataObject... pdos);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
</license>
|
</license>
|
||||||
|
|
||||||
<requires>
|
<requires>
|
||||||
<import feature="com.raytheon.uf.viz.cots.feature" version="1.0.0.qualifier"/>
|
<import feature="com.raytheon.uf.common.base.feature" version="1.0.0.qualifier"/>
|
||||||
<import feature="com.raytheon.uf.viz.common.core.feature" version="1.0.0.qualifier"/>
|
<import feature="com.raytheon.uf.viz.base.feature" version="1.0.0.qualifier"/>
|
||||||
</requires>
|
</requires>
|
||||||
|
|
||||||
<plugin
|
<plugin
|
||||||
|
|
Loading…
Add table
Reference in a new issue