GNU PIC で ステートチャート図

GNU PIC でステートチャート図 を書く。

GNU PIC でステートチャート図

.ps 14 # font size
.PS
scale = 2.54; # inch -> cm
arrowwid=0.5;
arrowhead=0;

define folk {[
    line right thick 2;
    move to last line.start;
    line left thick 2;
]}

define join {[
    folk();
]}

define frame {
    top_mergin = $2;
    bottom_mergin = $3;
    left_mergin = $4;
    right_mergin = $5;

    line from $1.nw + (-left_mergin, top_mergin) to $1.ne + (right_mergin, top_mergin);
    line from $1.sw + (-left_mergin, -bottom_mergin) to $1.se + (right_mergin, -bottom_mergin);
    line from $1.nw + (-left_mergin, top_mergin) to $1.sw + (-left_mergin, -bottom_mergin);
    line from $1.ne + (right_mergin, top_mergin) to $1.se + (right_mergin, -bottom_mergin);
}

define state {[
    box $1 ht $2 wid $3 invisible;
    line from last box.se to last box.sw;
    line from last box.sw to last box.nw -(0, 0.5);
    line from last box.se to last box.ne -(0, 0.5);
    line from last box.nw +(0.5, 0) to last box.ne +(-0.5, 0)
    arc from last line.start to 3rd last line.end;
    arc cw from last line.end to 2rd last line.end;

    box $4 ht $5 wid last box.wid with .ne at last box.se invisible;
    line from last box.nw to last box.sw +(0, 0.5);
    line from last box.ne to last box.se +(0, 0.5);
    line from last box.sw +(0.5, 0) to last box.se +(-0.5, 0)
    arc cw from last line.start to 3rd last line.end;
    arc from last line.end to 2rd last line.end;
]}

define spawn {[
    circle fill 1;
]}

define finish {[
    circle rad 0.5 fill 1;
    circle with .c at last circle.c;
]}

down;
Start: spawn();
Event1: arrow "" ljust;
State1: state("state1", 1, 6, \
                "entry/entry action" "do/repeat action" "exit/exit action" "event/internal state action", 2);
Event2: arrow "event[guard condition]/action"  ljust;

Folk: folk();
line down from 1/2 <Folk.s, Folk.sw>;
line left 4;
arrow down;
State2: state("state2", 1, 4, "", 1);
move to Folk.center + (-6, -6);
{
    up;
    arc from State2.w;
    arc;
    arrowwid=0.5; arrowhead=0;
    arc to State2.w ->;
}

line down from 1/2 <Folk.s, Folk.se>;
A: line right 4;
SubState: [
    down;
    spawn();
    arrow;
    State3: state("state3", 1, 4, "", 1);
    arrow;
    finish();
] with .n at A.end + (0, -(movewid + 1));
"sub state" at SubState.n + (0, 0.4);
frame(SubState, 1, 0.5, 1, 1);
arrow down from A.end;

move to (Folk.s.x, SubState.s.y - 0.5 - movewid * 2);
Join: join();

line up from 1/2 <Join.n, Join.nw> <-;
line left to (State2.s.x, last line.end.y);
line to State2.s;

line up from 1/2 <Join.n, Join.ne> <-;
line right to (SubState.s.x, last line.end.y);
line to SubState.s + (0, -0.5);

move to Join.s;
arrow down;
Finish: finish();

.PE