Skip to content

Commit

Permalink
Fix vertical layout without clear source node (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
phschaad authored Aug 22, 2023
1 parent d19b843 commit 3f44fa6
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 7 deletions.
21 changes: 15 additions & 6 deletions src/layouter/state_machine/sm_layouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ export class SMLayouter {
private readonly rankHeights: Map<number, number>;
private readonly dummyChains: Set<[SMLayouterEdge, string[]]>;

public constructor(g: DiGraph<SMLayouterNode, SMLayouterEdge>) {
public constructor(
g: DiGraph<SMLayouterNode, SMLayouterEdge>, startState?: string
) {
this.graph = g;

this.rankDict = new Map();
Expand Down Expand Up @@ -114,7 +116,10 @@ export class SMLayouter {
for (const s of sources)
this.graph.addEdge(this.startNode, s, { points: [] });
} else if (sources.length === 0) {
throw new Error('State machine has no sources.');
if (startState === undefined)
throw new Error('State machine has no sources.');
else
this.startNode = startState;
} else {
this.startNode = sources[0];
}
Expand Down Expand Up @@ -179,14 +184,16 @@ export class SMLayouter {
* performing the layout.
* @param {DagreSDFG} dagreGraph Dagre.js graph to perform layouting for.
*/
public static layoutDagreCompat(dagreGraph: DagreSDFG): void {
public static layoutDagreCompat(
dagreGraph: DagreSDFG, startState?: string
): void {
const g = new DiGraph<SMLayouterNode, SMLayouterEdge>();
for (const stateId of dagreGraph.nodes())
g.addNode(stateId, dagreGraph.node(stateId));
for (const edge of dagreGraph.edges())
g.addEdge(edge.v, edge.w, dagreGraph.edge(edge));

SMLayouter.layout(g);
SMLayouter.layout(g, startState);
}

/**
Expand Down Expand Up @@ -235,11 +242,13 @@ export class SMLayouter {
* Lay out a DiGraph.
* @param {DiGraph<SMLayouterNode, SMLayouterEdge>} g Graph to lay out.
*/
private static layout(g: DiGraph<SMLayouterNode, SMLayouterEdge>): void {
private static layout(
g: DiGraph<SMLayouterNode, SMLayouterEdge>, startState?: string
): void {
// Construct a layouter instance (runs preparation phase) and perform
// the laying out. Clean up afterwards by removing dummy start and end
// nodes if they were added.
const instance = new SMLayouter(g);
const instance = new SMLayouter(g, startState);
instance.doLayout();
if (instance.startNode === ARTIFICIAL_START)
g.removeNode(ARTIFICIAL_START);
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3302,7 +3302,7 @@ function relayout_sdfg(
// Fall back to dagre for anything that cannot be laid out with
// the vertical layout (e.g., irreducible control flow).
try {
SMLayouter.layoutDagreCompat(g);
SMLayouter.layoutDagreCompat(g, sdfg.start_state?.toString());
} catch (_ignored) {
dagre.layout(g);
}
Expand Down

0 comments on commit 3f44fa6

Please sign in to comment.