| /******************************************************************************* |
| * 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 |