blob: b44379876e7cd70ecb007dbf340fed91accd4949 [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,
* Regent L'Archeveque - initial API and implementation
*
* SPDX-License-Identifier: EPL-1.0
*
*******************************************************************************/
package org.eclipse.apogy.core.environment.surface.impl;
import java.util.Collection;
import org.eclipse.apogy.common.math.Matrix4x4;
import org.eclipse.apogy.common.topology.ApogyCommonTopologyFactory;
import org.eclipse.apogy.common.topology.INodeVisitor;
import org.eclipse.apogy.common.topology.Node;
import org.eclipse.apogy.common.topology.ReferencedGroupNode;
import org.eclipse.apogy.core.environment.surface.AbstractMapLayer;
import org.eclipse.apogy.core.environment.surface.AbstractMapLayerNode;
import org.eclipse.apogy.core.environment.surface.ApogySurfaceEnvironmentPackage;
import org.eclipse.apogy.core.environment.surface.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MapNodeCustomImpl extends MapNodeImpl {
private static final Logger Logger = LoggerFactory.getLogger(MapNodeImpl.class);
private ReferencedGroupNode referencedGroupNode = null;
private Adapter adapter = null;
protected MapNodeCustomImpl() {
super();
this.eAdapters().add(getAdapter());
}
@Override
public void accept(INodeVisitor visitor) {
if (visitor.getType().isInstance(this)) {
visitor.visit(this);
}
// We do the same for all the children.
for (Node child : getChildren()) {
child.accept(visitor);
}
}
private void clearTopology() {
getReferencedGroupNode().getChildren().clear();
}
/**
* Attaches the specified layer topology to the Map topology.
*
* @param layer The Map Layer.
* @return The node representing the layer that was attached in the Map
* topology.
*/
protected void addLayer(final AbstractMapLayer layer) {
getReferencedGroupNode().getChildren().add(layer.getAbstractMapLayerNode());
Logger.info("Added layer <" + layer.getName() + ">.");
}
/**
* Detaches the specified layer topology from the Map topology.
*
* @param layer The Map Layer.
* @return The topology node removed.
*/
protected void removeLayer(final AbstractMapLayer layer) {
// Find the node that represents the layer in the map topology.
AbstractMapLayerNode layerNode = layer.getAbstractMapLayerNode();
// Remove the node from the topology.
if (layerNode != null) {
// Removes the node from the topology.
getReferencedGroupNode().getChildren().remove(layerNode);
}
Logger.info("Removed layer <" + layer.getName() + ">.");
}
private ReferencedGroupNode getReferencedGroupNode() {
if (this.referencedGroupNode == null) {
this.referencedGroupNode = ApogyCommonTopologyFactory.eINSTANCE.createReferencedGroupNode();
this.referencedGroupNode.setDescription("Map Group Node.");
this.referencedGroupNode.setNodeId("Map Content (" + getMap().getName() + ")");
getChildren().add(this.referencedGroupNode);
}
return this.referencedGroupNode;
}
protected Adapter getAdapter() {
if (this.adapter == null) {
this.adapter = new AdapterImpl() {
@SuppressWarnings("unchecked")
@Override
public void notifyChanged(Notification msg) {
if (msg.getNotifier() instanceof MapNodeCustomImpl) {
if (msg.getFeatureID(MapNodeCustomImpl.class) == ApogySurfaceEnvironmentPackage.MAP_NODE__MAP) {
// Clear topology.
clearTopology();
if (msg.getOldValue() instanceof Map) {
((Map) msg.getOldValue()).eAdapters().remove(getAdapter());
}
if (msg.getNewValue() instanceof Map) {
((Map) msg.getNewValue()).eAdapters().add(getAdapter());
}
}
} else if (msg.getNotifier() instanceof Map) {
if (msg.getFeatureID(Map.class) == ApogySurfaceEnvironmentPackage.MAP__LAYERS) {
final Notification message = msg;
Job job = new Job("MapNode Modify Layers") {
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
switch (message.getEventType()) {
case Notification.ADD: {
AbstractMapLayer layerAdded = (AbstractMapLayer) message.getNewValue();
addLayer(layerAdded);
break;
}
case Notification.ADD_MANY: {
Collection<? extends AbstractMapLayer> layersAdded = (Collection<? extends AbstractMapLayer>) message
.getNewValue();
for (AbstractMapLayer abstractMapLayer : layersAdded) {
addLayer(abstractMapLayer);
}
break;
}
case Notification.REMOVE: {
AbstractMapLayer layerRemoved = (AbstractMapLayer) message.getOldValue();
removeLayer(layerRemoved);
break;
}
case Notification.REMOVE_MANY: {
Collection<? extends AbstractMapLayer> layersRemoved = (Collection<? extends AbstractMapLayer>) message
.getOldValue();
for (AbstractMapLayer abstractMapLayer : layersRemoved) {
removeLayer(abstractMapLayer);
}
break;
}
default: {
}
}
return org.eclipse.core.runtime.Status.OK_STATUS;
} catch (Throwable t) {
Logger.error(t.getMessage(), t);
}
return org.eclipse.core.runtime.Status.OK_STATUS;
}
};
job.setPriority(Job.LONG);
job.schedule();
} else if (msg.getFeatureID(Map.class) == ApogySurfaceEnvironmentPackage.MAP__TRANSFORMATION) {
Matrix4x4 matrix = (Matrix4x4) msg.getNewValue();
if (matrix != null) {
// Updates the transform node.
setTransformation(matrix.asMatrix4d());
}
}
}
}
};
}
return this.adapter;
}
} // MapNodeImpl