From df86a262a5fd42d09d33b248d56b450d4fbcfd9b Mon Sep 17 00:00:00 2001 From: Pierre-Charles David Date: Wed, 29 Mar 2023 16:49:01 +0200 Subject: [PATCH] [1527] Integrate new layout API The new API is only used for diagrams whose name ends with `__EXPERIMENTAL` for now, and the provided implementation does nothing for the moment. Bug: https://github.com/eclipse-sirius/sirius-components/issues/1527 Signed-off-by: Pierre-Charles David --- .../diagrams/DiagramCreationService.java | 17 +++++- .../layout/api/IDiagramLayoutEngine.java | 60 +++++++++++++++++++ .../experimental/DiagramLayoutEngine.java | 36 +++++++++++ .../view/emf/view/DynamicDiagramsTests.java | 3 +- 4 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 packages/diagrams/backend/sirius-components-diagrams-layout-api/src/main/java/org/eclipse/sirius/components/diagrams/layout/api/IDiagramLayoutEngine.java create mode 100644 packages/diagrams/backend/sirius-components-diagrams-layout/src/main/java/org/eclipse/sirius/components/diagrams/layout/experimental/DiagramLayoutEngine.java diff --git a/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/java/org/eclipse/sirius/components/collaborative/diagrams/DiagramCreationService.java b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/java/org/eclipse/sirius/components/collaborative/diagrams/DiagramCreationService.java index 8899baf782..9c3c6617c7 100644 --- a/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/java/org/eclipse/sirius/components/collaborative/diagrams/DiagramCreationService.java +++ b/packages/diagrams/backend/sirius-components-collaborative-diagrams/src/main/java/org/eclipse/sirius/components/collaborative/diagrams/DiagramCreationService.java @@ -13,6 +13,7 @@ package org.eclipse.sirius.components.collaborative.diagrams; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.concurrent.TimeUnit; @@ -34,7 +35,9 @@ import org.eclipse.sirius.components.diagrams.description.DiagramDescription; import org.eclipse.sirius.components.diagrams.events.ArrangeAllEvent; import org.eclipse.sirius.components.diagrams.events.IDiagramEvent; +import org.eclipse.sirius.components.diagrams.layout.api.IDiagramLayoutEngine; import org.eclipse.sirius.components.diagrams.layout.api.ILayoutService; +import org.eclipse.sirius.components.diagrams.layoutdata.DiagramLayoutData; import org.eclipse.sirius.components.diagrams.renderer.DiagramRenderer; import org.eclipse.sirius.components.representations.Element; import org.eclipse.sirius.components.representations.IOperationValidator; @@ -62,6 +65,8 @@ public class DiagramCreationService implements IDiagramCreationService { private final ILayoutService layoutService; + private final IDiagramLayoutEngine diagramLayoutEngine; + private final IOperationValidator operationValidator; private final Timer timer; @@ -69,11 +74,12 @@ public class DiagramCreationService implements IDiagramCreationService { private final Logger logger = LoggerFactory.getLogger(DiagramCreationService.class); public DiagramCreationService(IRepresentationDescriptionSearchService representationDescriptionSearchService, IRepresentationPersistenceService representationPersistenceService, - IObjectService objectService, ILayoutService layoutService, IOperationValidator operationValidator, MeterRegistry meterRegistry) { + IObjectService objectService, ILayoutService layoutService, IDiagramLayoutEngine diagramLayoutEngine, IOperationValidator operationValidator, MeterRegistry meterRegistry) { this.representationDescriptionSearchService = Objects.requireNonNull(representationDescriptionSearchService); this.representationPersistenceService = Objects.requireNonNull(representationPersistenceService); this.objectService = Objects.requireNonNull(objectService); this.layoutService = Objects.requireNonNull(layoutService); + this.diagramLayoutEngine = Objects.requireNonNull(diagramLayoutEngine); this.operationValidator = Objects.requireNonNull(operationValidator); // @formatter:off this.timer = Timer.builder(Monitoring.REPRESENTATION_EVENT_PROCESSOR_REFRESH) @@ -162,6 +168,15 @@ private Diagram doRender(String label, Object targetObject, IEditingContext edit newDiagram = this.layoutService.incrementalLayout(editingContext, newDiagram, optionalDiagramElementEvent); } + if (newDiagram.getLabel().endsWith("__EXPERIMENTAL")) { + DiagramLayoutData previousLayoutData = new DiagramLayoutData(Map.of(), Map.of(), Map.of()); + if (!this.shouldPerformFullLayout(optionalDiagramContext, diagramDescription) && optionalPreviousDiagram.isPresent()) { + previousLayoutData = optionalPreviousDiagram.get().getLayoutData(); + } + DiagramLayoutData newLayoutData = this.diagramLayoutEngine.layout(editingContext, newDiagram, previousLayoutData, optionalDiagramElementEvent); + newDiagram = Diagram.newDiagram(newDiagram).layoutData(newLayoutData).build(); + } + this.representationPersistenceService.save(editingContext, newDiagram); long end = System.currentTimeMillis(); diff --git a/packages/diagrams/backend/sirius-components-diagrams-layout-api/src/main/java/org/eclipse/sirius/components/diagrams/layout/api/IDiagramLayoutEngine.java b/packages/diagrams/backend/sirius-components-diagrams-layout-api/src/main/java/org/eclipse/sirius/components/diagrams/layout/api/IDiagramLayoutEngine.java new file mode 100644 index 0000000000..b45c367fa1 --- /dev/null +++ b/packages/diagrams/backend/sirius-components-diagrams-layout-api/src/main/java/org/eclipse/sirius/components/diagrams/layout/api/IDiagramLayoutEngine.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2023 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.components.diagrams.layout.api; + +import java.util.Map; +import java.util.Optional; + +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.diagrams.events.IDiagramEvent; +import org.eclipse.sirius.components.diagrams.layoutdata.DiagramLayoutData; + +/** + * Used to layout diagrams. + * + * @author pcdavid + */ +public interface IDiagramLayoutEngine { + /** + * Computes the new layout to be used for a diagram and its content. + * + * @param editingContext + * the editing context. + * @param diagram + * the diagram's structure (nodes, edges, etc.). + * @param previousLayoutData + * the layout data from the previous version of the diagram. This may be empty for the initial layout or + * for a "full" layout. + * @param optionalEvent + * if the (incremental) layout was triggered by a user operation (e.g. the invocation of a tool at a + * specific position) the corresponding event with the information relevant for the layout will be + * available here. + * @return the layout information to be used for the new version of the diagram. + */ + DiagramLayoutData layout(IEditingContext editingContext, Diagram diagram, DiagramLayoutData previousLayoutData, Optional optionalDiagramEvent); + + /** + * Implementation which does nothing, used for mocks in unit tests. + * + * @author pcdavid + */ + class NoOp implements IDiagramLayoutEngine { + + @Override + public DiagramLayoutData layout(IEditingContext editingContext, Diagram diagram, DiagramLayoutData previousLayoutData, Optional optionalDiagramEvent) { + return Optional.ofNullable(previousLayoutData).orElse(new DiagramLayoutData(Map.of(), Map.of(), Map.of())); + } + + } +} diff --git a/packages/diagrams/backend/sirius-components-diagrams-layout/src/main/java/org/eclipse/sirius/components/diagrams/layout/experimental/DiagramLayoutEngine.java b/packages/diagrams/backend/sirius-components-diagrams-layout/src/main/java/org/eclipse/sirius/components/diagrams/layout/experimental/DiagramLayoutEngine.java new file mode 100644 index 0000000000..caff330e39 --- /dev/null +++ b/packages/diagrams/backend/sirius-components-diagrams-layout/src/main/java/org/eclipse/sirius/components/diagrams/layout/experimental/DiagramLayoutEngine.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2023 Obeo. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Obeo - initial API and implementation + *******************************************************************************/ +package org.eclipse.sirius.components.diagrams.layout.experimental; + +import java.util.Map; +import java.util.Optional; + +import org.eclipse.sirius.components.core.api.IEditingContext; +import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.diagrams.events.IDiagramEvent; +import org.eclipse.sirius.components.diagrams.layout.api.IDiagramLayoutEngine; +import org.eclipse.sirius.components.diagrams.layoutdata.DiagramLayoutData; +import org.springframework.stereotype.Service; + +/** + * The default {@link IDiagramLayoutEngine}. Empty/no-op for now. + * + * @author pcdavid + */ +@Service +public class DiagramLayoutEngine implements IDiagramLayoutEngine { + @Override + public DiagramLayoutData layout(IEditingContext editingContext, Diagram diagram, DiagramLayoutData previousLayoutData, Optional optionalDiagramEvent) { + return new DiagramLayoutData(Map.of(), Map.of(), Map.of()); + } +} diff --git a/packages/view/backend/sirius-components-view-emf/src/test/java/org/eclipse/sirius/components/view/emf/view/DynamicDiagramsTests.java b/packages/view/backend/sirius-components-view-emf/src/test/java/org/eclipse/sirius/components/view/emf/view/DynamicDiagramsTests.java index cab68c9b17..b0bab3bb16 100644 --- a/packages/view/backend/sirius-components-view-emf/src/test/java/org/eclipse/sirius/components/view/emf/view/DynamicDiagramsTests.java +++ b/packages/view/backend/sirius-components-view-emf/src/test/java/org/eclipse/sirius/components/view/emf/view/DynamicDiagramsTests.java @@ -31,6 +31,7 @@ import org.eclipse.sirius.components.core.api.IObjectService; import org.eclipse.sirius.components.core.api.IRepresentationDescriptionSearchService; import org.eclipse.sirius.components.diagrams.Diagram; +import org.eclipse.sirius.components.diagrams.layout.api.IDiagramLayoutEngine; import org.eclipse.sirius.components.diagrams.layout.api.ILayoutService; import org.eclipse.sirius.components.emf.services.EditingContext; import org.eclipse.sirius.components.emf.services.JSONResourceFactory; @@ -158,7 +159,7 @@ public Optional findById(IEditingContext editingCont IObjectService objectService = new IObjectService.NoOp(); ILayoutService layoutService = new ILayoutService.NoOp(); MeterRegistry meterRegistry = new SimpleMeterRegistry(); - var diagramCreationService = new DiagramCreationService(representationDescriptionSearchService, new IRepresentationPersistenceService.NoOp(), objectService, layoutService, new IOperationValidator.NoOp(), meterRegistry); + var diagramCreationService = new DiagramCreationService(representationDescriptionSearchService, new IRepresentationPersistenceService.NoOp(), objectService, layoutService, new IDiagramLayoutEngine.NoOp(), new IOperationValidator.NoOp(), meterRegistry); IEditingContext editinContext = new IEditingContext.NoOp();