Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

copy properties to the SModel already during initial SModel generation #203

Merged
merged 4 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2018-2021 by
* Copyright 2018-2024 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
Expand Down Expand Up @@ -40,6 +40,7 @@ import de.cau.cs.kieler.klighd.lsp.model.SKLabel
import de.cau.cs.kieler.klighd.lsp.model.SKNode
import de.cau.cs.kieler.klighd.lsp.model.SKPort
import de.cau.cs.kieler.klighd.lsp.utils.KGraphElementIdGenerator
import de.cau.cs.kieler.klighd.lsp.utils.KGraphMappingUtil
import de.cau.cs.kieler.klighd.lsp.utils.SprottyProperties
import de.cau.cs.kieler.klighd.util.KlighdPredicates
import de.cau.cs.kieler.klighd.util.KlighdProperties
Expand Down Expand Up @@ -259,6 +260,7 @@ class KGraphDiagramGenerator implements IDiagramGenerator {
nodeElement.data = node.data.filter[KRenderingLibrary.isAssignableFrom(it.class)].toList

setProperties(nodeElement, node)
KGraphMappingUtil.mapProperties(node, nodeElement)
findSpecialRenderings(filteredData)

val renderingContextData = RenderingContextData.get(node)
Expand Down Expand Up @@ -311,6 +313,7 @@ class KGraphDiagramGenerator implements IDiagramGenerator {

val renderings = edge.data.filter[KRendering.isAssignableFrom(it.class)].toList

KGraphMappingUtil.mapProperties(edge, edgeElement)
findSpecialRenderings(renderings)
edgeElement.children.addAll(createLabels(edge.labels))
edgeElement.junctionPoints = edge.getProperty(CoreOptions.JUNCTION_POINTS)
Expand All @@ -332,6 +335,7 @@ class KGraphDiagramGenerator implements IDiagramGenerator {

val renderings = port.data.filter [ KRendering.isAssignableFrom(it.class)].toList

KGraphMappingUtil.mapProperties(port, portElement)
findSpecialRenderings(renderings)
portElement.children.addAll(createLabels(port.labels))

Expand All @@ -353,6 +357,7 @@ class KGraphDiagramGenerator implements IDiagramGenerator {

val renderings = label.data.filter[KRendering.isAssignableFrom(it.class)].toList

KGraphMappingUtil.mapProperties(label, labelElement)
findSpecialRenderings(renderings)
// activate the element by default if it does not have an active/inactive status yet.
val renderingContextData = RenderingContextData.get(label)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ class KGraphDiagramServer extends LanguageAwareDiagramServer {
* Tells the server that the diagram should be refreshed.
*/
protected def handle(RefreshDiagramAction action) {
getOptions().putAll(action.options)
updateDiagram()
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import de.cau.cs.kieler.klighd.lsp.launch.AbstractLanguageServer
import de.cau.cs.kieler.klighd.lsp.model.RequestDiagramPieceAction
import de.cau.cs.kieler.klighd.lsp.model.SKGraph
import de.cau.cs.kieler.klighd.lsp.utils.KGraphMappingUtil
import de.cau.cs.kieler.klighd.lsp.utils.RenderingPreparer
import de.cau.cs.kieler.klighd.util.KlighdSynthesisProperties
import java.util.HashSet
import java.util.List
Expand Down Expand Up @@ -316,6 +317,7 @@ class KGraphDiagramUpdater extends DiagramUpdater {
var SGraph sGraph = null;
synchronized (diagramState) {
sGraph = diagramGenerator.toSGraph(viewContext.viewModel, uri, cancelIndicator)
RenderingPreparer.prepareRenderingIDs(viewContext.viewModel, diagramGenerator.getKGraphToSModelElementMap)
}
if (incrementalDiagramGenerator) {
val requestManager = new KGraphDiagramPieceRequestManager(diagramGenerator as KGraphIncrementalDiagramGenerator)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class KGraphLayoutEngine extends ElkLayoutEngine {

synchronized (kGraphContext.viewModel) {
lightDiagramLayoutConfig.performLayout
RenderingPreparer.prepareRendering(kGraphContext.viewModel, diagramState.getKGraphToSModelElementMap(uri))
RenderingPreparer.prepareRenderingLayout(kGraphContext.viewModel, diagramState.getKGraphToSModelElementMap(uri))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2018-2022 by
* Copyright 2018-2024 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
Expand All @@ -18,6 +18,7 @@ package de.cau.cs.kieler.klighd.lsp.model

import de.cau.cs.kieler.klighd.krendering.KImage
import java.util.List
import java.util.Map
import java.util.Set
import java.util.function.Consumer
import org.eclipse.sprotty.Action
Expand Down Expand Up @@ -213,6 +214,8 @@ class RefreshDiagramAction implements Action {
public static val KIND = 'refreshDiagram'
String kind = KIND

Map<String, String> options

new() {}
new(Consumer<RefreshDiagramAction> initializer) {
initializer.accept(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* http://rtsys.informatik.uni-kiel.de/kieler
*
* Copyright 2018-2022 by
* Copyright 2018-2024 by
* + Kiel University
* + Department of Computer Science
* + Real-Time and Embedded Systems Group
Expand Down Expand Up @@ -39,6 +39,7 @@ abstract interface SKElement {
def List<KGraphData> getData()
def void setData(List<KGraphData> data)
def HashMap<String, Object> getProperties()
def void setProperties(HashMap<String, Object> theProperties)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import de.cau.cs.kieler.klighd.kgraph.KLabel
import de.cau.cs.kieler.klighd.kgraph.KNode
import de.cau.cs.kieler.klighd.kgraph.KPort
import de.cau.cs.kieler.klighd.kgraph.KShapeLayout
import de.cau.cs.kieler.klighd.kgraph.util.KGraphUtil
import de.cau.cs.kieler.klighd.lsp.model.SKEdge
import de.cau.cs.kieler.klighd.lsp.model.SKElement
import de.cau.cs.kieler.klighd.lsp.model.SKLabel
Expand All @@ -39,7 +40,6 @@ import org.eclipse.sprotty.Dimension
import org.eclipse.sprotty.Point
import org.eclipse.sprotty.SModelElement
import org.eclipse.sprotty.SShapeElement
import de.cau.cs.kieler.klighd.kgraph.util.KGraphUtil

/**
* A helper class containing static methods for mapping of KGraph and SGraph bounds.
Expand Down Expand Up @@ -108,15 +108,7 @@ class KGraphMappingUtil {
skEdge.junctionPoints.addAllAsCopies(0, kEdge.getProperty(CoreOptions.JUNCTION_POINTS))
skEdge.junctionPoints.offset(new KVector(leftInset, topInset))

// map all properties excepts those that are blacklisted
// also include external whitelisted properties
var properties = kEdge.allProperties;

for (propertyKVPair : properties.entrySet()) {
if (keepProperty(propertyKVPair.key)) {
skEdge.properties.put(propertyKVPair.key.id, propertyKVPair.value)
}
}
mapProperties(kEdge, skEdge)
}

/**
Expand All @@ -138,11 +130,19 @@ class KGraphMappingUtil {
skNode.position = new Point(kNode.xpos + leftInset, kNode.ypos + topInset)
skNode.size = new Dimension(kNode.width, kNode.height)

var properties = kNode.allProperties;
mapProperties(kNode, skNode)
}

/**
* Maps the properties of the KGraphElement to the corresponding SModelElement.
* Excepts those that are blacklisted, but also include whitelisted external properties.
*/
static def mapProperties(KGraphElement kElement, SKElement sElement) {
val properties = kElement.allProperties

for (propertyKVPair : properties.entrySet()) {
if (keepProperty(propertyKVPair.key)) {
skNode.properties.put(propertyKVPair.key.id, propertyKVPair.value)
sElement.properties.put(propertyKVPair.key.id, propertyKVPair.value)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,93 @@ import static extension de.cau.cs.kieler.klighd.lsp.utils.SprottyProperties.*
* @author nre
*/
final class RenderingPreparer {

/**
* Prepares the rendering IDs of a KGraph to be generated for an external viewer.
*
*
* @param element The parent element containing the graph to calculate all rendering IDs for.
* @param kGraphToSGraph A map for identifying the SGraph element for each KGraph element in this graph.
*/
static def void prepareRenderingIDs(KGraphElement element, Map<KGraphElement, SModelElement> kGraphToSGraph) {
// calculate the IDs of all renderings:
for (var int i = 0; i < element.data.size; i++) {
val data = element.data.get(i)
switch(data) {
KRenderingLibrary: {
// The library needs to generate ids for all later KRenderingRefs to refer to.
for (var int j = 0; j < data.renderings.size; j++) {
val rendering = data.renderings.get(j)
if (rendering instanceof KRendering) {
KRenderingIdGenerator.generateIdsRecursive(rendering, "$$lib$$", j)
}
}
}
KRenderingRef: {
// rendering refs refer to the referred ID
data.renderingId = kGraphToSGraph.get(element)?.id + data.rendering.renderingId
}
KRendering: {
// every rendering needs an ID, generate it here
KRenderingIdGenerator.generateIdsRecursive(data, kGraphToSGraph.get(element)?.id + "$$", i)
}
}
}

// Recursively call this method for every child KGraphElement of this.
// (all labels, child nodes, outgoing edges and ports)

if (element instanceof KLabeledGraphElement) {
for (label : element.labels) {
prepareRenderingIDs(label, kGraphToSGraph)
}
}
if (element instanceof KNode) {
// Do not recurse generating IDs if the element is not expanded, as there won't be any SGraph generated for
// it.
var boolean isExpanded
val renderingContextData = RenderingContextData.get(element)
if (renderingContextData.hasProperty(SprottyProperties.EXPANDED)) {
isExpanded = renderingContextData.getProperty(SprottyProperties.EXPANDED)
} else {
// If the expanded property does not exist yet, use the initial expansion.
isExpanded = element.getProperty(KlighdProperties.EXPAND)
}

if (isExpanded) {
for (node : element.children) {
prepareRenderingIDs(node, kGraphToSGraph)
}
}
for (edge : element.outgoingEdges) {
// not expanded => edge must not have the target node inside the non-expanded
if (isExpanded || !KGraphUtil.isDescendant(edge.target, element)) {
prepareRenderingIDs(edge, kGraphToSGraph)
}
}
for (port : element.ports) {
prepareRenderingIDs(port, kGraphToSGraph)
}
}

// Also prepare the IDs of all proxy-renderings
val proxyRendering = element.getProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING)
if (element.getProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY) && proxyRendering !== null) {
for (var int i = 0; i < proxyRendering.size; i++) {
val data = proxyRendering.get(i)
switch(data) {
KRenderingRef: {
// rendering refs refer to the referred ID
data.renderingId = kGraphToSGraph.get(element)?.id + data.rendering.renderingId
}
KRendering: {
// every rendering needs an ID, generate it here
KRenderingIdGenerator.generateIdsRecursive(data, kGraphToSGraph.get(element)?.id + "$$", i)
}
}
}
}
}

/**
* Prepares a KGraphElement to be rendered in an external viewer.
Expand All @@ -74,29 +161,18 @@ final class RenderingPreparer {
* In case of a {@link KRenderingRef} the bounds and decoration are persisted for every referenced rendering as a map
* inside the properties of the reference.
* For example: &lt;id of the rendering in the library: bounds in this instance&gt;
* Furthermore, for every rendering a unique ID is generated.
* Finally, modifiable styles defined by the synthesis are processed for the rendering.
*
* @param element The parent element containing the graph to calculate all rendering bounds for.
* @param kGraphToSGraph A map for identifying the SGraph element for each KGraph element in this graph.
*/
static def void prepareRendering(KGraphElement element, Map<KGraphElement, SModelElement> kGraphToSGraph) {
static def void prepareRenderingLayout(KGraphElement element, Map<KGraphElement, SModelElement> kGraphToSGraph) {
// calculate the sizes of all renderings:
for (var int i = 0; i < element.data.size; i++) {
val data = element.data.get(i)
switch(data) {
KRenderingLibrary: {
// The library needs to generate ids for all later KRenderingRefs to refer to, but no own bounds,
// since these are generic renderings.
for (var int j = 0; j < data.renderings.size; j++) {
val rendering = data.renderings.get(j)
if (rendering instanceof KRendering) {
KRenderingIdGenerator.generateIdsRecursive(rendering, "$$lib$$", j)
}
}
}
KRenderingRef: {
// all references to KRenderings need to place a map with the ids of the renderings and their
// all references to KRenderings need to place a map with their
// sizes and their decoration in this case in the properties of the reference.
var boundsMap = new HashMap<String, Bounds>
var decorationMap = new HashMap<String, Decoration>
Expand All @@ -105,12 +181,8 @@ final class RenderingPreparer {
data.properties.put(CALCULATED_BOUNDS_MAP, boundsMap)
// and the decorationMap
data.properties.put(CALCULATED_DECORATION_MAP, decorationMap)
// remember the id of the rendering in the reference
data.renderingId = kGraphToSGraph.get(element)?.id + data.rendering.renderingId
}
KRendering: {
// every rendering needs an ID, generate it here
KRenderingIdGenerator.generateIdsRecursive(data, kGraphToSGraph.get(element)?.id + "$$", i)
handleKRendering(element, data, null, null)
}
}
Expand All @@ -121,7 +193,7 @@ final class RenderingPreparer {

if (element instanceof KLabeledGraphElement) {
for (label : element.labels) {
prepareRendering(label, kGraphToSGraph)
prepareRenderingLayout(label, kGraphToSGraph)
}
}
if (element instanceof KNode) {
Expand All @@ -138,17 +210,17 @@ final class RenderingPreparer {

if (isExpanded) {
for (node : element.children) {
prepareRendering(node, kGraphToSGraph)
prepareRenderingLayout(node, kGraphToSGraph)
}
}
for (edge : element.outgoingEdges) {
// not expanded => edge must not have the target node inside the non-expanded
if (isExpanded || !KGraphUtil.isDescendant(edge.target, element)) {
prepareRendering(edge, kGraphToSGraph)
prepareRenderingLayout(edge, kGraphToSGraph)
}
}
for (port : element.ports) {
prepareRendering(port, kGraphToSGraph)
prepareRenderingLayout(port, kGraphToSGraph)
}
}

Expand All @@ -168,13 +240,9 @@ final class RenderingPreparer {
data.properties.put(CALCULATED_BOUNDS_MAP, boundsMap)
// and the decorationMap
data.properties.put(CALCULATED_DECORATION_MAP, decorationMap)
// remember the id of the rendering in the reference
data.renderingId = kGraphToSGraph.get(element)?.id + data.rendering.renderingId

}
KRendering: {
// every rendering needs an ID, generate it here
KRenderingIdGenerator.generateIdsRecursive(data, kGraphToSGraph.get(element)?.id + "$$", i)
if (data.eContainer instanceof KNode) {
// Calculate the size and layout of the proxy first.
val parent = data.eContainer as KNode
Expand Down
Loading