diff options
| author | Maxime Porhel | 2015-03-27 12:46:19 +0000 |
|---|---|---|
| committer | Maxime Porhel | 2015-03-31 15:06:16 +0000 |
| commit | 2fad4c24ec101d2547fd1880c672d51c0dcffdbb (patch) | |
| tree | 4ef7985e8f3a408914d03ff0552ed0baf38eddbd | |
| parent | f5daae6981e0b3131ecd9a128d2c18af221697a9 (diff) | |
| download | org.eclipse.sirius-2fad4c24ec101d2547fd1880c672d51c0dcffdbb.tar.gz org.eclipse.sirius-2fad4c24ec101d2547fd1880c672d51c0dcffdbb.tar.xz org.eclipse.sirius-2fad4c24ec101d2547fd1880c672d51c0dcffdbb.zip | |
[463299] Refresh regions optimization
Reuse the same mechanism than the DNodeListElement sort in
AbstractDNodeListCompartmentEditPart.
Bug: 463299
Change-Id: I2a305c8d64e0889a932a1025f6732f7458799768
Signed-off-by: Maxime Porhel <maxime.porhel@obeo.fr>
2 files changed, 73 insertions, 56 deletions
diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/AbstractDNodeContainerCompartmentEditPart.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/AbstractDNodeContainerCompartmentEditPart.java index 08cc8fd1e4..ac70151e42 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/AbstractDNodeContainerCompartmentEditPart.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/edit/parts/AbstractDNodeContainerCompartmentEditPart.java @@ -258,21 +258,16 @@ public abstract class AbstractDNodeContainerCompartmentEditPart extends ShapeCom } } - /** - * {@inheritDoc} - * - * @see org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart#getModelChildren() - */ /* * Hide non-visible elements */ + @Override protected List getModelChildren() { // create a new view to avoid to change the super.getModelChildren list. List<View> modelChildren = Lists.newArrayList(Iterables.filter(super.getModelChildren(), View.class)); DiagramElementEditPartOperation.removeInvisibleElements(modelChildren); - if (isRegionContainerCompartment() && getModel() instanceof View) { - RegionContainerUpdateLayoutOperation.sortRegions((View) getModel(), modelChildren); + RegionContainerUpdateLayoutOperation.sortRegions((DNodeContainer)resolveSemanticElement(), modelChildren); } return modelChildren; } diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/operation/RegionContainerUpdateLayoutOperation.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/operation/RegionContainerUpdateLayoutOperation.java index 2c4a50b45c..59cb045557 100644 --- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/operation/RegionContainerUpdateLayoutOperation.java +++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/operation/RegionContainerUpdateLayoutOperation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 THALES GLOBAL SERVICES. + * Copyright (c) 2013, 2015 THALES GLOBAL SERVICES and others. * 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 @@ -11,11 +11,11 @@ package org.eclipse.sirius.diagram.ui.internal.operation; import java.util.Collections; -import java.util.Comparator; import java.util.List; import java.util.Map; import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil; import org.eclipse.gmf.runtime.notation.LayoutConstraint; @@ -23,7 +23,7 @@ import org.eclipse.gmf.runtime.notation.Location; import org.eclipse.gmf.runtime.notation.Node; import org.eclipse.gmf.runtime.notation.Size; import org.eclipse.gmf.runtime.notation.View; -import org.eclipse.sirius.diagram.DDiagramElementContainer; +import org.eclipse.sirius.diagram.DDiagramElement; import org.eclipse.sirius.diagram.DNodeContainer; import org.eclipse.sirius.diagram.business.internal.query.DNodeContainerExperimentalQuery; import org.eclipse.sirius.diagram.description.ContainerMapping; @@ -36,9 +36,11 @@ import org.eclipse.sirius.diagram.ui.part.SiriusVisualIDRegistry; import org.eclipse.sirius.viewpoint.DMappingBased; import org.eclipse.sirius.viewpoint.description.RepresentationElementMapping; +import com.google.common.base.Function; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Ordering; /** * Update and keep consistent the GMF Bounds of a Region Container and its @@ -92,12 +94,11 @@ public class RegionContainerUpdateLayoutOperation extends AbstractModelChangeOpe public Void execute() { List<Node> regionsToLayout = getRegionsToLayout(); if (!regionsToLayout.isEmpty()) { - - sortRegions(regionContainer, regionsToLayout); - EObject element = regionContainer.getElement(); if (element instanceof DNodeContainer) { - DNodeContainerExperimentalQuery query = new DNodeContainerExperimentalQuery((DNodeContainer) element); + DNodeContainer dnc = (DNodeContainer) element; + sortRegions(dnc, regionsToLayout); + DNodeContainerExperimentalQuery query = new DNodeContainerExperimentalQuery(dnc); if (query.isVerticalStackContainer()) { updateRegionsLayoutContraints(regionsToLayout, true); } else if (query.isHorizontaltackContainer()) { @@ -169,58 +170,79 @@ public class RegionContainerUpdateLayoutOperation extends AbstractModelChangeOpe * Sort the regions with the ddiagram element index comparator and then with * a mapping comparator. * - * @param containerNode - * the region container view + * @param dNodeContainer + * the {@link DNodeContainer} region container * @param modelChildren * the regions */ - public static void sortRegions(View containerNode, List<? extends View> modelChildren) { - Collections.sort(modelChildren, new IndexComparator(containerNode)); - Collections.sort(modelChildren, new MappingComparator(containerNode)); + public static void sortRegions(DNodeContainer dNodeContainer, List<? extends View> modelChildren) { + new RegionComparisonHelper(dNodeContainer).sort(modelChildren); } - private static class MappingComparator implements Comparator<View> { - private final View containerView; + private static class RegionComparisonHelper { + private DNodeContainer self; - public MappingComparator(View container) { - this.containerView = container; + public RegionComparisonHelper(DNodeContainer self) { + this.self = self; } - public int compare(View view0, View view1) { - EObject element0 = view0.getElement(); - EObject element1 = view1.getElement(); - if (element0 instanceof DMappingBased && element1 instanceof DMappingBased) { - EObject eObj = containerView.getElement(); - if (eObj instanceof DNodeContainer) { - DNodeContainer container = (DNodeContainer) eObj; - List<ContainerMapping> allMappings = container.getActualMapping().getAllContainerMappings(); - RepresentationElementMapping origin0 = ((DMappingBased) element0).getMapping(); - RepresentationElementMapping origin1 = ((DMappingBased) element1).getMapping(); - return allMappings.indexOf(origin0) - allMappings.indexOf(origin1); + public void sort(List<? extends View> views) { + /* + * The main sort criterion is based on the elements' mapping's + * position in the VSM, so that all instances of the same mapping + * are grouped together, and if a mapping M1 appears before another + * M2 in the specification, all instances of M1 appear before those + * of M2. + */ + final EList<ContainerMapping> allMappings = self.getActualMapping().getAllContainerMappings(); + Function<View, Integer> mappingIndex = new Function<View, Integer>() { + @Override + public Integer apply(View view) { + if (view != null) { + EObject element = view.getElement(); + if (element instanceof DMappingBased) { + RepresentationElementMapping mapping = ((DMappingBased) element).getMapping(); + /* + * Use a plain indexOf search here, assuming that in + * practice there are never more than a handful of + * mappings inside a list container. + */ + return allMappings.indexOf(mapping); + } + } + return Integer.MAX_VALUE; } + }; + /* + * Inside a group of elements from the same mapping, use the + * DNodeListItem order. As opposed to the mappings, the number of + * actual items can grow very large, so we pre-compute the elements' + * indices with a linear scan to avoid repeated calls to indexOf for + * each comparison. + */ + final Map<DDiagramElement, Integer> indices = Maps.newHashMap(); + EList<DDiagramElement> containers = self.getOwnedDiagramElements(); + int i = 0; + for (DDiagramElement current : containers) { + indices.put(current, i); + i++; } - return 0; - } - } - - private static class IndexComparator implements Comparator<View> { - private final View container; - - public IndexComparator(View container) { - this.container = container; - } - - public int compare(View o1, View o2) { - final EObject semantic = ViewUtil.resolveSemanticElement(container); - if (semantic instanceof DNodeContainer) { - final EObject sem1 = ViewUtil.resolveSemanticElement(o1); - final EObject sem2 = ViewUtil.resolveSemanticElement(o2); - if (sem1 instanceof DDiagramElementContainer && sem2 instanceof DDiagramElementContainer) { - DNodeContainer dNodeContainer = (DNodeContainer) semantic; - return dNodeContainer.getContainers().indexOf(sem1) - dNodeContainer.getContainers().indexOf(sem2); + Function<View, Integer> nodeIndex = new Function<View, Integer>() { + @Override + public Integer apply(View view) { + if (view != null) { + EObject sem = ViewUtil.resolveSemanticElement(view); + if (sem != null && indices.containsKey(sem)) { + return indices.get(sem); + } + } + return Integer.MAX_VALUE; } - } - return 0; + }; + /* + * Perform the actual sort, combining the two criteria above. + */ + Collections.sort(views, Ordering.natural().onResultOf(mappingIndex).compound(Ordering.natural().onResultOf(nodeIndex))); } - }; + } } |
