blob: 4a2a776419af12af5326265f91e0482f19b63375 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Agence spatiale canadienne / Canadian Space Agency
* 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:
* Pierre Allard - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*******************************************************************************/
package org.eclipse.apogy.core.environment.earth.ui.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.apogy.common.emf.transaction.ApogyCommonTransactionFacade;
import org.eclipse.apogy.core.environment.earth.ui.ApogyEarthEnvironmentUIPackage;
import org.eclipse.apogy.core.environment.earth.ui.utils.MultiEObjectsAdapter;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.progress.UIJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.layers.RenderableLayer;
public abstract class AbstractWorldWindLayerCustomImpl extends AbstractWorldWindLayerImpl {
private static final Logger Logger = LoggerFactory.getLogger(AbstractWorldWindLayerImpl.class);
private static UIJob blinkingJob = null;
private static Map<AbstractWorldWindLayerCustomImpl, Boolean> blinkingLayers = new HashMap<AbstractWorldWindLayerCustomImpl, Boolean>();
private MultiEObjectsAdapter layerAdapter = null;
protected AbstractWorldWindLayerCustomImpl() {
super();
eAdapters().add(getLayerAdapter());
// Forces the blinking Job to start.
getBlinkingJob();
}
@Override
public void setVisible(boolean newVisible) {
super.setVisible(newVisible);
updateRenderableLayer();
}
@Override
public void setBlinking(boolean newBlinking) {
if (newBlinking && !this.blinking) {
// Changed to blinking.
blinkingLayers.put(this, this.isVisible());
} else if (!newBlinking && this.blinking) {
// Changed to not blinking.
Boolean originalVisibility = blinkingLayers.get(this);
if (originalVisibility != null) {
ApogyCommonTransactionFacade.INSTANCE.basicSet(this,
ApogyEarthEnvironmentUIPackage.Literals.ABSTRACT_WORLD_WIND_LAYER__VISIBLE, originalVisibility,
true);
}
blinkingLayers.remove(this);
}
super.setBlinking(newBlinking);
}
@Override
public RenderableLayer getRenderableLayer() {
RenderableLayer tmp = super.getRenderableLayer();
if (tmp == null) {
tmp = new RenderableLayer();
ApogyCommonTransactionFacade.INSTANCE.basicSet(this,
ApogyEarthEnvironmentUIPackage.Literals.ABSTRACT_WORLD_WIND_LAYER__RENDERABLE_LAYER, tmp);
}
return tmp;
}
@Override
public void initialise() {
// Nothing to do here.
}
@Override
public void update() throws Exception {
if (!isUpdating() && !isDisposed()) {
try {
updateRenderableLayer();
} catch (Exception e) {
Logger.error(e.getMessage(), e);
}
}
}
@Override
public void dispose() {
// Wait for the layer to finish its update.
while (isUpdating()) {
try {
Logger.warn("Waiting for layer to complete update...");
Thread.sleep(200);
} catch (Exception e) {
}
}
// Set disposed flag to true.
ApogyCommonTransactionFacade.INSTANCE.basicSet(this,
ApogyEarthEnvironmentUIPackage.Literals.ABSTRACT_WORLD_WIND_LAYER__DISPOSED, true, true);
// Removes the layer from the display.
RenderableLayer layer = getRenderableLayer();
layer.removeAllRenderables();
getRenderableLayer().firePropertyChange(AVKey.LAYER, null, this);
}
@Override
public void selectionChanged(ISelection selection) {
// Nothing to do.
}
@Override
public boolean getDefaultAutoUpdateEnabled() {
return false;
}
/**
* Method that does the update of the renderable layer in World Wind.
*/
protected abstract void updateRenderableLayer();
private MultiEObjectsAdapter getLayerAdapter() {
if (this.layerAdapter == null) {
this.layerAdapter = new MultiEObjectsAdapter() {
@Override
public void notifyChanged(Notification msg) {
if (msg.getNotifier() instanceof AbstractWorldWindLayerCustomImpl) {
int featureId = msg.getFeatureID(AbstractWorldWindLayerCustomImpl.class);
switch (featureId) {
case ApogyEarthEnvironmentUIPackage.ABSTRACT_WORLD_WIND_LAYER__VISIBLE:
if (isAutoUpdateEnabled())
updateRenderableLayer();
break;
default:
break;
}
}
}
};
}
return this.layerAdapter;
}
private static UIJob getBlinkingJob() {
if (blinkingJob == null) {
blinkingJob = new UIJob("World Wind Layer Blinking") {
private boolean visible = true;
@Override
public IStatus runInUIThread(IProgressMonitor progressMonitor) {
List<AbstractWorldWindLayerCustomImpl> layers = new ArrayList<AbstractWorldWindLayerCustomImpl>(
blinkingLayers.keySet());
for (AbstractWorldWindLayerCustomImpl layer : layers) {
if (!layer.isDisposed()) {
ApogyCommonTransactionFacade.INSTANCE.basicSet(layer,
ApogyEarthEnvironmentUIPackage.Literals.ABSTRACT_WORLD_WIND_LAYER__VISIBLE,
this.visible, true);
}
}
// Toggle visibility.
this.visible = !this.visible;
if (!progressMonitor.isCanceled())
this.schedule(1000);
return Status.OK_STATUS;
}
};
blinkingJob.setPriority(UIJob.LONG);
blinkingJob.schedule();
}
return blinkingJob;
}
} // AbstractWorldWindLayerImpl