packages feed

cpsa-4.4.1: doc/src/strands.mp

% Strand macros

%% John D. Ramsdell--May 2008,
%% The MITRE Corporation, Bedford, MA.

% For simple drawings, use the strand macro.

% Use these macros when drawing strand edges.  The cmstrands package
% redefines these two macros.

% Draw a message edge
def drawmsg(expr p) =
  drawarrow p;
enddef;

% Draw a strand succession edge.  The arrow head is drawn, not filled.
% Based on "Hints and Tricks" in TUGboat, Volume 19 (1998), No. 2, by
% Jeremy Gibbons.
def drawsucc(expr p) =
  draw arrowhead p;
  path q;
  q := fullcircle scaled (2*ahlength)
    shifted (point (length p) of p);
  numeric tp, tq;
  (tp,tq) = p intersectiontimes q;
  draw subpath (0, tp) of p;
enddef;

% Draw a message edge with a dashed line.  Used sometimes for when the
% source and the distination message differ.
def drawdashedmsg(expr p) =
  drawarrow p dashed evenly scaled 3;
enddef;

% Strand drawing macros

% Box the nodes of a strand.  The origin of the strand is the center
% of the last strand node.  The name is a picture for the first node,
% and node is a picture for the successive nodes.
vardef boxstrand@#(expr height, origin, name, node) =
  boxit.@#1(name);
  for i = 2 upto height:
    boxit.@#[i](node);
    xpart @#[i-1].s = xpart @#[i].n;
  endfor;
  @#[height].c = origin;
enddef;

% Space a pair of strand nodes using the given height and separation
% delta.
vardef spacestrand@#(expr pos, delta) =
  ypart @#[pos].s = delta + ypart @#[pos+1].n;
enddef;

% Layout strand by making the distance been successive nodes the given
% separation delta.
vardef layoutstrand@#(expr height, delta) =
  for i = 1 upto height - 1:
    spacestrand@#(i, delta);
  endfor;
enddef;

% Link the nodes of a strand.
vardef linkstrand@#(expr height) =
  for i = 2 upto height:
    drawsucc(@#[i-1].s -- @#[i].n);
  endfor;
enddef;

% Draw a strand with equally spaced nodes.  The origin of the strand
% is the center of the last strand node.  The the distance between
% successive nodes is delta.  The name is a picture for the first
% node, and node is a picture for the successive nodes.

% A strand is drawn bottom up because the size of the label in the
% first box may vary.

vardef strand@#(expr height, origin, delta, name, node) =
  boxstrand@#(height, origin, name, node);
  layoutstrand@#(height, delta);
  for i = height downto 1:
    draw pic @#[i];
  endfor;
  linkstrand@#(height);
enddef;

% layout a strand but don't draw it.
vardef phantomstrand@#(expr height, origin, delta, name, node) =
  boxstrand@#(height, origin, name, node);
  layoutstrand@#(height, delta);
  for i = height downto 1:
    fixsize(@#[i]);
  endfor;
enddef;

% Event macros used while displaying roles.

% Draw an inbound term at a given strand position.
% The width is the length of the first arrow.
vardef inbnd@#(expr pos, width, term) =
  pair d;
  d = (xpart @#[1].e + width, ypart @#[pos].e);
  drawmsg(d .. @#[pos].e);
  label.rt(term, d);
enddef;

% Draw an outbound term at a given strand position.
% The width is the length of the first arrow.
vardef outbnd@#(expr pos, width, term) =
  pair d;
  d = (xpart @#[1].e + width, ypart @#[pos].e);
  drawmsg(@#[pos].e .. d);
  label.rt(term, d);
enddef;

% Reverse versions:
vardef rinbnd@#(expr pos, width, term) =
  pair d;
  d = (xpart @#[1].w - width, ypart @#[pos].w);
  drawmsg(d .. @#[pos].w);
  label.lft(term, d);
enddef;

vardef routbnd@#(expr pos, width, term) =
  pair d;
  d = (xpart @#[1].w - width, ypart @#[pos].w);
  drawmsg(@#[pos].w .. d);
  label.lft(term, d);
enddef;