Skip to content

Commit

Permalink
Make general control flow regions work
Browse files Browse the repository at this point in the history
  • Loading branch information
phschaad committed Dec 13, 2023
1 parent 2a93f04 commit 7b1fb51
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 51 deletions.
3 changes: 3 additions & 0 deletions sdfv.css
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,9 @@ pre.code code {
--loop-background-color: #ffffff;
--loop-background-simple-color: #e0e0e0;
--loop-foreground-color: #000000;
--control-flow-region-background-color: #ffffff;
--control-flow-region-background-simple-color: #e0e0e0;
--control-flow-region-foreground-color: #000000;
--interstate-edge-color: #86add9;
--connector-scoped-color: #c1dfe690;
--connector-unscoped-color: #f0fdff;
Expand Down
3 changes: 2 additions & 1 deletion src/renderer/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3362,7 +3362,7 @@ function relayoutStateMachine(
blockInfo.width = Math.max(
maxLabelWidth, ctx.measureText(block.label).width
) + 3 * LoopRegion.META_LABEL_MARGIN;
} else if (blockElem instanceof State) {
} else {
blockInfo.width = ctx.measureText(blockInfo.label).width;
}
} else {
Expand Down Expand Up @@ -3866,6 +3866,7 @@ function relayoutSDFGBlock(
): DagreSDFG | null {
switch (block.type) {
case SDFGElementType.LoopRegion:
case SDFGElementType.ControlFlowRegion:
return relayoutStateMachine(
ctx, block as StateMachineType, sdfg, sdfgList, stateParentList,
omitAccessNodes, parent
Expand Down
191 changes: 141 additions & 50 deletions src/renderer/renderer_elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,147 @@ export class BasicBlock extends SDFGElement {
}

export class ControlFlowRegion extends ControlFlowBlock {

public static readonly META_LABEL_MARGIN: number = 5;

public draw(
renderer: SDFGRenderer, ctx: CanvasRenderingContext2D,
_mousepos?: Point2D
): void {
const topleft = this.topleft();
const visibleRect = renderer.get_visible_rect();

let clamped;
if (visibleRect)
clamped = {
x: Math.max(topleft.x, visibleRect.x),
y: Math.max(topleft.y, visibleRect.y),
x2: Math.min(
topleft.x + this.width, visibleRect.x + visibleRect.w
),
y2: Math.min(
topleft.y + this.height, visibleRect.y + visibleRect.h
),
w: 0,
h: 0,
};
else
clamped = {
x: topleft.x,
y: topleft.y,
x2: topleft.x + this.width,
y2: topleft.y + this.height,
w: 0,
h: 0,
};
clamped.w = clamped.x2 - clamped.x;
clamped.h = clamped.y2 - clamped.y;
if (!(ctx as any).lod)
clamped = {
x: topleft.x, y: topleft.y, x2: 0, y2: 0,
w: this.width, h: this.height
};

// Draw the region's background below everything and stroke the border.
ctx.fillStyle = this.getCssProperty(
renderer, '--control-flow-region-background-color'
);
ctx.strokeStyle = this.getCssProperty(
renderer, '--control-flow-region-foreground-color'
);
ctx.fillRect(clamped.x, clamped.y, clamped.w, clamped.h);
ctx.strokeRect(clamped.x, clamped.y, clamped.w, clamped.h);
ctx.fillStyle = this.getCssProperty(
renderer, '--control-flow-region-foreground-color'
);

if (visibleRect && visibleRect.x <= topleft.x &&
visibleRect.y <= topleft.y + SDFV.LINEHEIGHT &&
SDFVSettings.showStateNames)
ctx.fillText(
this.label(), topleft.x + LoopRegion.META_LABEL_MARGIN,
topleft.y + SDFV.LINEHEIGHT
);

// If this state is selected or hovered
if ((this.selected || this.highlighted || this.hovered) &&
(clamped.x === topleft.x ||
clamped.y === topleft.y ||
clamped.x2 === topleft.x + this.width ||
clamped.y2 === topleft.y + this.height)) {
ctx.strokeStyle = this.strokeStyle(renderer);
ctx.strokeRect(clamped.x, clamped.y, clamped.w, clamped.h);
}

// If collapsed, draw a "+" sign in the middle
if (this.attributes().is_collapsed) {
ctx.beginPath();
ctx.moveTo(this.x, this.y - SDFV.LINEHEIGHT);
ctx.lineTo(this.x, this.y + SDFV.LINEHEIGHT);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(this.x - SDFV.LINEHEIGHT, this.y);
ctx.lineTo(this.x + SDFV.LINEHEIGHT, this.y);
ctx.stroke();
}

ctx.strokeStyle = 'black';
}

public simple_draw(
renderer: SDFGRenderer, ctx: CanvasRenderingContext2D,
mousepos?: Point2D
): void {
// Fast drawing function for small states
const topleft = this.topleft();

ctx.fillStyle = this.getCssProperty(
renderer, '--control-flow-region-background-simple-color'
);
ctx.fillRect(topleft.x, topleft.y, this.width, this.height);
ctx.fillStyle = this.getCssProperty(
renderer, '--control-flow-region-foreground-color'
);

if (mousepos && this.intersect(mousepos.x, mousepos.y))
renderer.set_tooltip((c) => this.tooltip(c));
}

public shade(
_renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, color: string,
alpha: number = 0.4
): void {
// Save the current style properties.
const orig_fill_style = ctx.fillStyle;
const orig_alpha = ctx.globalAlpha;

ctx.globalAlpha = alpha;
ctx.fillStyle = color;

const topleft = this.topleft();
ctx.fillRect(topleft.x, topleft.y, this.width, this.height);

// Restore the previous style properties.
ctx.fillStyle = orig_fill_style;
ctx.globalAlpha = orig_alpha;
}

public tooltip(container: HTMLElement): void {
container.innerText = 'Loop: ' + this.label();
}

public attributes(): any {
return this.data.block.attributes;
}

public label(): string {
return this.data.block.label;
}

public type(): string {
return this.data.block.type;
}

}

export class State extends BasicBlock {
Expand Down Expand Up @@ -387,8 +528,6 @@ export class State extends BasicBlock {

export class LoopRegion extends ControlFlowRegion {

public static readonly META_LABEL_MARGIN: number = 5;

public static get CONDITION_SPACING(): number {
return 3 * SDFV.LINEHEIGHT;
}
Expand Down Expand Up @@ -588,58 +727,10 @@ export class LoopRegion extends ControlFlowRegion {
ctx.strokeStyle = 'black';
}

public simple_draw(
renderer: SDFGRenderer, ctx: CanvasRenderingContext2D,
mousepos?: Point2D
): void {
// Fast drawing function for small states
const topleft = this.topleft();

ctx.fillStyle = this.getCssProperty(
renderer, '--loop-background-simple-color'
);
ctx.fillRect(topleft.x, topleft.y, this.width, this.height);
ctx.fillStyle = this.getCssProperty(renderer, '--loop-foreground-color');

if (mousepos && this.intersect(mousepos.x, mousepos.y))
renderer.set_tooltip((c) => this.tooltip(c));
}

public shade(
_renderer: SDFGRenderer, ctx: CanvasRenderingContext2D, color: string,
alpha: number = 0.4
): void {
// Save the current style properties.
const orig_fill_style = ctx.fillStyle;
const orig_alpha = ctx.globalAlpha;

ctx.globalAlpha = alpha;
ctx.fillStyle = color;

const topleft = this.topleft();
ctx.fillRect(topleft.x, topleft.y, this.width, this.height);

// Restore the previous style properties.
ctx.fillStyle = orig_fill_style;
ctx.globalAlpha = orig_alpha;
}

public tooltip(container: HTMLElement): void {
container.innerText = 'Loop: ' + this.label();
}

public attributes(): any {
return this.data.block.attributes;
}

public label(): string {
return this.data.block.label;
}

public type(): string {
return this.data.block.type;
}

}

export class SDFGNode extends SDFGElement {
Expand Down

0 comments on commit 7b1fb51

Please sign in to comment.