%% MSC Macro Package %% msc.sty %% June 2, 2008 %% %% Copyright 2008 V. Bos, T. van Deursen, and S. Mauw % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % This work has the LPPL maintenance status `maintained'. % % The Current Maintainer of this work is T. van Deursen. % % This program consists of the files % msc.sty % manual.tex % manual.pdf % refman.tex % refman.pdf % biblio.bib % maintenance.tex % maintenance.pdf % README % COPYRIGHT % % Contact address: % Ton van Deursen % Universit\'e du Luxembourg % Facult\'e des Sciences, de la Technologie et de la Communication % 6, rue Richard Coudenhove-Kalergi % L-1359 Luxembourg % Email: ton.vandeursen@uni.lu % Updates via: http://satoss.uni.lu/mscpackage/ % \def\mscdate{2008/06/02}% update this whenever this file changes \def\mscversion{1.16}% update this whenever a new version is ready \NeedsTeXFormat{LaTeX2e}% \ProvidesPackage{msc}[\mscdate, v\mscversion] \typeout{msc version \mscversion. (\mscdate)} \RequirePackage{color,pstricks,calc,ifthen} % % mscunit: the unit of msc lengths \def\mscunit{cm}% \def\setmscunit#1{\gdef\mscunit{#1}} % % % % msc lengths % First the customizable lengths: \newlength{\actionheight}% height of action symbols \newlength{\actionwidth}% width of action symbol \newlength{\bottomfootdist}% distance between bottom of foot symbol and frame \newlength{\msccommentdist}% distance of comment to its instance \newlength{\conditionheight}% height of condition symbols \newlength{\conditionoverlap}% overlap of condition symbol \newlength{\envinstdist}% distance between environments and nearest instance line \newlength{\firstlevelheight}% height of level just below head symbols \newlength{\hmscconditionheight}% height of hmsc condition symbol \newlength{\hmscconditionwidth}% width of hmsc condition symbol \newlength{\hmscconnectionradius}% radius of hmsc connection symbols \newlength{\hmscreferenceheight}% height of hmsc reference symbol \newlength{\hmscreferencewidth}% width of hmsc reference symbol \newlength{\hmscstartsymbolwidth}% width of hmsc start symbol \newlength{\inlineoverlap}% overlap of inline symbol \newlength{\instbarwidth}% default width of vertical instance bars \newlength{\instdist}% distance between (vertical) instance lines \newlength{\instfootheight}% height of foot symbols \newlength{\instheadheight}% height of head symbols \newlength{\instwidth}% width of header and foot symbols \newlength{\labeldist}% distance between labels and message lines or head symbol boxes \newlength{\lastlevelheight}% height of level just above foot symbols \newlength{\leftnamedist}% distance between left of frame and (top of) msc title \newlength{\levelheight}% height of a level \newlength{\lostsymbolradius}% radius of the lost and found symbols \newlength{\markdist}% distance between mark and its instance \newlength{\measuredist}% user definable length for horizontal measure distance \newlength{\measuresymbolwidth}% width of measure symbols \newlength{\mscdocreferenceheight}% minimal height of mscdoc reference \newlength{\mscdocreferencewidth}% minimal width of mscdoc reference \newlength{\referenceoverlap}% overlap of reference symbol \newlength{\regionbarwidth}% width of region bars \newlength{\selfmesswidth}% length of horizontal arms of self messages \newlength{\stopwidth}% width of the stop symbol \newlength{\timerwidth}% width of the timer symbols \newlength{\topheaddist}% distance between top of head symbols and frame \newlength{\topnamedist}% distance between top of frame and (top of) msc title % % Now the internal lengths \newlength{\tmp@X} \newlength{\tmp@Y} \newlength{\tmp@Xa} \newlength{\tmp@Ya} \newlength{\tmp@Xb} \newlength{\tmp@Yb} \newlength{\tmp@Xc} \newlength{\tmp@Yc} \newlength{\tmp@Xd} \newlength{\tmp@Yd} \newlength{\msc@currentheight} \newlength{\msc@currentwidth} \newlength{\msc@totalwidth} \newlength{\msc@totalheight} \newlength{\msc@commentdist}% distance of comment to its instance % % \newcommand{\msc@incrcounter}[1]{\addtocounter{#1}{1}}% % % internal box \newsavebox{\tmp@box} % % some internal offsets \def\msc@leveloffset{0}% \def\mscscalefactor{1}% \newcommand{\setmscscale}[1]{\def\mscscalefactor{#1}}% % % Command to change the footer color (legal values are black, gray, % lightgray, and white) \def\setfootcolor#1{\def\msc@footcolor{#1}} % % And some internal counters \newcounter{mscinstcnt} \newcounter{tmpcnt} % % \messlabelpos defines the position of message labels. % The default value is "l" (left) other value(s) are "r" (right) \def\timerpos{l} % % \msc@timerpos is the internal variant of \timerpos % This internal variant is used by the actual drawing commands for self messages \def\msc@timerpos{l} % % \msc@settimerpos sets the internal \mes@timerpos \def\msc@settimerpos#1{ \ifthenelse{\not\(\equal{#1}{l} \or \equal{#1}{r}\)}{% \msc@unknowntimerposerr{#1}}{% else \def\msc@timerpos{#1}% }% } % % \dummyinst{#1} (\dummyinst*{#1}) declares a dummy msc-instance and does not % draws its head symbol nor its instance axis until an instance create/start is % encountered. The starred version declares a fat instance. % #1: nickname that can be used in \mess -like commands % \def\dummyinst{\@ifstar{\msc@dummyinststar}{\msc@dummyinstnostar}} \def\msc@dummyinstnostar#1{% \msc@makedummyinst{\the\instbarwidth}{#1}% } \def\msc@dummyinststar#1{% \msc@makedummyinst{\the\instwidth}{#1}% } \def\msc@makedummyinst#1#2{% \@ifundefined{mscinst#2}{% \ifthenelse{\value{mscinstcnt}=2}{% Aha: this is the first msc instance, so, add the \addtolength{\msc@currentwidth}{\envinstdist}% left \envinstdist to \msc@currentwidth }{%not the first instance , so add the instdist to the \mec@currentwidth \addtolength{\msc@currentwidth}{\instdist}% }% and update x-pos of right environment \setlength{\tmp@X}{\msc@currentwidth+\envinstdist}% \msc@setinstxpos{envright}{\the\tmp@X}% % make an instance with empty inside name and empty above name: \msc@declinst{#2}{\relax}{\relax}{#1}% % make y-pos undefined, to make sure that no instance line will be drawn \msc@setinstypos{#2}{undefined}% --added sm }{% else: nickname #2 already defined! \msc@nicknamedefinederr{#2}% }% } % % \declinst[*] declares a new msc-instance and draws its head symbol % the starred versions makes a fat instance. % #1: nickname that can be used in \mess % #2: name of the instance (above instance head symbol) % #3: name of the instance (inside instance head symbol) % % \def\declinst{\@ifstar{\msc@declinststar}{\msc@declinstnostar}} % % Some commands are defined as well (INSTNR is the arabic % representation of the instance number): % \instabname#1: `above name' of instance with nickname #1 % \instinname#1: `inside name' of instance with nickname #1 % \instnicknameINSTNR: returns the nickname of instance INSTNR % \instxposINSTNR: returns the x-position of instance with nickname #1 % \instyposINSTNR: returns the last y-position of instance with nickname #1 % \instlinestyle#1: the line style (dashed or solid) of instance with nickname #1 \def\msc@declinstnostar#1#2#3{% user command to declare instances \msc@dummyinstnostar{#1}% %\inststart{#1}{#2}{#3}% % define above name and inside name \expandafter\def\csname instabname#1\endcsname{#2}% `above name' \expandafter\def\csname instinname#1\endcsname{#3}% `inside name' % draw the instance header symbol \msc@drawinstanceheadsymbol{#1}{\the\topheaddist}% % redefine the instance's y position \setlength{\tmp@Y}{\topheaddist+\instheadheight}% \msc@setinstypos{#1}{\the\tmp@Y}% } % \def\msc@declinststar#1#2#3{% user command to declare instances \msc@dummyinststar{#1}% % define above name and inside name \expandafter\def\csname instabname#1\endcsname{#2}% `above name' \expandafter\def\csname instinname#1\endcsname{#3}% `inside name' % draw the instance header symbol \msc@drawinstanceheadsymbol{#1}{\the\topheaddist}% % redefine the instance's y position \setlength{\tmp@Y}{\topheaddist+\instheadheight}% \msc@setinstypos{#1}{\the\tmp@Y}% } % % \msc@declinst: internal command to declare instances. % Some commands are defined as well (INSTNR is the arabic % representation of the instance number): % \instabnameINSTNR: returns the instance above name of #1 % \instnicknameINSTNR: returns the nickname of instance #1 % \instxposINSTNR: returns the x-position of instance with nickname #1 % \instyposINSTNR: returns the last y-position of instance with nickname #1 % \instlinestyle#1: the line style (dashed or solid) of instance with nickname #1 % \instregionstyle#1: the region style (normal, coregion, suspension, or activation) \def\msc@declinst#1#2#3#4{% internal command to declare instances \@ifundefined{mscinst#1}{% \@namedef{mscinst#1}{\relax}% \expandafter\def\csname instabname#1\endcsname{#2}% `above name' \expandafter\def\csname instinname#1\endcsname{#3}% `inside name' \expandafter\def\csname instbarwidth#1\endcsname{#4}% width of the vertical instance bar % the x position of an instance, \instxpos#1, is stored as a string, not as % a TeX-length, since that would use up too much of TeX limited number of % length-registers. % However, this means we first have to calculate the x-pos, and then % assign the string representation of the result to \instxpos#1: \setlength{\tmp@X}{\msc@currentwidth}% \expandafter\edef\csname instxpos#1\endcsname{\the\tmp@X}% \ifthenelse{\lengthtest{\instbarwidth < #4}}% {% \expandafter\def\csname instisfat#1\endcsname{true}% \setlength{\tmp@Xa}{#4}% \addtolength{\tmp@X}{-.5\tmp@Xa}% \expandafter\edef\csname instlxpos#1\endcsname{\the\tmp@X}% \addtolength{\tmp@X}{\tmp@Xa}% \expandafter\edef\csname instrxpos#1\endcsname{\the\tmp@X}% }% {% \expandafter\def\csname instisfat#1\endcsname{false}% \expandafter\edef\csname instlxpos#1\endcsname{\the\tmp@X}% \expandafter\edef\csname instrxpos#1\endcsname{\the\tmp@X}% }% \expandafter\def\csname instnickname\arabic{mscinstcnt}\endcsname{#1}% \setlength{\tmp@Y}{\msc@currentheight}% \expandafter\edef\csname instypos#1\endcsname{\the\tmp@Y}% \expandafter\def\csname instlinestyle#1\endcsname{solid}% \expandafter\def\csname instfootcolor#1\endcsname{\msc@footcolor}% \expandafter\def\csname instregionstyle#1\endcsname{normal}% \msc@incrcounter{mscinstcnt}% }{% else, #1 already defined \msc@nicknamedefinederr{#1}% }% } % % \msc@instnickname gets the nickname of msc instance with number #1 % (This macro is used in \msc@drawinstancelevels) \def\msc@instnickname#1{% \csname instnickname\arabic{#1}\endcsname% } % \msc@instabname gets the above name of instance #1 \def\msc@instabname#1{% \csname instabname#1\endcsname% } % \msc@instinname gets the inside name of instance #1 \def\msc@instinname#1{% \csname instinname#1\endcsname% } % % \msc@instxpos gets the x position (i.e., horizontal position) of the % msc instance with nickname #1. \def\msc@instxpos#1{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \expandafter\csname instxpos#1\endcsname}% } % % \def\msc@instlxpos#1{ \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \expandafter\csname instlxpos#1\endcsname}% } % \def\msc@instrxpos#1{ \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \expandafter\csname instrxpos#1\endcsname}% } % % \msc@setinstxpos sets the (l/r) x position of instance with nickname #1 to % the string #2 \def\msc@setinstxpos#1#2{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \expandafter\edef\csname instxpos#1\endcsname{#2}% \expandafter\edef\csname instlxpos#1\endcsname{#2}% \expandafter\edef\csname instrxpos#1\endcsname{#2}% }% } % \def\msc@setinstlxpos#1#2{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \expandafter\edef\csname instlxpos#1\endcsname{#2}% }% } % \def\msc@setinstrxpos#1#2{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \expandafter\edef\csname instrxpos#1\endcsname{#2}% }% } % % \msc@instypos gets the last y position (i.e., vertical position) of the % msc instance with nickname #1. \def\msc@instypos#1{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \csname instypos#1\endcsname}% } % % \msc@setinstypos sets the last y position of instance with nickname #1 to % the string #2 \def\msc@setinstypos#1#2{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \expandafter\edef\csname instypos#1\endcsname{#2}% }% } % % Change \instlinestyle command of msc instance with nickname #1 into #2 % #2 should be one of: solid, dashed, or dotted \def\msc@setinstlinestyle#1#2{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \ifthenelse{\not\(\equal{#2}{solid} \or \equal{#2}{dashed} \or \equal{#2}{dotted}\)}{% unknown linestyle \msc@unknownlinestyleerr{#2}}{% \expandafter\def\csname instlinestyle#1\endcsname{#2}% }% }% } % % \msc@instlinestyle returns the linestyle of instance with nickname #1 \def\msc@instlinestyle#1{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \csname instlinestyle#1\endcsname}% } % % Change the foot color for instance with nickname #1 into #2 \def\msc@setinstfootcolor#1#2{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \expandafter\def\csname instfootcolor#1\endcsname{#2}% }% } % % \msc@instfootcolor returns the color of the footer of instance with nicknam #1 \def\msc@instfootcolor#1{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \csname instfootcolor#1\endcsname}% } % % Change \instregionstyle command of msc instance with nickname #1 into #2 % #2 should be one of: normal, coregion, suspension, or activation \def\msc@setinstregionstyle#1#2{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \ifthenelse{\not\(\equal{#2}{normal} \or \equal{#2}{coregion} \or \equal{#2}{suspension} \or \equal{#2}{activation}\)} {% unknown region style \msc@unknownregionstyleerr{#2} }{% \expandafter\def\csname instregionstyle#1\endcsname{#2}% }% \ifthenelse{\equal{#2}{suspension} \or \equal{#2}{activation}} {% \ifthenelse{\equal{\msc@instisfat{#1}}{true}} {\relax} {% \setlength{\tmp@X}{\msc@instxpos{#1}}% \setlength{\tmp@Xa}{\regionbarwidth}% \addtolength{\tmp@X}{-.5\tmp@Xa}% \msc@setinstlxpos{#1}{\the\tmp@X}% \addtolength{\tmp@X}{\tmp@Xa}% \msc@setinstrxpos{#1}{\the\tmp@X}% } }{% new region style is normal or coregion \ifthenelse{\equal{\msc@instisfat{#1}}{true}}% {\relax}% {\msc@setinstbarwidth{#1}{\instbarwidth}% \msc@setinstlxpos{#1}{\msc@instxpos{#1}}% \msc@setinstrxpos{#1}{\msc@instxpos{#1}}% }% }% }% } % % \msc@instregionstyle returns the region style of instance with nickname #1 \def\msc@instregionstyle#1{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \csname instregionstyle#1\endcsname}% } % % \msc@instbarwidth returns the width of the bar of instance with nickname #1 \def\msc@instbarwidth#1{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \csname instbarwidth#1\endcsname}% } % % \msc@setinstbarwidth sets the width of the bar of instance with nickname #1 % to the string #2 \def\msc@setinstbarwidth#1#2{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \expandafter\edef\csname instbarwidth#1\endcsname{#2}% \ifthenelse{\lengthtest{\instbarwidth < #2}}% {\expandafter\def\csname instisfat#1\endcsname{true}}% {\expandafter\def\csname instisfat#1\endcsname{false}}% }% } % %\msc@isfateinst returns one of the strings `true' of `false', indicating if % the instance with nickname #1 is a fat instance. \def\msc@instisfat#1{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \csname instisfat#1\endcsname}% } % % % \changeinstbarwidth changes the instance width of instance with nickname #1 to % the length #2 \def\changeinstbarwidth#1#2{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}% {% else, #1 is defined \msc@drawinstanceline{#1}% \setlength{\tmp@X}{\msc@instxpos{#1}}% \setlength{\tmp@Y}{\msc@currentheight}% \msc@setinstypos{#1}{\the\tmp@Y}% \setlength{\tmp@Xb}{#2}% \ifthenelse{\lengthtest{\tmp@Xb > \instbarwidth}}% {% \setlength{\tmp@Xb}{0.5\tmp@Xb}% \addtolength{\tmp@Xb}{\tmp@X}}% {% \setlength{\tmp@Xb}{\tmp@X}}% \ifthenelse{\equal{true}{\msc@instisfat{#1}}} {% \setlength{\tmp@Xa}{\msc@instbarwidth{#1}}% \setlength{\tmp@Xa}{0.5\tmp@Xa}% \addtolength{\tmp@Xa}{\tmp@X}% }{% \setlength{\tmp@Xa}{\tmp@X}% }% \psline(\tmp@Xa,-\tmp@Y)(\tmp@Xb,-\tmp@Y)% \setlength{\tmp@Xb}{#2}% \ifthenelse{\lengthtest{\tmp@Xb > \instbarwidth}}% {% \setlength{\tmp@Xb}{-0.5\tmp@Xb}% \addtolength{\tmp@Xb}{\tmp@X}}% {% \setlength{\tmp@Xb}{\tmp@X}}% \ifthenelse{\equal{true}{\msc@instisfat{#1}}} {% \setlength{\tmp@Xa}{\msc@instbarwidth{#1}}% \setlength{\tmp@Xa}{-0.5\tmp@Xa}% \addtolength{\tmp@Xa}{\tmp@X}% }{% \setlength{\tmp@Xa}{\tmp@X}% }% \psline(\tmp@Xa,-\tmp@Y)(\tmp@Xb,-\tmp@Y)% \msc@setinstbarwidth{#1}{#2}% }% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % DUMMY INSTANCES (start and stop) % % Start a dummy inst % % \inststart{#1}{#2}{#3} % #1: nickname of stared instance % #2: name of the instance (above instance head symbol) % #3: name of the instance (inside instance head symbol) % \def\inststart#1#2#3{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined % set the above and inside names \expandafter\def\csname instabname#1\endcsname{#2}% `above name' \expandafter\def\csname instinname#1\endcsname{#3}% `inside name' % draw the instance header symbol \msc@drawinstanceheadsymbol{#1}{\the\msc@currentheight}% % redefine the instance's y position \setlength{\tmp@Y}{\msc@currentheight+\instheadheight}% \msc@setinstypos{#1}{\the\tmp@Y}% } } % % \inststop{#1} % #1: nick name of instance % % Draws the footer of #1 at current level. \def\inststop#1{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \addtolength{\msc@currentheight}{\lastlevelheight} \msc@drawinstanceline{#1}% \setlength{\tmp@Y}{\msc@currentheight}% \msc@drawinstancefootsymbol{#1}{\the\tmp@Y}% \addtolength{\msc@currentheight}{-\lastlevelheight} \msc@setinstypos{#1}{undefined} } } % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5 % % CREATE % % \create creates a new msc-instance and draws its head symbol % #1: text above creation message % #2: nickname of creating instance % #3: nickname of created instance % #4: name of the instance (above instance head symbol) % #5: name of the instance (inside instance head symbol) % % Some commands are defined as well (INSTNR is the arabic % representation of the instance number): % \instabname#3: `above name' of instance with nickname #3 % \instinname#3: `inside name' of instance with nickname #3 % \instlinestyle#3: the line style (dashed or solid) of instance with nickname #3 \newcommand{\create}{% \@ifstar% {\def\mess@style{mess}\def\mess@linsestyle{dashed}\create@A}{\def\mess@style{mess}\def\mess@linestyle{solid}\create@A}% }% \newcommand{\create@A}[1]{% \def\mess@labeltext{#1}% \create@B% } \newcommand{\create@B}[2][t]{% \def\mess@labelposition{#1}% \def\mess@sender{#2}% \create@C% } \newcommand{\create@C}[4][0.5]{% \def\mess@labelplacement{#1}% \def\mess@receiver{#2}% \def\mess@leveloffset{0}% \def\mess@instanceoffset{0.5\instwidth}% % \expandafter\@ifundefined{mscinst\mess@sender}{% \msc@instundefinederr{\mess@sender}}{% else, \mess@sender is defined \expandafter\@ifundefined{mscinst\mess@receiver}{% \msc@instundefinederr{\mess@receiver}}{% else, \mess@receiver is defined \expandafter\def\csname instabname\mess@receiver\endcsname{#3}% `above name' \expandafter\def\csname instinname\mess@receiver\endcsname{#4}% `inside name' % draw the instance header symbol \setlength{\tmp@X}{\msc@instxpos{\mess@receiver}}% x-center head box \setlength{\tmp@Y}{\msc@currentheight}% y-center head box \setlength{\tmp@Xa}{-0.5\instwidth+\tmp@X}% x-upperleft head box \setlength{\tmp@Ya}{\msc@currentheight-0.5\instheadheight}% \setlength{\tmp@Xb}{\tmp@Xa+\instwidth}% x-lowerright head box \setlength{\tmp@Yb}{\tmp@Ya+\instheadheight}% y-lowerright head box \psframe[dimen=middle](\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% \rput[B](\tmp@X,-\tmp@Ya){\raisebox{\labeldist}{\makebox[0pt][c]{#3}}}% \rput[B](\tmp@X,-\tmp@Y){\raisebox{-.5ex}{\makebox[0pt][c]{#4}}}% % redefine the instance's y position \setlength{\tmp@Y}{\msc@currentheight+0.5\instheadheight}% \msc@setinstypos{\mess@receiver}{\the\tmp@Y}% % draw creation arrow \msc@drawarrow% }% }% } % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % INLINE EXPRESSIONS (inlines) % % % \inlineestart creates an inline expression at the current level % [#1]: left overlap % [#2]: right overlap % #3: nickname of the inline % #4: text of the inline % #5: first instance of the inline % #6: final instance of the inline \newcommand{\inlinestart}[1][\inlineoverlap]{% \def\msc@leftoverlap{#1}\msc@inlinecont% } \newcommand{\msc@inlinecont}[5][\msc@leftoverlap]{\msc@declinline{\msc@leftoverlap}{#1}{#2}{#3}{#4}{#5}}% % % \inlineend draws and ends the inline expression with nickname #1 % \newcommand{\inlineend}{% \@ifstar{\msc@inlineends}{\msc@inlineend}} % % \inlineseparator draws a ``separator'' (horizontal dashed line) through % inline expression with nickname #1 \newcommand{\inlineseparator}[1]{% \expandafter\@ifundefined{mscinl#1}{% \msc@inlundefinederr{#1}}{% else, #1 is defined \setlength{\tmp@Y}{\msc@currentheight}% \psline[linestyle=dashed](\msc@inlulx{#1},-\tmp@Y)(\msc@inllrx{#1},-\tmp@Y)% }% } % % internal commands to implement the inline expressions: % #1: left overlap % #2: right overlap % #3: nickname of the inline % #4: text of the inline % #5: first instance of the inline % #6: final instance of the inline % \def\msc@declinline#1#2#3#4#5#6{% \@ifundefined{mscinl#3}{% \@ifundefined{mscinst#5}{% #5 is not an instance nickname \msc@instundefinederr{#5}}{% \@ifundefined{mscinst#6}{% #6 is not an instance nickname \msc@instundefinederr{#6}}{% \ifthenelse{\lengthtest{\msc@instxpos{#5}>\msc@instxpos{#6}}}{% \msc@inlfirstlasterror{#3}{#5}{#6}}{% \@namedef{mscinl#3}{\relax}% \expandafter\def\csname inltext#3\endcsname{\raisebox{\depth}[\totalheight][0pt]{#4}}% \ifthenelse{\equal{true}{\msc@instisfat{#5}}}% {% \setlength{\tmp@X}{\msc@instlxpos{#5}-#1}% }% {% \setlength{\tmp@X}{\msc@instxpos{#5}-#1}% }% \expandafter\edef\csname inlulx#3\endcsname{\the\tmp@X}% \expandafter\edef\csname inluly#3\endcsname{\the\msc@currentheight}% \ifthenelse{\equal{true}{\msc@instisfat{#6}}}% {% \setlength{\tmp@X}{\msc@instrxpos{#6}+#2}% }% {% \setlength{\tmp@X}{\msc@instxpos{#6}+#2}% }% \expandafter\edef\csname inllrx#3\endcsname{\the\tmp@X}% \expandafter\edef\csname inllry#3\endcsname{undefined}% % two additional instances are defined \msc@declinst{#3left}{\relax}{\relax}{\the\instbarwidth}% left of inline \msc@setinstxpos{#3left}{\msc@inlulx{#3}}% \msc@setinstlxpos{#3left}{\msc@inlulx{#3}}% \msc@setinstrxpos{#3left}{\msc@inlulx{#3}}% \msc@setinstypos{#3left}{undefined}% no instance line drawing \msc@declinst{#3right}{\relax}{\relax}{\the\instbarwidth}% left of inline \msc@setinstxpos{#3right}{\msc@inllrx{#3}}% \msc@setinstlxpos{#3right}{\msc@inllrx{#3}}% \msc@setinstrxpos{#3right}{\msc@inllrx{#3}}% \msc@setinstypos{#3right}{undefined}% no instance line drawing }% }% }% }{% nickname #3 already defined \msc@nicknamedefinederr{#3}% }% } % % \msc@inlulx gets the upper-left x-position of inline with nickname #1. \def\msc@inlulx#1{% \expandafter\@ifundefined{mscinl#1}{% \msc@inlundefinederr{#1}}{% else, #1 is defined \csname inlulx#1\endcsname% }% } % % \msc@inluly gets the upper-left y-position of inline with nickname #1. \def\msc@inluly#1{% \expandafter\@ifundefined{mscinl#1}{% \msc@inlundefinederr{#1}}{% else, #1 is defined \csname inluly#1\endcsname% }% } % % \msc@inllrx gets the lower-right x-position of inline with nickname #1. \def\msc@inllrx#1{% \expandafter\@ifundefined{mscinl#1}{% \msc@inlundefinederr{#1}}{% else, #1 is defined \csname inllrx#1\endcsname% }% } % % \msc@inllry gets the lower-right y-position of inline with nickname #1. \def\msc@inllry#1{% \expandafter\@ifundefined{mscinl#1}{% \msc@inlundefinederr{#1}}{% else, #1 is defined \csname inllry#1\endcsname% }% } % % \msc@inltext gets the text of inline with nickname #1 \def\msc@inltext#1{% \expandafter\@ifundefined{mscinl#1}{% \msc@inlundefinederr{#1}}{% else, #1 is defined \csname inltext#1\endcsname% }% } % % \msc@inlineend completes the inline with nickname #1 % (the bottom line is solid) \def\msc@inlineend#1{% \expandafter\@ifundefined{mscinl#1}{% \msc@inlundefinederr{#1}}{% else, #1 is defined \expandafter\edef\csname inllry#1\endcsname{\the\msc@currentheight}% \setlength{\tmp@Xa}{\msc@inlulx{#1}}% \setlength{\tmp@Ya}{\msc@inluly{#1}}% \setlength{\tmp@Xb}{\msc@inllrx{#1}}% \setlength{\tmp@Yb}{\msc@inllry{#1}}% %% Debug info: % \typeout{(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)}% \psframe[dimen=middle](\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% \settowidth{\tmp@X}{\msc@inltext{#1}}% \setlength{\tmp@X}{1.1\tmp@X+\labeldist}% \settoheight{\tmp@Y}{\msc@inltext{#1}}% \setlength{\tmp@Y}{1.1\tmp@Y+\labeldist}% \setlength{\tmp@Xb}{\tmp@X+\labeldist}% \setlength{\tmp@Yb}{\tmp@Y+\labeldist}% \rput(\tmp@Xa,-\tmp@Ya){% \rput[tl](\labeldist,-\labeldist){\msc@inltext{#1}}% \psline(0,-\tmp@Yb)(\tmp@X,-\tmp@Yb)(\tmp@Xb,-\tmp@Y)(\tmp@Xb,0)% }% }% } % % \msc@inlineends completes the inline with nickname #1 % (the bottom line is dashed) \def\msc@inlineends#1{% \expandafter\@ifundefined{mscinl#1}{% \msc@inlundefinederr{#1}}{% else, #1 is defined \expandafter\edef\csname inllry#1\endcsname{\the\msc@currentheight}% \setlength{\tmp@Xa}{\msc@inlulx{#1}}% \setlength{\tmp@Ya}{\msc@inluly{#1}}% \setlength{\tmp@Xb}{\msc@inllrx{#1}}% \setlength{\tmp@Yb}{\msc@inllry{#1}}% %% Debug info: % \typeout{(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)}% % first the solid part of the inline expression: \psline(\tmp@Xa,-\tmp@Yb)(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% % then the dashed bottom line: \psline[linestyle=dashed](\tmp@Xa,-\tmp@Yb)(\tmp@Xb,-\tmp@Yb) \settowidth{\tmp@X}{\msc@inltext{#1}}% \setlength{\tmp@X}{1.1\tmp@X+\labeldist}% \settoheight{\tmp@Y}{\msc@inltext{#1}}% \setlength{\tmp@Y}{1.1\tmp@Y+\labeldist}% \setlength{\tmp@Xb}{\tmp@X+\labeldist}% \setlength{\tmp@Yb}{\tmp@Y+\labeldist}% \rput(\tmp@Xa,-\tmp@Ya){% \rput[tl](\labeldist,-\labeldist){\msc@inltext{#1}}% \psline(0,-\tmp@Yb)(\tmp@X,-\tmp@Yb)(\tmp@Xb,-\tmp@Y)(\tmp@Xb,0)% }% }% } % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % REFERENCES % % % \referencestart creates an msc reference at the current level % [#1] : left overlap % [#2] : right overlap % #3: nickname of the reference % #4: text of the reference % #5: first instance of the reference % #6: final instance of the reference \newcommand{\referencestart}[1][\referenceoverlap]{% \def\msc@leftoverlap{#1}\msc@referencecont% } \newcommand{\msc@referencecont}[5][\referenceoverlap]{% \msc@declreference{\msc@leftoverlap}{#1}{#2}{#3}{#4}{#5}% \setcounter{tmpcnt}{0}% \msc@reffindfirst{#2}{\msc@drawtorefaux}% } % % \referenceend draws and ends the reference with nickname #1 \newcommand{\referenceend}[1]{% \msc@drawreference{#1}% \setcounter{tmpcnt}{0}% \setlength{\tmp@Y}{\msc@currentheight}% \msc@reffindfirst{#1}{\msc@refresetypos{\the\tmp@Y}}% } % % internal commands to implement references: % #1: left overlap % #2: right overlap % #3: nickname of the reference % #4: text of the reference % #5: first instance of the reference % #6: final instance of the reference % \def\msc@declreference#1#2#3#4#5#6{% \@ifundefined{mscref#3}{% \@ifundefined{mscinst#5}{% #5 is not an instance nickname \msc@instundefinederr{#5}}{% \@ifundefined{mscinst#6}{% #6 is not an instance nickname \msc@instundefinederr{#6}}{% \ifthenelse{\lengthtest{\msc@instxpos{#5}>\msc@instxpos{#6}}}{% \msc@reffirstlasterror{#3}{#5}{#6}}{% \@namedef{mscref#3}{\relax}% \expandafter\def\csname reftext#3\endcsname{#4}% \ifthenelse{\equal{true}{\msc@instisfat{#5}}}% {% \setlength{\tmp@X}{\msc@instlxpos{#5}-#1}% }% {% \setlength{\tmp@X}{\msc@instxpos{#5}-#1}% }% \expandafter\edef\csname refulx#3\endcsname{\the\tmp@X}% \expandafter\edef\csname refuly#3\endcsname{\the\msc@currentheight}% \ifthenelse{\equal{true}{\msc@instisfat{#6}}}% {% \setlength{\tmp@X}{\msc@instrxpos{#6}+#2}% }% {% \setlength{\tmp@X}{\msc@instxpos{#6}+#2}% }% \expandafter\edef\csname reflrx#3\endcsname{\the\tmp@X}% \expandafter\edef\csname reflry#3\endcsname{undefined}% \expandafter\def\csname reffirst#3\endcsname{#5}% \expandafter\def\csname reffinal#3\endcsname{#6}% % two additional instances are defined \msc@declinst{#3left}{\relax}{\relax}{\the\instbarwidth}% left of reference \msc@setinstxpos{#3left}{\msc@refulx{#3}}% \msc@setinstlxpos{#3left}{\msc@refulx{#3}}% \msc@setinstrxpos{#3left}{\msc@refulx{#3}}% \msc@setinstypos{#3left}{undefined}% no instance line drawing \msc@declinst{#3right}{\relax}{\relax}{\the\instbarwidth}% left of reference \msc@setinstxpos{#3right}{\msc@reflrx{#3}}% \msc@setinstlxpos{#3right}{\msc@reflrx{#3}}% \msc@setinstrxpos{#3right}{\msc@reflrx{#3}}% \msc@setinstypos{#3right}{undefined}% no instance line drawing }% }% }% }{% nickname #3 already defined \msc@nicknamedefinederr{#3}% }% } % % \msc@refulx gets the upper-left x-position of reference with nickname #1. \def\msc@refulx#1{% \expandafter\@ifundefined{mscref#1}{% \msc@refundefinederr{#1}}{% else, #1 is defined \csname refulx#1\endcsname% }% } % % \msc@refuly gets the upper-left y-position of reference with nickname #1. \def\msc@refuly#1{% \expandafter\@ifundefined{mscref#1}{% \msc@refundefinederr{#1}}{% else, #1 is defined \csname refuly#1\endcsname% }% } % % \msc@reflrx gets the lower-right x-position of reference with nickname #1. \def\msc@reflrx#1{% \expandafter\@ifundefined{mscref#1}{% \msc@refundefinederr{#1}}{% else, #1 is defined \csname reflrx#1\endcsname% }% } % % \msc@reflry gets the lower-right y-position of reference with nickname #1. \def\msc@reflry#1{% \expandafter\@ifundefined{mscref#1}{% \msc@refundefinederr{#1}}{% else, #1 is defined \csname reflry#1\endcsname% }% } % % \msc@reftext gets the text of reference with nickname #1 \def\msc@reftext#1{% \expandafter\@ifundefined{mscref#1}{% \msc@refundefinederr{#1}}{% else, #1 is defined \csname reftext#1\endcsname% }% } % % \msc@reftext gets the nickname of the first instance of the reference with nickname #1 \def\msc@reffirst#1{% \expandafter\@ifundefined{mscref#1}{% \msc@refundefinederr{#1}}{% else, #1 is defined \csname reffirst#1\endcsname% }% } % % \msc@reftext gets the nickname of the final instance of the reference with nickname #1 \def\msc@reffinal#1{% \expandafter\@ifundefined{mscref#1}{% \msc@refundefinederr{#1}}{% else, #1 is defined \csname reffinal#1\endcsname% }% } % % \msc@drawreference completes the reference with nickname #1 \def\msc@drawreference#1{% \expandafter\@ifundefined{mscref#1}{% \msc@refundefinederr{#1}}{% else, #1 is defined \expandafter\edef\csname reflry#1\endcsname{\the\msc@currentheight}% \setlength{\tmp@Xa}{\msc@refulx{#1}}% \setlength{\tmp@Ya}{\msc@refuly{#1}}% \setlength{\tmp@Xb}{\msc@reflrx{#1}}% \setlength{\tmp@Yb}{\msc@reflry{#1}}% %% Debug info: % \typeout{(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)}% \psframe[dimen=middle,framearc=0.25](\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% note: rounded corners \setlength{\tmp@X}{\tmp@Xb-\tmp@Xa}% \setlength{\tmp@Y}{\tmp@Yb-\tmp@Ya}% \rput(\tmp@Xa,-\tmp@Ya){% \rput[B](.5\tmp@X,-.5\tmp@Y){\raisebox{-.5ex}{\makebox[0pt][c]{\msc@reftext{#1}}}}% }% }% } % \def\msc@reffindfirst#1#2{% \ifthenelse{\value{tmpcnt} < \value{mscinstcnt}}{% % Debug info: % \typeout{(drawtoref) checking \msc@instnickname{tmpcnt}}% \ifthenelse{\equal{\msc@instnickname{tmpcnt}}{\msc@reffirst{#1}}}{% first instance found % Debug info: % \typeout{first found: \msc@instnickname{tmpcnt}}% #2{#1}}{% else, keep on looking \msc@incrcounter{tmpcnt}% \msc@reffindfirst{#1}{#2}}}{% done ! all instances checked }% } % \def\msc@drawtorefaux#1{% \ifthenelse{\value{tmpcnt} < \value{mscinstcnt}}{% % Debug info: % \typeout{(drawtorefaux) checking \msc@instnickname{tmpcnt}}% \msc@drawinstanceline{\msc@instnickname{tmpcnt}}% \msc@setinstypos{\msc@instnickname{tmpcnt}}{undefined}% \ifthenelse{\equal{\msc@instnickname{tmpcnt}}{\msc@reffinal{#1}}}{% final instance found % Debug info: % \typeout{final found: \msc@instnickname{tmpcnt}}% }{% else, non-final \msc@incrcounter{tmpcnt}% \msc@drawtorefaux{#1}}% }{% done ! all instances checked }% } % \def\msc@refresetypos#1#2{% \ifthenelse{\value{tmpcnt} < \value{mscinstcnt}}{% % Debug info: % \typeout{(drawtorefaux) checking \msc@instnickname{tmpcnt}} \msc@setinstypos{\msc@instnickname{tmpcnt}}{#1}% \ifthenelse{\equal{\msc@instnickname{tmpcnt}}{\msc@reffinal{#2}}}{% final instance found % Debug info: % \typeout{final found: \msc@instnickname{tmpcnt}}% }{% else, non-final \msc@incrcounter{tmpcnt}% \msc@refresetypos{#1}{#2}}% }{% done ! all instances checked }% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % CO-REGIONS % % \coregionstart starts a coregion on instance #1 (nickname) in the current level. \def\coregionstart#1{\regionstart{coregion}{#1}} % \coregionend ends a coregion on instance #1 (nickname) in the current level. \def\coregionend#1{\regionend{#1}}% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % REGIONS (normal, coregion, suspension, and activation) % % % \regionstart{#1}{#2} % starts a region % #1: region style: normal, coregion, suspension, or activation % #2: nickname: nick name of the instance \def\regionstart#1#2{% \expandafter\@ifundefined{mscinst#2}{% \msc@instundefinederr{#2}}{% else, #2 is defined \msc@drawinstanceline{#2}% \msc@setinstregionstyle{#2}{#1}% \msc@drawregionstart{#2}% }% } % % \regionend{#1} % ends the region of instance with nickname #1 \def\regionend#1{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \msc@drawinstanceline{#1}% \msc@drawregionend{#1}% \msc@setinstregionstyle{#1}{normal}% }% } % % \def\msc@drawregionstart#1{% \setlength{\tmp@Y}{\msc@currentheight}% \ifthenelse{\equal{\msc@instisfat{#1}}{true}} {% \setlength{\tmp@Xa}{\msc@instlxpos{#1}}% \setlength{\tmp@Xb}{\msc@instrxpos{#1}}% \psline(\tmp@Xa,-\tmp@Y)(\tmp@Xb,-\tmp@Y)% } {% \setlength{\tmp@Xa}{-.5\regionbarwidth+\msc@instxpos{#1}}% \setlength{\tmp@Xb}{.5\regionbarwidth+\msc@instxpos{#1}}% \psline(\tmp@Xa,-\tmp@Y)(\tmp@Xb,-\tmp@Y)% } \msc@setinstypos{#1}{\the\tmp@Y}% } % % \def\msc@drawregionend#1{% \setlength{\tmp@Y}{\msc@currentheight}% \ifthenelse{\equal{\msc@instisfat{#1}}{true}} {% \setlength{\tmp@Xa}{\msc@instlxpos{#1}}% \setlength{\tmp@Xb}{\msc@instrxpos{#1}}% \psline(\tmp@Xa,-\tmp@Y)(\tmp@Xb,-\tmp@Y)% } {\setlength{\tmp@Xa}{-.5\regionbarwidth+\msc@instxpos{#1}}% \setlength{\tmp@Xb}{.5\regionbarwidth+\msc@instxpos{#1}}% \psline(\tmp@Xa,-\tmp@Y)(\tmp@Xb,-\tmp@Y)% } \msc@setinstypos{#1}{\the\tmp@Y}% } % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MESSAGE ARROWS % % \messarrowscale sets the arrow scale \def\messarrowscale#1{\psset{arrowscale=#1}} % % \msc@setleveloffset sets the internal level offset \def\msc@setleveloffset#1{% \def\msc@leveloffset{#1}% } % \mess has one optional argument to define the position of % the label of a self message. \newcommand{\mess}{% \@ifstar% {\def\mess@style{mess}\def\mess@linestyle{dashed}\mess@A}{\def\mess@style{mess}\def\mess@linestyle{solid}\mess@A}% }% % \newcommand{\mess@A}[2][l]{% \def\selfmess@position{#1}% \def\mess@labeltext{#2}% \mess@B% }% \newcommand{\mess@B}[2][\ifx\mess@sender\mess@receiver \selfmess@position\else t\fi]{% \def\mess@labelposition{#1}% \def\mess@sender{#2}% \mess@C% } \newcommand{\mess@C}[2][0.5]{% \def\mess@labelplacement{#1}% \def\mess@receiver{#2}% \mess@D% } \newcommand{\mess@D}[1][\ifx\mess@sender\mess@receiver 1\else 0\fi]{% \edef\mess@leveloffset{#1}% \mess@E% } \newcommand{\mess@E}[1][0\mscunit]{% \edef\mess@instanceoffset{#1}% \msc@drawarrow% } \newcommand{\msc@drawarrow}{% \expandafter\@ifundefined{mscinst\mess@sender}{% \msc@instundefinederr{\mess@sender}}{% else, sender is defined \expandafter\@ifundefined{mscinst\mess@receiver}{% \msc@instundefinederr{\mess@receiver}}{% else, receiver is defined \ifx\mess@sender\mess@receiver\msc@drawselfarrow\else\msc@drawnonselfarrow\fi% }% }% } \newcommand{\msc@drawselfarrow}{% \ifthenelse{\equal{\selfmess@position}{l} \or% \equal{\selfmess@position}{r}% }{% \ifthenelse{\equal{\selfmess@position}{l}}% {% \setlength{\tmp@Xa}{\msc@instlxpos{\mess@sender} - \selfmesswidth}% \setlength{\tmp@Xb}{\tmp@Xa}% }{% ELSE \setlength{\tmp@Xa}{\msc@instrxpos{\mess@sender} + \selfmesswidth}% \setlength{\tmp@Xb}{\tmp@Xa}% }% \setlength{\tmp@Ya}{\msc@currentheight}% \setlength{\tmp@Yb}{\msc@currentheight + (\levelheight * \mess@leveloffset)}% \msc@computelabelcoords% \msc@computelabelspec% \rput[\msc@labelrefpoint](\tmp@X,-\tmp@Y){\msc@labelbox{\mess@labeltext}}% \ifthenelse{\equal{\selfmess@position}{l}}% {% \setlength{\tmp@Xa}{\msc@instlxpos{\mess@sender}}% \setlength{\tmp@Xc}{\msc@instlxpos{\mess@sender} - \mess@instanceoffset}% }{% ELSE \setlength{\tmp@Xa}{\msc@instrxpos{\mess@sender}}% \setlength{\tmp@Xc}{\msc@instrxpos{\mess@sender} + \mess@instanceoffset}% }% \ifthenelse{\equal{\mess@style}{mess}}% {% THEN message arrow \psline[linestyle=\mess@linestyle]{->}% (\tmp@Xa,-\tmp@Ya)% (\tmp@Xb,-\tmp@Ya)% (\tmp@Xb,-\tmp@Yb)% (\tmp@Xc,-\tmp@Yb)% }{% ELSE order arrow \setlength{\tmp@Yd}{.5\tmp@Yb + .5\tmp@Ya}% \psline[linestyle=\mess@linestyle]{->}% (\tmp@Xa,-\tmp@Ya)% (\tmp@Xb,-\tmp@Ya)% (\tmp@Xb,-\tmp@Yd)% \psline[linestyle=\mess@linestyle]% (\tmp@Xb,-\tmp@Yd)% (\tmp@Xb,-\tmp@Yb)% (\tmp@Xc,-\tmp@Yb)% }% }{% ELSE \msc@illegalselfmesspositionerr{\selfmess@position}% }% } \newcommand{\msc@drawnonselfarrow}{% \ifthenelse{\lengthtest{\msc@instxpos{\mess@sender} < \msc@instxpos{\mess@receiver}}}% {\setlength{\tmp@Xa}{\msc@instrxpos{\mess@sender}}% \setlength{\tmp@Xb}{\msc@instlxpos{\mess@receiver}}% \addtolength{\tmp@Xb}{-\mess@instanceoffset}}% {\setlength{\tmp@Xa}{\msc@instlxpos{\mess@sender}}% \setlength{\tmp@Xb}{\msc@instrxpos{\mess@receiver}}% \addtolength{\tmp@Xb}{\mess@instanceoffset}}% \setlength{\tmp@Ya}{\msc@currentheight}% \setlength{\tmp@Yb}{\msc@currentheight + (\levelheight * \mess@leveloffset)}% \msc@computelabelcoords% \msc@computelabelspec% \ifthenelse{\equal{\mess@style}{mess}}% {% THEN message arrow \psline[linestyle=\mess@linestyle]{->}% (\tmp@Xa,-\tmp@Ya)% (\tmp@Xb,-\tmp@Yb)% }{%ELSE order arrow \setlength{\tmp@Xd}{.5\tmp@Xb + .5\tmp@Xa}% \setlength{\tmp@Yd}{.5\tmp@Yb + .5\tmp@Ya}% \psline[linestyle=\mess@linestyle]{->}% (\tmp@Xa,-\tmp@Ya)% (\tmp@Xd,-\tmp@Yd)% \psline[linestyle=\mess@linestyle]% (\tmp@Xd,-\tmp@Yd)% (\tmp@Xb,-\tmp@Yb)% }% \rput[\msc@labelrefpoint](\tmp@X,-\tmp@Y){\msc@labelbox{\mess@labeltext}}% }% \newcommand{\msc@computelabelcoords}{% \ifthenelse{%\equal{t}{t}% \(\equal{\mess@sender}{\mess@receiver} \and \(\equal{\mess@labelposition}{l} \or% \equal{\mess@labelposition}{r}\)% \)% \or% \(\not\(\equal{\mess@sender}{\mess@receiver}\) \and \(\equal{\mess@labelposition}{t} \or% \equal{\mess@labelposition}{b}\)% \)% }{% THEN \ifthenelse{\lengthtest{\tmp@Xa<\tmp@Xb}}% {% THEN \ifthenelse{\lengthtest{\tmp@Ya<\tmp@Yb}}% {% THEN \setlength{\tmp@X}{\tmp@Xa + (\tmp@Xb - \tmp@Xa)*\real{\mess@labelplacement}}% \setlength{\tmp@Y}{\tmp@Ya + (\tmp@Yb - \tmp@Ya)*\real{\mess@labelplacement}}% }{% ELSE \setlength{\tmp@X}{\tmp@Xa + (\tmp@Xb - \tmp@Xa)*\real{\mess@labelplacement}}% \setlength{\tmp@Y}{\tmp@Yb + (\tmp@Ya - \tmp@Yb) + (\tmp@Yb - \tmp@Ya)*\real{\mess@labelplacement}}% }% }{% ELSE \ifthenelse{\lengthtest{\tmp@Xa>\tmp@Xb}}% {% THEN \ifthenelse{\lengthtest{\tmp@Ya<\tmp@Yb}}% {% THEN \setlength{\tmp@X}{\tmp@Xb + (\tmp@Xa - \tmp@Xb) + (\tmp@Xb - \tmp@Xa)*\real{\mess@labelplacement}}% \setlength{\tmp@Y}{\tmp@Ya + (\tmp@Yb - \tmp@Ya)*\real{\mess@labelplacement}}% }{% ELSE \setlength{\tmp@X}{\tmp@Xb + (\tmp@Xa - \tmp@Xb) + (\tmp@Xb - \tmp@Xa)*\real{\mess@labelplacement}}% \setlength{\tmp@Y}{\tmp@Yb + (\tmp@Ya - \tmp@Yb) + (\tmp@Yb - \tmp@Ya)*\real{\mess@labelplacement}}% }% }{% ELSE \tmpXa = \tmp@Xb (self message) \setlength{\tmp@X}{\tmp@Xa}% \ifthenelse{\lengthtest{\tmp@Ya<\tmp@Yb}}% {% \setlength{\tmp@Y}{\tmp@Ya + (\tmp@Yb - \tmp@Ya)*\real{\mess@labelplacement}}% }{% \setlength{\tmp@Y}{\tmp@Yb + (\tmp@Ya - \tmp@Yb) + (\tmp@Yb - \tmp@Ya)*\real{\mess@labelplacement}}}% }% }% }{% ELSE \msc@illegalmesslabelpositionerr{\mess@labelposition}% } } \newcommand{\msc@computelabelspec}{% \ifthenelse{\lengthtest{\tmp@Xa < \tmp@Xb}}% {% THEN W->E \ifthenelse{\lengthtest{\tmp@Ya < \tmp@Yb}}% {% THEN NW->SE \ifthenelse{\equal{\mess@labelposition}{t}}% {\def\msc@labelrefpoint{Bl} \addtolength{\tmp@X}{\labeldist}% \addtolength{\tmp@Y}{-\labeldist}% }% {\def\msc@labelrefpoint{tr} \addtolength{\tmp@X}{-\labeldist}% \addtolength{\tmp@Y}{\labeldist}% }% }{% ELSE \ifthenelse{\lengthtest{\tmp@Ya > \tmp@Yb}}% {% THEN SW -> NE \ifthenelse{\equal{\mess@labelposition}{t}}% {\def\msc@labelrefpoint{Br} \addtolength{\tmp@X}{-\labeldist}% \addtolength{\tmp@Y}{-\labeldist}% }% {\def\msc@labelrefpoint{tl} \addtolength{\tmp@X}{\labeldist}% \addtolength{\tmp@Y}{\labeldist}% }% }{% ELSE W->E \ifthenelse{\equal{\mess@labelposition}{t}}% {\def\msc@labelrefpoint{B} \addtolength{\tmp@X}{0\labeldist}% \addtolength{\tmp@Y}{-\labeldist}% }% {\def\msc@labelrefpoint{t} \addtolength{\tmp@X}{0\labeldist}% \addtolength{\tmp@Y}{\labeldist}% }% }% }% }{% ELSE \ifthenelse{\lengthtest{\tmp@Xa > \tmp@Xb}}% {% THEN E -> W \ifthenelse{\lengthtest{\tmp@Ya < \tmp@Yb}}% {% THEN NE -> SW \ifthenelse{\equal{\mess@labelposition}{t}}% {\def\msc@labelrefpoint{Br} \addtolength{\tmp@X}{-\labeldist}% \addtolength{\tmp@Y}{-\labeldist}% }% {\def\msc@labelrefpoint{tl} \addtolength{\tmp@X}{\labeldist}% \addtolength{\tmp@Y}{\labeldist}% }% }{% ELSE \ifthenelse{\lengthtest{\tmp@Ya > \tmp@Yb}}% {% THEN SE -> NW \ifthenelse{\equal{\mess@labelposition}{t}}% {\def\msc@labelrefpoint{Bl} \addtolength{\tmp@X}{\labeldist}% \addtolength{\tmp@Y}{-\labeldist}% }% {\def\msc@labelrefpoint{tr} \addtolength{\tmp@X}{-\labeldist}% \addtolength{\tmp@Y}{\labeldist}% }% }{% ELSE E -> W \ifthenelse{\equal{\mess@labelposition}{t}}% {\def\msc@labelrefpoint{B} \addtolength{\tmp@X}{0\labeldist}% \addtolength{\tmp@Y}{-\labeldist}% }% {\def\msc@labelrefpoint{t} \addtolength{\tmp@X}{0\labeldist}% \addtolength{\tmp@Y}{\labeldist}% }% } } }{% ELSE \tmp@Xa = \tmp@Xb (self message) \ifthenelse{\equal{\mess@labelposition}{l}}% {\def\msc@labelrefpoint{r} \addtolength{\tmp@X}{-\labeldist}% \addtolength{\tmp@Y}{0\labeldist}% }% {\def\msc@labelrefpoint{l} \addtolength{\tmp@X}{\labeldist}% \addtolength{\tmp@Y}{0\labeldist}% }% }% }% }% \newcommand{\msc@labelbox}[1]{{#1}}% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Genralized orders % \order[pos]{sender}{receiver}[leveloffset][instanceoffset] % \newcommand{\order}[3][l]{% \def\mess@style{order}% \def\mess@linestyle{dashed}% \def\selfmess@position{#1}% \def\mess@labelposition{\ifx\mess@sender\mess@receiver l\else t\fi}% \def\mess@labeltext{\relax}% \def\mess@labelplacement{0.5}% \def\mess@sender{#2}% \def\mess@receiver{#3}% \order@B% } \newcommand{\order@B}[1][\ifx\mess@sender\mess@receiver 1\else 0\fi]{% \edef\mess@leveloffset{#1}% \order@C% } \newcommand{\order@C}[1][0pt]{% \def\mess@instanceoffset{#1}% \msc@drawarrow% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % LOST and FOUND messages % % \lost[pos]{label}[labelpos]{gate}{sender}[placement] % \found[pos]{label}[labelpos]{gate}{sender}[placement] \newcommand{\lost}[1][l]{% \def\lostfound@position{#1}% %\def\msc@arrowdirection{->}% \def\lostfound@type{lost}% \def\msc@circlefillstyle{black}% \lostfound@B% } \newcommand{\found}[1][l]{% \def\lostfound@position{#1}% %\def\msc@arrowdirection{<-}% \def\lostfound@type{found}% \def\msc@circlefillstyle{white}% \lostfound@B% } \newcommand{\lostfound@B}[1]{% \def\mess@style{mess}% \def\mess@labeltext{#1}% \lostfound@C% } \newcommand{\lostfound@C}[3][t]{% \def\mess@labelposition{#1}% \def\mess@gate{#2}% \def\mess@sender{#3}% \lostfound@D% } \newcommand{\lostfound@D}[1][0.5]{% \def\mess@labelplacement{#1}% \@lostfound% } % % \@lostfound draws lost and found messages \def\@lostfound{% \expandafter\@ifundefined{mscinst\mess@sender}{% \msc@instundefinederr{\mess@sender}}{% else, \mess@sender is defined %\setlength{\tmp@Xa}{\msc@instxpos{\mess@sender}}% \setlength{\tmp@Ya}{\msc@currentheight}% \ifthenelse{\equal{\lostfound@position}{l}} {% THEN put lost/found message left \ifthenelse{\equal{\lostfound@type}{lost}}% {% THEN \setlength{\tmp@Xa}% start of arrow {\msc@instlxpos{\mess@sender}}% \setlength{\tmp@Xb}% end of arrow {\tmp@Xa-\selfmesswidth}% \setlength{\tmp@X}% label position {\tmp@Xb + (\tmp@Xa - \tmp@Xb) * \real{\mess@labelplacement}}% \setlength{\tmp@Xc}% circle position {\tmp@Xb-\lostsymbolradius}% }{% ELSE \setlength{\tmp@Xb}% end of arrow {\msc@instlxpos{\mess@sender}}% \setlength{\tmp@Xa}% start of arrow {\tmp@Xb-\selfmesswidth}% \setlength{\tmp@X}% label position {\tmp@Xa + (\tmp@Xb - \tmp@Xa) * \real{\mess@labelplacement}}% \setlength{\tmp@Xc}% circle position {\tmp@Xa-\lostsymbolradius}% }% \setlength{\tmp@Xd}% gate position {\tmp@Xc-\lostsymbolradius-\labeldist}% \def\msc@gaterefpoint{r}% }{% ELSE, lost/found message right \ifthenelse{\equal{\lostfound@type}{lost}}% {% THEN \setlength{\tmp@Xa}% start of arrow {\msc@instrxpos{\mess@sender}}% \setlength{\tmp@Xb}% end of arrow {\tmp@Xa+\selfmesswidth}% \setlength{\tmp@X}% label position {\tmp@Xa + (\tmp@Xb - \tmp@Xa) * \real{\mess@labelplacement}}% \setlength{\tmp@Xc}% circle position {\tmp@Xb+\lostsymbolradius}% }{% ELSE \setlength{\tmp@Xb}% end of arrow {\msc@instrxpos{\mess@sender}}% \setlength{\tmp@Xa}% start of arrow {\tmp@Xb+\selfmesswidth}% \setlength{\tmp@X}% label position {\tmp@Xb + (\tmp@Xa - \tmp@Xb) * \real{\mess@labelplacement}}% \setlength{\tmp@Xc}% circle position {\tmp@Xa+\lostsymbolradius}% }% \setlength{\tmp@Xd}% gate position {\tmp@Xc+\lostsymbolradius+\labeldist}% \def\msc@gaterefpoint{l}% }% \psline{->}(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Ya)% \ifthenelse{\equal{\mess@labelposition}{t}}% {% THEN \setlength{\tmp@Y}{\tmp@Ya-\lostsymbolradius-\labeldist}% \def\msc@labelrefpoint{B}% }{% ELSE \ifthenelse{\equal{\mess@labelposition}{b}}% {% THEN \setlength{\tmp@Y}{\tmp@Ya+\lostsymbolradius+\labeldist}% \def\msc@labelrefpoint{t}% }{% ELSE \msc@illegallostfoundlabelpositionerr{\mess@labelposition}% }% }% \rput[\msc@labelrefpoint](\tmp@X,-\tmp@Y){\mess@labeltext}% \edef\msc@scratch{\msc@circlefillstyle}% \pscircle[fillstyle=solid,fillcolor=\msc@scratch]% (\tmp@Xc,-\tmp@Ya){\lostsymbolradius} \rput[\msc@gaterefpoint](\tmp@Xd,-\tmp@Ya){\mess@gate}% }% } % % % \settimer has one optional argument to define the position of % the label of a self message. \newcommand{\settimer}[1][l]{% \msc@settimerpos{#1}% \@timer{set}% } % % % \timeout has one optional argument to define the position of % the label of a self message. \newcommand{\timeout}[1][l]{% \msc@settimerpos{#1}% \@timer{timeout}% } % % % \stoptimer has one optional argument to define the position of % the label of a self message. \newcommand{\stoptimer}[1][l]{% \msc@settimerpos{#1}% \@timer{stop}% } % % % \settimeout has one optional argument to define the position of % the label of a self message. \newcommand{\settimeout}[1][l]{% \msc@settimerpos{#1}% \@timerdispatcher{settimeout}% } % % % \setstoptimer has one optional argument to define the position of % the label of a self message. \newcommand{\setstoptimer}[1][l]{% \msc@settimerpos{#1}% \@timerdispatcher{setstoptimer}% } \def\@timerdispatcher#1#2#3{% \@ifnextchar[{\@oargtimerdispatcher{#1}{#2}{#3}}{\@nooargtimerdispatcher{#1}{#2}{#3}}} % \def\@oargtimerdispatcher#1#2#3[#4]{% \msc@setleveloffset{#4}% \@timer{#1}{#2}{#3}% } % \def\@nooargtimerdispatcher#1#2#3{% \msc@setleveloffset{2}% default level-offset value for combined timers \@timer{#1}{#2}{#3}% } % % % \@timer draws timers % #1: type of the timer (set/timeout/stop) % #2: label % #3: nickname of the instance \def\@timer#1#2#3{% \expandafter\@ifundefined{mscinst#3}{% \msc@instundefinederr{#3}}{% else, #3 is defined \setlength{\tmp@Xa}{\msc@instxpos{#3}}% \setlength{\tmp@Ya}{\msc@currentheight}% \ifthenelse{\equal{\msc@timerpos}{l}}{% point left of axis \ifthenelse{\equal{\msc@instisfat{#3}}{true}}{% \setlength{\tmp@Xa}{\msc@instlxpos{#3}}% }{% \relax% }% \setlength{\tmp@Xb}{\tmp@Xa-\selfmesswidth}% }{ % else point right of axis \ifthenelse{\equal{\msc@instisfat{#3}}{true}}{% \setlength{\tmp@Xa}{\msc@instrxpos{#3}}% }{% \relax% }% \setlength{\tmp@Xb}{\tmp@Xa+\selfmesswidth}% }% \ifthenelse{\equal{#1}{timeout}}{% draw an arrow \psline{<-}(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Ya)% }{ % else draw a line without arrow head \psline(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Ya)% }% \setlength{\tmp@X}{\tmp@Xb}% This looks clumsy - sm \setlength{\tmp@Y}{\tmp@Ya}% \msc@drawtimer{#1}{\tmp@X}{\tmp@Y}{\msc@timerpos}{#2}% \ifthenelse{\equal{#1}{settimeout}}{% draw second part of settimeout \setlength{\tmp@Ya}{\tmp@Y+\levelheight*\msc@leveloffset}% \setlength{\tmp@Y}{\tmp@Y+0.75\timerwidth}% \setlength{\tmp@Xa}{\msc@instxpos{#3}}% \ifthenelse{\equal{\msc@timerpos}{l}}{% point left of axis \ifthenelse{\equal{\msc@instisfat{#3}}{true}}{% \setlength{\tmp@Xa}{\msc@instlxpos{#3}}% }{% \relax% }% }{ % else point right of axis \ifthenelse{\equal{\msc@instisfat{#3}}{true}}{% \setlength{\tmp@Xa}{\msc@instrxpos{#3}}% }{% \relax% }% } \psline{->}(\tmp@X,-\tmp@Y)(\tmp@X,-\tmp@Ya)(\tmp@Xa,-\tmp@Ya)% }{ % else not settimeout \ifthenelse{\equal{#1}{setstoptimer}}{% draw second part of setstoptimer \setlength{\tmp@Ya}{\tmp@Y+\levelheight*\msc@leveloffset}% \setlength{\tmp@Y}{\tmp@Y+0.75\timerwidth}% \setlength{\tmp@Xb}{\msc@instxpos{#3}}% \ifthenelse{\equal{\msc@instisfat{#3}}{true}}{% \ifthenelse{\equal{\msc@timerpos}{l}}{% point left of axis \setlength{\tmp@Xb}{\msc@instlxpos{#3}}% }{% point right of axis \setlength{\tmp@Xb}{\msc@instrxpos{#3}}% }% }{% not a fat instance \relax% } \psline(\tmp@X,-\tmp@Y)(\tmp@X,-\tmp@Ya)(\tmp@Xb,-\tmp@Ya)% \setlength{\tmp@Y}{\tmp@Ya}% \msc@drawtimer{stop}{\tmp@X}{\tmp@Y}{\msc@timerpos}{}% }{ % else no second part needed }% }% }% } % % \msc@drawtimer draws the timer symbols % #1: type of the timer (set/timeout/stop) % #2: x-coordinate of center of timer % #3: y-coordinate of center of timer % #4: place text left (l) or right (r) % #5: text added to the timer \def\msc@drawtimer#1#2#3#4#5{% \setlength{\tmp@Xa}{#2-0.5\timerwidth}% \setlength{\tmp@Xb}{#2+0.5\timerwidth}% \ifthenelse{\equal{#1}{stop}}{% draw reset symbol \setlength{\tmp@Ya}{-#3+0.5\timerwidth}% \setlength{\tmp@Yb}{-#3-0.5\timerwidth}% \psline(\tmp@Xa,\tmp@Ya)(\tmp@Xb,\tmp@Yb)% \psline(\tmp@Xb,\tmp@Ya)(\tmp@Xa,\tmp@Yb)% }{% else draw set/timeout symbol \setlength{\tmp@Ya}{-#3+0.75\timerwidth}% \setlength{\tmp@Yb}{-#3-0.75\timerwidth}% \psline(\tmp@Xa,\tmp@Ya)(\tmp@Xb,\tmp@Yb)% (\tmp@Xa,\tmp@Yb)(\tmp@Xb,\tmp@Ya)(\tmp@Xa,\tmp@Ya)% }% \ifthenelse{\equal{#4}{l}}{% place label left \setlength{\tmp@Xa}{#2-\labeldist-0.3ex}% \setlength{\tmp@Ya}{-#3-0.5ex}% \rput[B](\tmp@Xa,\tmp@Ya){\makebox[0pt][r]{#5}} }{% else place label right \setlength{\tmp@Xa}{#2+\labeldist+0.3ex}% \setlength{\tmp@Ya}{-#3-0.5ex}% \rput[B](\tmp@Xa,\tmp@Ya){\makebox[0pt][l]{#5}}% }% } % % % \msc@drawinstancehead draws the head of the instance % #1: nickname of the instance \def\msc@drawinstancehead#1{% \setlength{\tmp@Y}{\msc@currentheight}% \msc@drawinstanceheadsymbol{#1}{\the\tmp@Y}% } % % \msc@drawinstanceheadsymbol draw the head symbol of instance #1 at y-pos #2 \def\msc@drawinstanceheadsymbol#1#2{% \setlength{\tmp@X}{\msc@instxpos{#1}}% x-center head box \setlength{\tmp@Y}{#2 + 0.5\instheadheight}% center of head symbol \setlength{\tmp@Xa}{-0.5\instwidth+\tmp@X}% x-upperleft head box \setlength{\tmp@Ya}{#2}% y-upperleft head box \setlength{\tmp@Xb}{\tmp@Xa+\instwidth}% x-lowerright head box \setlength{\tmp@Yb}{#2 + \instheadheight}% y-lowerright head box \ifthenelse{\equal{\msc@insthead}{yes}}{% \psframe[dimen=middle,linestyle=\msc@instlinestyle{#1}](\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% }{% else, no head symbol drawing% } \rput[B](\tmp@X,-\tmp@Ya){\raisebox{\labeldist}{\makebox[0pt][c]{\msc@instabname{#1}}}}% \rput[B](\tmp@X,-\tmp@Y){\raisebox{-.5ex}{\makebox[0pt][c]{\msc@instinname{#1}}}}% } % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \def\msc@drawinstanceline#1{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined \ifthenelse{\equal{\msc@instypos{#1}}{undefined}}{% y-pos undefined: no line needed }{% else \setlength{\tmp@Ya}{\msc@instypos{#1}}% \setlength{\tmp@Yb}{\msc@currentheight}% \ifthenelse{\equal{true}{\msc@instisfat{#1}}}% {% fat instance \setlength{\tmp@Xa}{\msc@instlxpos{#1}}% \setlength{\tmp@Xb}{\msc@instrxpos{#1}}% \ifthenelse{\equal{\msc@instregionstyle{#1}}{coregion}} {% \psline[linestyle=dashed](\tmp@Xa,-\tmp@Ya)(\tmp@Xa,-\tmp@Yb)% \psline[linestyle=dashed](\tmp@Xb,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% } {\ifthenelse{\equal{\msc@instregionstyle{#1}}{suspension}} {% \psline[linestyle=dashed,dash=7pt 7pt](\tmp@Xa,-\tmp@Ya)(\tmp@Xa,-\tmp@Yb)% \psline[linestyle=dashed,dash=7pt 7pt](\tmp@Xb,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% } {\ifthenelse{\equal{\msc@instregionstyle{#1}}{activation}} {% \psframe[dimen=middle,fillstyle=solid,fillcolor=lightgray](\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb) \psline[linestyle=solid](\tmp@Xa,-\tmp@Ya)(\tmp@Xa,-\tmp@Yb)% \psline[linestyle=solid](\tmp@Xb,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% } {% normal region: \psline[linestyle=solid](\tmp@Xa,-\tmp@Ya)(\tmp@Xa,-\tmp@Yb)% \psline[linestyle=solid](\tmp@Xb,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% } } } } {% normal instance (not fat) \setlength{\tmp@X}{\msc@instxpos{#1}}% \ifthenelse{\equal{\msc@instregionstyle{#1}}{coregion}} {% \psline[linestyle=dashed](\tmp@X,-\tmp@Ya)(\tmp@X,-\tmp@Yb)% } {\ifthenelse{\equal{\msc@instregionstyle{#1}}{suspension}} {% \setlength{\tmp@X}{\regionbarwidth} \setlength{\tmp@Xa}{\msc@instxpos{#1} - 0.5\tmp@X}% \setlength{\tmp@Xb}{\msc@instxpos{#1} + 0.5\tmp@X}% \psline[linestyle=dashed,dash=7pt 7pt](\tmp@Xa,-\tmp@Ya)(\tmp@Xa,-\tmp@Yb)% \psline[linestyle=dashed,dash=7pt 7pt](\tmp@Xb,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% } {\ifthenelse{\equal{\msc@instregionstyle{#1}}{activation}} {% \setlength{\tmp@X}{\regionbarwidth} \setlength{\tmp@Xa}{\msc@instxpos{#1} - 0.5\tmp@X}% \setlength{\tmp@Xb}{\msc@instxpos{#1} + 0.5\tmp@X}% \psframe[dimen=middle,fillstyle=solid,fillcolor=lightgray](\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb) \psline[linestyle=solid](\tmp@Xa,-\tmp@Ya)(\tmp@Xa,-\tmp@Yb)% \psline[linestyle=solid](\tmp@Xb,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% } {% normal region \psline[linestyle=\msc@instlinestyle{#1}](\tmp@X,-\tmp@Ya)(\tmp@X,-\tmp@Yb)% } } } }% }% }% }% % % \msc@drawinstancefoot draws the last level and foot of the instance % #1: nickname of the instance \def\msc@drawinstancefoot#1{% \setlength{\tmp@Y}{\msc@currentheight}% \msc@drawinstancefootsymbol{#1}{\the\tmp@Y}% } % % \msc@drawinstancefootsymbol draws a footer symbol for instance #1 at y-pos #2. \def\msc@drawinstancefootsymbol#1#2{% \setlength{\tmp@Xa}{-0.5\instwidth+\msc@instxpos{#1}}% \setlength{\tmp@Ya}{\msc@currentheight}% \setlength{\tmp@Xb}{\tmp@Xa+\instwidth}% \setlength{\tmp@Yb}{#2 + \instfootheight}% \ifthenelse{\equal{\msc@instfoot}{yes}}{ \edef\msc@scratch{\msc@instfootcolor{#1}}% \psframe[dimen=middle,fillstyle=solid,fillcolor=\msc@scratch,linestyle=\msc@instlinestyle{#1}](\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% }{% else, no foot symbol drawing% } } % % \nextlevel incresaes \msc@currentheight by #1 * \levelheight % (optional) #1: a nonnegative integer number (defaults to 1) % \newcommand{\nextlevel}[1][1]{% \addtolength{\msc@currentheight}{#1\levelheight}% } % \def\msc@drawinstancefooters{% \ifthenelse{\value{tmpcnt} < \value{mscinstcnt}}{% % Only draw the instancefoot if the instypos is defined (not ``undefined'') % This signals a previous instance stop. \ifthenelse{\equal{\msc@instypos{\msc@instnickname{tmpcnt}}}{undefined}}{\relax}{% \msc@drawinstanceline{\msc@instnickname{tmpcnt}}% \msc@drawinstancefoot{\msc@instnickname{tmpcnt}}% }% \msc@incrcounter{tmpcnt}% \msc@drawinstancefooters}{% else nothing }% }% % % \action puts an action symbol on the instance with nickname #2. % The action symbol will be placed on the current level and the text #1 % is centered inside the action symbol. The starred version adjusts the width % and height of the action symbol \def\action{\@ifstar{\msc@actionstar}{\msc@actionnostar}} \def\msc@actionstar#1#2{ \setlength{\tmp@Xc}{\actionwidth}% \setlength{\tmp@Yc}{\actionheight}% \savebox{\tmp@box}{#1} \setlength{\actionwidth}{\wd\tmp@box + 2\labeldist} \setlength{\actionheight}{\ht\tmp@box + \dp\tmp@box +2\labeldist} \msc@actionnostar{\usebox{\tmp@box}}{#2}% \setlength{\actionwidth}{\tmp@Xc}% \setlength{\actionheight}{\tmp@Yc}% } \def\msc@actionnostar#1#2{% \expandafter\@ifundefined{mscinst#2}{% \msc@instundefinederr{#2}}{% else, #2 is defined % first, draw the instance line as far as possible \msc@drawinstanceline{#2}% % then, draw the action symbol % if #2's bar width is greater than the action width, the width of this % action will be the instnce bar width. \ifthenelse{\lengthtest{\msc@instbarwidth{#2}<\actionwidth}}% {\setlength{\tmp@X}{\actionwidth}}% {\setlength{\tmp@X}{\msc@instbarwidth{#2}}}% \setlength{\tmp@Xa}{\msc@instxpos{#2}-0.5\tmp@X}% \setlength{\tmp@Xb}{\tmp@Xa+\tmp@X}% \setlength{\tmp@Ya}{\msc@currentheight}% \setlength{\tmp@Yb}{\tmp@Ya+\actionheight}% \psframe[dimen=middle](\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% \setlength{\tmp@X}{\msc@instxpos{#2}}% \setlength{\tmp@Y}{\tmp@Ya+0.5\actionheight}% \rput[B](\tmp@X,-\tmp@Y){\raisebox{-.5ex}{\makebox[0pt][c]{#1}}}% % redefine the instance's y position \setlength{\tmp@Y}{\msc@currentheight+\actionheight}% \msc@setinstypos{#2}{\the\tmp@Y}% }% } % % \stop ends the instance with nickname #1. \def\stop#1{% \expandafter\@ifundefined{mscinst#1}{% \msc@instundefinederr{#1}}{% else, #1 is defined % first, draw the instance line as far as possible \msc@drawinstanceline{#1}% \setlength{\tmp@Yb}{\msc@currentheight}% % close the instance axis if it is a fat instance \ifthenelse{\equal{true}{\msc@instisfat{#1}}}% {% \setlength{\tmp@Xa}{\msc@instlxpos{#1}}% \setlength{\tmp@Xb}{\msc@instrxpos{#1}}% \psline(\tmp@Xa,-\tmp@Yb)(\tmp@Xb,-\tmp@Yb)% }% {% else it is not fat }% % then, draw the stop symbol \setlength{\tmp@X}{\msc@instxpos{#1}}% \setlength{\tmp@Xa}{\tmp@X-0.5\stopwidth}% \setlength{\tmp@Xb}{\tmp@X+0.5\stopwidth}% \setlength{\tmp@Ya}{\tmp@Yb+0.5\stopwidth}% \setlength{\tmp@Yb}{\tmp@Yb-0.5\stopwidth}% \psline(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb)% \psline(\tmp@Xb,-\tmp@Ya)(\tmp@Xa,-\tmp@Yb)% % redefine the instance's y position % ``undefined'' means that the instance axis will not be drawn any further \msc@setinstypos{#1}{undefined}% }% } % % % \condition puts a condition symbol over the given instances. The % starred version adjusts the width and the height of the condition symbol. % #1: name to be put inside the condition symbol % #2: comma-separated list of instance nicknames, such that: % - The first instance nickname is supposed to be the leftmost % instance of the condition % - The last instance nickname is supposed to be the rightmost % instance of the condition \def\condition{\@ifstar{\msc@conditionstar}{\msc@conditionnostar}} \def\msc@conditionstar#1#2{ % \message{(msc: conditionheight: \msc@conditionheight, actionheight: \msc@actionheight)} \setlength{\tmp@Xd}{\conditionoverlap}% \setlength{\tmp@Yd}{\conditionheight}% \savebox{\tmp@box}{#1} \setlength{\conditionoverlap}{.5\wd\tmp@box + \labeldist} \setlength{\conditionheight}{\ht\tmp@box + \dp\tmp@box + 2\labeldist} \msc@conditionnostar{\usebox{\tmp@box}}{#2} % \settowidth{\conditionoverlap}{#1}% % \setlength{\conditionoverlap}{.5\conditionoverlap} % \settoheight{\conditionheight}{\rule{0pt}{\tmp@Yd-1ex} #1}% % \addtolength{\conditionheight}{1ex} % \msc@conditionnostar{#1}{#2}% \setlength{\conditionoverlap}{\tmp@Xd}% \setlength{\conditionheight}{\tmp@Yd}% } \def\msc@conditionnostar#1#2{ \def\msc@conditiontext{#1}% \def\msc@firstconditioninst{undefined}% \def\msc@lastconditioninst{undefined}% \msc@condition{#2}% % debugging info: % \message{(msc: condition: \msc@firstconditioninst...\msc@lastconditioninst)}% \ifthenelse{\equal{\msc@instisfat{\msc@firstconditioninst}}{true}}{% \setlength{\tmp@Xa}{\msc@instlxpos{\msc@firstconditioninst}-\conditionoverlap}% }{% \setlength{\tmp@Xa}{\msc@instxpos{\msc@firstconditioninst}-\conditionoverlap}% }% \setlength{\tmp@Ya}{\msc@currentheight}% \ifthenelse{\equal{\msc@instisfat{\msc@lastconditioninst}}{true}}{% \setlength{\tmp@Xb}{\msc@instrxpos{\msc@lastconditioninst}+\conditionoverlap}% }{% \setlength{\tmp@Xb}{\msc@instxpos{\msc@lastconditioninst}+\conditionoverlap}% }% \setlength{\tmp@Yb}{\tmp@Ya+\conditionheight}% \msc@drawcondition{#1}{\tmp@Xa}{\tmp@Ya}{\tmp@Xb}{\tmp@Yb}% } % \def\msc@condition#1{% \@for\msccondition@rg:=#1\do{% \expandafter\@ifundefined{mscinst\msccondition@rg}{% \msc@instundefinederr{\msccondition@rg}}{% else, \msccondition@rg is defined % debugging info: % \message{(msc: condition instance "\msccondition@rg")}% \ifthenelse{\equal{\msc@firstconditioninst}{undefined}}{% \edef\msc@firstconditioninst{\msccondition@rg}% }{\ifthenelse{\lengthtest{\msc@instxpos{\msc@firstconditioninst} > \msc@instxpos{\msccondition@rg}}}{% \edef\msc@firstconditioninst{\msccondition@rg}}{}% }% \ifthenelse{\equal{\msc@lastconditioninst}{undefined}}{% \edef\msc@lastconditioninst{\msccondition@rg}% }{\ifthenelse{\lengthtest{\msc@instxpos{\msc@lastconditioninst} < \msc@instxpos{\msccondition@rg}}}{% \edef\msc@lastconditioninst{\msccondition@rg}}{}% } % now, draw the instance line as far as possible \msc@drawinstanceline{\msccondition@rg}% % \setlength{\tmp@X}{\msc@instxpos{\msccondition@rg}}% % \setlength{\tmp@Ya}{\msc@instypos{\msccondition@rg}}% % \setlength{\tmp@Yb}{\msc@currentheight+\msc@headoffset}% % \psline[linestyle=\msc@instlinestyle{\msccondition@rg}](\tmp@X,-\tmp@Ya)(\tmp@X,-\tmp@Yb)% % and redefine the instance's y position \setlength{\tmp@Y}{\msc@currentheight+\conditionheight}% \msc@setinstypos{\msccondition@rg}{\the\tmp@Y}% }% }% } % % \msc@drawcondition draw the condition symbol % #1: condition-text \def\msc@drawcondition#1#2#3#4#5{% \setlength{\tmp@Xc}{#4+ .6#5 - .6#3}% \setlength{\tmp@Yc}{.5#3 + .5#5}% \psline(#2,-#3)(#4,-#3)(\tmp@Xc,-\tmp@Yc)(#4,-#5)% \setlength{\tmp@Xc}{#2- .6#5 + .6#3}% \psline(#4,-#5)(#2,-#5)(\tmp@Xc,-\tmp@Yc)(#2,-#3)% \setlength{\tmp@Xc}{.5#2 + .5#4}% \setlength{\tmp@Yc}{.5#3 + .5#5}% \rput[B](\tmp@Xc,-\tmp@Yc){\raisebox{-.5ex}{\makebox[0pt][c]{#1}}}% } % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % GATES % \gate[hpos][vpos]{text}{nickname}[h-offset] % \gate*[hpos][vpos]{text}{nickname}[h-offset] % (starred version puts a dot at the position of the gate on the instance line) % % hpos: optional horizontal position argument l(eft) or r(ight). default: l % vpos: optional vertical position argument t(op), c(enter) or b(ottom). default: t % text: text to be placed at the gate % nickname: nickname of the instance to which the gate belongs % \def\gate{\@ifstar{\def\msc@gatestar{defined}\msc@gateh}{\def\msc@gatestar{undefined}\msc@gateh}} \newcommand{\msc@gateh}[1][l]{% \def\msc@gatehpos{#1}% \msc@gatev% } % \newcommand{\msc@gatev}[3][t]{% \msc@gate{#1}{#2}{#3}% } % \def\msc@gate#1#2#3{% \expandafter\@ifundefined{mscinst#3}{% \msc@instundefinederr{#3}}{% else, #3 is defined \ifthenelse{\equal{\msc@instisfat{#3}}{true}} {\ifthenelse{\equal{\msc@gatehpos}{l}} {\setlength{\tmp@X}{\msc@instlxpos{#3}}} {\setlength{\tmp@X}{\msc@instrxpos{#3}}} }% {\setlength{\tmp@X}{\msc@instxpos{#3}}} \ifthenelse{\equal{\msc@gatestar}{defined}}{% \setlength{\tmp@Y}{\msc@currentheight}% \pscircle[fillstyle=solid,fillcolor=black](\tmp@X,-\tmp@Y){.5mm}}{}% \ifthenelse{\equal{t}{#1}}{ \setlength{\tmp@Y}{\msc@currentheight - \labeldist}% \def\msc@gatetext{{#2}}% }{% \ifthenelse{\equal{c}{#1}}{% \setlength{\tmp@Y}{\msc@currentheight}% \def\msc@gatetext{\raisebox{-.5\totalheight}{#2}}% }{% \setlength{\tmp@Y}{\msc@currentheight + \labeldist}% \def\msc@gatetext{\raisebox{-\totalheight}{#2}}% }}% \ifthenelse{\equal{l}{\msc@gatehpos}}{% \addtolength{\tmp@X}{-\labeldist}% \rput[B](\tmp@X,-\tmp@Y){\makebox[0pt][r]{\msc@gatetext}}}% {% \addtolength{\tmp@X}{\labeldist}% \rput[B](\tmp@X,-\tmp@Y){\makebox[0pt][l]{\msc@gatetext}}% }% } } % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MSC COMMENTS % % % \msccomment[#1]{#2}{#3} % #1: position l/r or a distance % #2: text % #3: instance nick name \newcommand{\msccomment}[3][l]{% \expandafter\@ifundefined{mscinst#3}{% \msc@instundefinederr{#3}} {% else, #3 is defined \ifthenelse{\equal{#1}{l}}% {\setlength{\msc@commentdist}{-\msccommentdist}}% {\ifthenelse{\equal{#1}{r}}% {\setlength{\msc@commentdist}{\msccommentdist}}% {\setlength{\msc@commentdist}{#1}}% } \savebox{\tmp@box}{\raisebox{\depth}[\totalheight][0pt]{#2}}% \setlength{\tmp@Y}{\msc@currentheight}% \setlength{\tmp@Ya}{\tmp@Y + .5\ht\tmp@box}% \addtolength{\tmp@Ya}{\labeldist}% \setlength{\tmp@Yb}{\tmp@Y - .5\ht\tmp@box}% \addtolength{\tmp@Yb}{-\labeldist}% % \message{( a: \the\tmp@Ya, b: \the\tmp@Yb)} \ifthenelse{\lengthtest{\msc@commentdist < 0pt}}% {% comment left from instance #3 \setlength{\tmp@X}{\msc@instlxpos{#3}} \setlength{\tmp@Xa}{\tmp@X + \msc@commentdist} \psline(\tmp@X,-\tmp@Y)(\tmp@Xa,-\tmp@Y) \psline(\tmp@Xa,-\tmp@Ya)(\tmp@Xa,-\tmp@Yb) \setlength{\tmp@Xb}{\wd\tmp@box} \setlength{\tmp@Xb}{\tmp@Xa - \tmp@Xb} \addtolength{\tmp@Xb}{-\labeldist} \psline(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Ya) \psline(\tmp@Xa,-\tmp@Yb)(\tmp@Xb,-\tmp@Yb) \addtolength{\tmp@Xa}{-\labeldist} \rput[r](\tmp@Xa,-\tmp@Y){#2}% }% {% comment right from instance #3 \setlength{\tmp@X}{\msc@instrxpos{#3}} \setlength{\tmp@Xa}{\tmp@X + \msc@commentdist} \psline(\tmp@X,-\tmp@Y)(\tmp@Xa,-\tmp@Y) \psline(\tmp@Xa,-\tmp@Ya)(\tmp@Xa,-\tmp@Yb) \setlength{\tmp@Xb}{\wd\tmp@box} \setlength{\tmp@Xb}{\tmp@Xa + \tmp@Xb} \addtolength{\tmp@Xb}{\labeldist} \psline(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Ya) \psline(\tmp@Xa,-\tmp@Yb)(\tmp@Xb,-\tmp@Yb) \addtolength{\tmp@Xa}{\labeldist} \rput[l](\tmp@Xa,-\tmp@Y){\usebox{\tmp@box}} }% }% } % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MSC MARKS % % \mark[#1]{#2}{#3} % #1: placement: tl,bl,tr,br % #2: text % #3: instance nick name % \newcommand{\mscmark}[3][tl]{% \expandafter\@ifundefined{mscinst#3}{% \msc@instundefinederr{#3}} {% else, #3 is defined \savebox{\tmp@box}{\raisebox{\depth}[\totalheight][0pt]{#2}} \ifthenelse{\equal{#1}{tl}} {%tl: \setlength{\tmp@X}{\msc@instlxpos{#3}} \setlength{\tmp@Xa}{\tmp@X - \markdist} \setlength{\tmp@Xb}{\tmp@Xa - \wd\tmp@box - 2\labeldist} \setlength{\tmp@Y}{\msc@currentheight} \setlength{\tmp@Ya}{\msc@currentheight - .5\markdist} \psline[linestyle=dashed](\tmp@X,-\tmp@Y)(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Ya) \setlength{\tmp@Xb}{\tmp@Xa - \labeldist - .5\wd\tmp@box} \addtolength{\tmp@Ya}{-\labeldist} \rput[b](\tmp@Xb,-\tmp@Ya){\usebox{\tmp@box}} }{ \ifthenelse{\equal{#1}{bl}} {%bl: \setlength{\tmp@X}{\msc@instlxpos{#3}} \setlength{\tmp@Xa}{\tmp@X - \markdist} \setlength{\tmp@Xb}{\tmp@Xa - \wd\tmp@box - 2\labeldist} \setlength{\tmp@Y}{\msc@currentheight} \setlength{\tmp@Ya}{\msc@currentheight + .5\markdist} \psline[linestyle=dashed](\tmp@X,-\tmp@Y)(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Ya) \setlength{\tmp@Xb}{\tmp@Xa - \labeldist - .5\wd\tmp@box} \addtolength{\tmp@Ya}{-\labeldist} \rput[b](\tmp@Xb,-\tmp@Ya){\usebox{\tmp@box}} }{ \ifthenelse{\equal{#1}{tr}} {%tr: \setlength{\tmp@X}{\msc@instrxpos{#3}} \setlength{\tmp@Xa}{\tmp@X + \markdist} \setlength{\tmp@Xb}{\tmp@Xa + \wd\tmp@box + 2\labeldist} \setlength{\tmp@Y}{\msc@currentheight} \setlength{\tmp@Ya}{\msc@currentheight - .5\markdist} \psline[linestyle=dashed](\tmp@X,-\tmp@Y)(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Ya) \setlength{\tmp@Xb}{\tmp@Xa + \labeldist + .5\wd\tmp@box} \addtolength{\tmp@Ya}{-\labeldist} \rput[b](\tmp@Xb,-\tmp@Ya){\usebox{\tmp@box}} }{ \ifthenelse{\equal{#1}{br}} {%br: \setlength{\tmp@X}{\msc@instrxpos{#3}} \setlength{\tmp@Xa}{\tmp@X + \markdist} \setlength{\tmp@Xb}{\tmp@Xa + \wd\tmp@box + 2\labeldist} \setlength{\tmp@Y}{\msc@currentheight} \setlength{\tmp@Ya}{\msc@currentheight + .5\markdist} \psline[linestyle=dashed](\tmp@X,-\tmp@Y)(\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Ya) \setlength{\tmp@Xb}{\tmp@Xa + \labeldist + .5\wd\tmp@box} \addtolength{\tmp@Ya}{-\labeldist} \rput[b](\tmp@Xb,-\tmp@Ya){\usebox{\tmp@box}} }{ \msc@illegalmarkplacement{#1} }}}}} } % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MSC MEASURES % % \newlength{\msc@measuredist}% internal length for horizontal measure distance % \measure[*][#1]{#2}{#3}{#4}[#5] % *: the starred version puts the top measure mark above and the bottom measure mark % below the measure position. % #1: placement: l (left) r (right), or distance (negative or positive) to closest of #3 or #4 % #2: name % #3: instance nick name % #4: instance nick name % #5: (vertical) offset \newcommand{\measure}{% \@ifstar{\def\msc@innermeasure{false}\msc@measureargs} {\def\msc@innermeasure{true}\msc@measureargs}% } % \newcommand{\msc@measureargs}[4][l]{% \def\msc@i{#1}% \def\msc@ii{#2}% \def\msc@iii{#3}% \def\msc@iv{#4}% \msc@measureoffset% } \newcommand{\msc@measureoffset}[1][1]{% \def\msc@mscv{#1}% \msc@measure{\msc@i}{\msc@ii}{\msc@iii}{\msc@iv}{\msc@mscv} } \newcommand{\msc@measure}[5]{% \ifthenelse{\equal{#1}{l}} {\setlength{\msc@measuredist}{-\measuredist}} {\ifthenelse{\equal{#1}{r}} {\setlength{\msc@measuredist}{\measuredist}} {\setlength{\msc@measuredist}{#1}}} % \setlength{\tmp@Ya}{\msc@currentheight} \setlength{\tmp@Yb}{\tmp@Ya + #5\levelheight} \setlength{\tmp@Y}{.5\tmp@Ya + .5\tmp@Yb} \ifthenelse{\lengthtest{\msc@instxpos{#3} < \msc@instxpos{#4}}} {% \ifthenelse{\lengthtest{\msc@measuredist < 0pt}} {% left from instances \setlength{\tmp@Xa}{\msc@instlxpos{#3}} \setlength{\tmp@Xb}{\msc@instlxpos{#4}} \setlength{\tmp@X}{\tmp@Xa + \msc@measuredist} } {% right from instances \setlength{\tmp@Xa}{\msc@instrxpos{#3}} \setlength{\tmp@Xb}{\msc@instrxpos{#4}} \setlength{\tmp@X}{\tmp@Xb + \msc@measuredist} } } {% \ifthenelse{\lengthtest{\msc@measuredist < 0pt}} {% left from instances \setlength{\tmp@Xa}{\msc@instlxpos{#3}} \setlength{\tmp@Xb}{\msc@instlxpos{#4}} \setlength{\tmp@X}{\tmp@Xb + \msc@measuredist} } {% right from instances \setlength{\tmp@Xa}{\msc@instrxpos{#3}} \setlength{\tmp@Xb}{\msc@instrxpos{#4}} \setlength{\tmp@X}{\tmp@Xa + \msc@measuredist} } } \psline[linestyle=dashed](\tmp@Xa,-\tmp@Ya)(\tmp@X,-\tmp@Ya)(\tmp@X,-\tmp@Yb)(\tmp@Xb,-\tmp@Yb) \ifthenelse{\lengthtest{\msc@measuredist < 0pt}} {% left from instances \addtolength{\tmp@X}{-\labeldist} \rput[r](\tmp@X,-\tmp@Y){\raisebox{\depth}[\totalheight][0pt]{#2}} \addtolength{\tmp@X}{\labeldist} } {% right from instances \addtolength{\tmp@X}{\labeldist} \rput[l](\tmp@X,-\tmp@Y){\raisebox{\depth}[\totalheight][0pt]{#2}} \addtolength{\tmp@X}{-\labeldist} } \ifthenelse{\equal{\msc@innermeasure}{true}} {% \msc@measuresymbolup{\tmp@X}{\tmp@Ya} \msc@measuresymboldown{\tmp@X}{\tmp@Yb} } {% \msc@measuresymboldown{\tmp@X}{\tmp@Ya} \msc@measuresymbolup{\tmp@X}{\tmp@Yb} } } % % % \measurestart[*][#1]{#2}{#3}{#4} % *: unstarred/starred version draws downward/upward triangle % #1: placement: l (left) r (right), or distance (negative or positive) to #3 % #2: name % #3: instance nick name % #4: gate name \newcommand{\measurestart}{% \@ifstar{\def\msc@innermeasure{false}\msc@measurestartargs} {\def\msc@innermeasure{true}\msc@measurestartargs} } % % \newcommand{\msc@measurestartargs}[4][l]{% \def\msc@i{#1}% \def\msc@ii{#2}% \def\msc@iii{#3}% \def\msc@iv{#4}% \msc@measurestartoffset% } \newcommand{\msc@measurestartoffset}[1][2]{% \msc@measurestart{\msc@i}{\msc@ii}{\msc@iii}{\msc@iv}{#1}% } % \newcommand{\msc@measurestart}[5]{% \ifthenelse{\equal{#1}{l}} {\setlength{\msc@measuredist}{-\measuredist}} {\ifthenelse{\equal{#1}{r}} {\setlength{\msc@measuredist}{\measuredist}} {\setlength{\msc@measuredist}{#1}}} \setlength{\tmp@Ya}{\msc@currentheight} \ifthenelse{\lengthtest{\msc@measuredist < 0pt}} {% left from instance \setlength{\tmp@Xa}{\msc@instlxpos{#3}} \setlength{\tmp@Xb}{\tmp@Xa + \msc@measuredist} \setlength{\tmp@Yb}{\tmp@Ya + #5\levelheight} \setlength{\tmp@X}{\tmp@Xb - \labeldist - 0.5\measuresymbolwidth} \setlength{\tmp@Y}{.5\tmp@Ya + .5\tmp@Yb} \rput[r](\tmp@X,-\tmp@Y){\raisebox{\depth}[\totalheight][0pt]{#2}} \setlength{\tmp@Y}{\tmp@Yb + \labeldist} \rput[r](\tmp@X,-\tmp@Yb){\raisebox{\depth}[\totalheight][0pt]{#4}} } {% right from instance \setlength{\tmp@Xa}{\msc@instrxpos{#3}} \setlength{\tmp@Xb}{\tmp@Xa + \msc@measuredist} \setlength{\tmp@Yb}{\tmp@Ya + #5\levelheight} \setlength{\tmp@X}{\tmp@Xb + \labeldist + 0.5\measuresymbolwidth} \setlength{\tmp@Y}{.5\tmp@Ya + .5\tmp@Yb} \rput[l](\tmp@X,-\tmp@Y){\raisebox{\depth}[\totalheight][0pt]{#2}} \setlength{\tmp@Y}{\tmp@Yb + \labeldist} \rput[l](\tmp@X,-\tmp@Yb){\raisebox{\depth}[\totalheight][0pt]{#4}} } \psline[linestyle=dashed](\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb) \ifthenelse{\equal{\msc@innermeasure}{true}} {\msc@measuresymbolup{\tmp@Xb}{\tmp@Ya}} {\msc@measuresymboldown{\tmp@Xb}{\tmp@Ya}} \rput(\tmp@Xb,-\tmp@Yb){\pscircle[fillcolor=white,fillstyle=solid](0,0){.5\measuresymbolwidth}} } % % \measureend[*][#1]{#2}{#3}{#4} % *: unstarred/starred version draws upward/downward triangle % #1: placement: l (left) r (right), or distance (negative or positive) to #3 % #2: name % #3: instance nick name % #4: gate name \newcommand{\measureend}{% \@ifstar{\def\msc@innermeasure{false}\msc@measureendargs}% {\def\msc@innermeasure{true}\msc@measureendargs}% } % \newcommand{\msc@measureendargs}[4][l]{% \def\msc@i{#1}% \def\msc@ii{#2}% \def\msc@iii{#3}% \def\msc@iv{#4}% \msc@measureendoffset% } % \newcommand{\msc@measureendoffset}[1][2]{% \msc@measureend{\msc@i}{\msc@ii}{\msc@iii}{\msc@iv}{#1}% } % \newcommand{\msc@measureend}[5]{% \ifthenelse{\equal{#1}{l}} {\setlength{\msc@measuredist}{-\measuredist}} {\ifthenelse{\equal{#1}{r}} {\setlength{\msc@measuredist}{\measuredist}} {\setlength{\msc@measuredist}{#1}}} \setlength{\tmp@Ya}{\msc@currentheight} \ifthenelse{\lengthtest{\msc@measuredist < 0pt}} {% left from instance \setlength{\tmp@Xa}{\msc@instlxpos{#3}} \setlength{\tmp@Xb}{\tmp@Xa + \msc@measuredist} \setlength{\tmp@Yb}{\tmp@Ya - #5\levelheight} \setlength{\tmp@X}{\tmp@Xb - \labeldist - 0.5\measuresymbolwidth} \setlength{\tmp@Y}{.5\tmp@Ya + .5\tmp@Yb} \rput[r](\tmp@X,-\tmp@Y){\raisebox{\depth}[\totalheight][0pt]{#2}} \setlength{\tmp@Y}{\tmp@Yb - \labeldist} \rput[r](\tmp@X,-\tmp@Yb){\raisebox{\depth}[\totalheight][0pt]{#4}} } {% right from instance \setlength{\tmp@Xa}{\msc@instrxpos{#3}} \setlength{\tmp@Xb}{\tmp@Xa + \msc@measuredist} \setlength{\tmp@Yb}{\tmp@Ya - #5\levelheight} \setlength{\tmp@X}{\tmp@Xb + \labeldist + 0.5\measuresymbolwidth} \setlength{\tmp@Y}{.5\tmp@Ya + .5\tmp@Yb} \rput[l](\tmp@X,-\tmp@Y){\raisebox{\depth}[\totalheight][0pt]{#2}} \setlength{\tmp@Y}{\tmp@Yb - \labeldist} \rput[l](\tmp@X,-\tmp@Yb){\raisebox{\depth}[\totalheight][0pt]{#4}} } \psline[linestyle=dashed](\tmp@Xa,-\tmp@Ya)(\tmp@Xb,-\tmp@Ya)(\tmp@Xb,-\tmp@Yb) \ifthenelse{\equal{\msc@innermeasure}{true}} {\msc@measuresymboldown{\tmp@Xb}{\tmp@Ya}} {\msc@measuresymbolup{\tmp@Xb}{\tmp@Ya}} \rput(\tmp@Xb,-\tmp@Yb){\pscircle[fillcolor=white,fillstyle=solid](0,0){.5\measuresymbolwidth}} } % % measure symbols % \def\msc@measuresymbolup#1#2{% % sin(pi/3) =~ 0.866025403784 % draw an upward triangle with 60-degree (pi/3) angles and base at (#1,#2) \rput[t](#1,-#2){% \begin{pspicture}(-1,0)(1,0.866025403784\measuresymbolwidth)% \pstriangle[dimen=middle,fillcolor=white,fillstyle=solid](\measuresymbolwidth,0.866025403784\measuresymbolwidth)% \end{pspicture}% } } % \def\msc@measuresymboldown#1#2{% % sin(pi/3) =~ 0.866025403784 % draw a downward triangle with 60-degree (pi/3) angles and base at (#1,#2) \rput[b](#1,-#2){% \begin{pspicture}(-1,0)(1,-0.866025403784\measuresymbolwidth)% \pstriangle[dimen=middle,fillcolor=white,fillstyle=solid](\measuresymbolwidth,-0.866025403784\measuresymbolwidth)% \end{pspicture}% } } % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \drawmscframe draws a frame of the right size around the msc % This command also set the value of \msc@totalsizebox \def\msc@drawframe{% \ifthenelse{\equal{\msc@frame}{yes}}{% \psframe[dimen=middle](0,0)(\msc@currentwidth,-\msc@currentheight)% }{% no frame drawing }% } % % \msckeyword is the keyword representation of msc \def\msckeyword{msc} \def\msckeywordstyle#1{\textbf{#1}} % % This keyword can be changed by the \setmsckeyword command (or by \renewcommand{\msckeyword}{...}): \newcommand{\setmsckeyword}[1]{\def\msckeyword{#1}} \newcommand{\setmsckeywordstyle}[1]{\def\msckeywordstyle{#1}}% % % Commands to switch internal options that control the drawing of header and footer symbols \newcommand{\drawinsthead}[1]{\def\msc@insthead{#1}}% \drawinsthead{yes}% \newcommand{\drawinstfoot}[1]{\def\msc@instfoot{#1}}% \drawinstfoot{yes}% % A similar command to control drawing of the msc-frame \newcommand{\drawframe}[1]{\def\msc@frame{#1}}% \drawframe{yes}% % % \def\msc@grid{no}% \newcommand{\showgrid}{\def\msc@grid{yes}} \newcommand{\nogrid}{\def\msc@grid{no}} \def\msc@settitle{% \MSC@settitle{msc}% {0\mscunit}% {-\msc@totalheight}% {\msc@totalwidth}% {0\mscunit}% {\msc@titlejustification}% {\msckeywordstyle{\msckeyword}{} \msc@title}% } % % \msc@title stores the title given in \begin{msc}{title} \def\msc@title{}% % % \msc@titlejustification says how the title should be justified % Justification is relative to the total width of the msc % l: left (default) % c: centered % r: right % \newsavebox{\mscbox}% % % the msc-environment \newenvironment{msc}[2][l]{% \message{(\msckeyword: '#2'}% \def\msc@titlejustification{#1}% \def\msc@title{#2}% \setcounter{mscinstcnt}{0}% \setlength{\msc@currentheight}{\topheaddist}% \addtolength{\msc@currentheight}{\instheadheight}% \addtolength{\msc@currentheight}{\firstlevelheight}% \setlength{\msc@currentwidth}{0pt}% % define the artificial left and right environment instances \msc@declinst{envleft}{}{}{\the\instbarwidth}% \msc@setinstxpos{envleft}{0pt}% \msc@declinst{envright}{}{}{\the\instbarwidth}% \msc@setinstxpos{envright}{\envinstdist}% \begin{lrbox}{\mscbox}% \begin{pspicture}(0,0)% we draw the msc in a picture of size 0x0 \psset{dash=4pt 4pt}% sets the hashed linestyle style }{% \addtolength{\msc@currentheight}{\lastlevelheight}% \setcounter{tmpcnt}{2}% \msc@drawinstancefooters% % If there is at least one instance, the current width is % set to the xpos of the NEXT msc instance. There is at least one instance, % if mscinstcnt >= 2. So, in that case, we have to % substract one \instdist from the current width. % %\ifthenelse{\value{mscinstcnt}<2}{% no user defined instances, so, relax % \relax% %}{% mscinstcnt >= 2 % \addtolength{\msc@currentwidth}{-\instdist}% %}% % Now we compute the final current width: one extra \envinstdist: \setlength{\msc@currentwidth}{\msc@instxpos{envright}}% \addtolength{\msc@currentheight}{\instfootheight+\bottomfootdist}% \msc@drawframe% \global\msc@totalwidth=\msc@currentwidth% \global\msc@totalheight=\msc@currentheight% \ifthenelse{\equal{\msc@grid}{yes}}{% \psgrid[subgriddiv=1,griddots=10](0,0)(0,0)(\msc@currentwidth,-\msc@currentheight)% }{\relax}% \msc@settitle% \end{pspicture}% % Debug info: %\typeout{msc size: \the\msc@totalwidth x\the\msc@totalheight}% \end{lrbox}% % the \mscbox now contains a box of 0x0, however the actual width and % height are stored in \msc@total{width,height}. We use these lengths % to adjust the width and height of the \mscbox \wd\mscbox=\msc@totalwidth% \ht\mscbox=\msc@totalheight% \dp\mscbox=0pt% % Now the \mscbox can be scaled (by \mscscalefactor) and `printed': {% DEBUG: use this \fbox stuf to check the bounding box \setlength{\fboxrule}{0.01pt}% \setlength{\fboxsep}{1pt}% \color{white}\mbox{% \psscalebox{\mscscalefactor}{\raisebox{\msc@totalheight}[\msc@totalheight][0pt]{\usebox{\mscbox}}}% }% }% \message{)}% }% % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newcommand{\MSC@settitle}[7]{% % #1: diagram type (msc, mscdoc, hmsc) % #2: llx % #3: lly % #4: urx % #5: ury % #6: justification (l, c, r) % #7: typeset title \setlength{\tmp@X}{#4 - #2 - 2\leftnamedist}% \ifthenelse{\equal{#6}{l}}% {% \def\MSC@dosettitle{\parbox[t]{\tmp@X}{\raggedright #7}}% }% {\ifthenelse{\equal{#6}{c}}% {% \def\MSC@dosettitle{\parbox[t]{\tmp@X}{\centering #7}}% }% {\ifthenelse{\equal{#6}{r}}% {% \def\MSC@dosettitle{\parbox[t]{\tmp@X}{\raggedleft #7}}% }% {\msc@illegaltitleplacement{#6}}% }% }% \setlength{\tmp@Y}{#5 - \topnamedist}% \setlength{\tmp@Xb}{#2 + \leftnamedist}% \rput[tl](\tmp@Xb,\tmp@Y){\MSC@dosettitle}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MSC documents % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % \mscdockeyword is the keyword representation of msc \def\mscdockeyword{mscdoc} \def\mscdockeywordstyle#1{\textbf{#1}} % % This keyword can be changed by the \setmscdockeyword command (or by \renewcommand{\mscdockeyword}{...}): \newcommand{\setmscdockeyword}[1]{\def\mscdockeyword{#1}} \newcommand{\setmscdockeywordstyle}[1]{\def\mscdockeywordstyle{#1}}% \newcommand{\mscdoc@settitle}{% \MSC@settitle{mscdoc}% {\mscdoc@llx}% {\mscdoc@lly}% {\mscdoc@urx}% {\mscdoc@ury}% {\mscdoc@titlejustification}% {\mscdockeywordstyle{\mscdockeyword}{} \mscdoc@title}% } \newenvironment{mscdoc}[2][l]% {% \message{( \mscdockeyword: '#2'}% \def\mscdoc@titlejustification{#1}% \def\mscdoc@title{#2}% \def\reference##1(##2,##3){% \setlength{\tmp@X}{\mscdocreferencewidth}% \setlength{\tmp@Y}{\mscdocreferenceheight}% \def\txt{\vbox to \tmp@Y{\vss\hbox to \tmp@X{\hss{}##1\hss}\vss}}% \rput(##2\mscunit,##3\mscunit){\psframebox[% framearc=0.25,% framesep=0pt,% border=0pt% ]{\txt}}}% \def\separator##1{% \psline[linestyle=dashed](\mscdoc@llx,##1)(\mscdoc@urx,##1) }% \def\mscdoc@sizespec(##1,##2)(##3,##4)% {% \def\mscdoc@llx{##1\mscunit}% \def\mscdoc@lly{##2\mscunit}% \def\mscdoc@urx{##3\mscunit}% \def\mscdoc@ury{##4\mscunit}% \begin{lrbox}{\mscbox}% \begin{pspicture}(\mscdoc@llx,\mscdoc@lly)(\mscdoc@urx,\mscdoc@ury)% \ifthenelse{\equal{\msc@grid}{yes}}{% \psgrid[subgriddiv=1,griddots=10](\mscdoc@llx,\mscdoc@lly)(\mscdoc@urx,\mscdoc@ury)% }{\relax}% \ifthenelse{\equal{\msc@frame}{yes}}{% \psframe(\mscdoc@llx,\mscdoc@lly)(\mscdoc@urx,\mscdoc@ury)% }{\relax}% \mscdoc@settitle% }% \mscdoc@sizespec% }% {% \end{pspicture}% \end{lrbox}% {% DEBUG: use this \fbox stuf to check the bounding box \setlength{\fboxrule}{0.01pt}% \setlength{\fboxsep}{1pt}% \color{white}\fbox{% \usebox{\mscbox}% }% }% \message{)}% } % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % HMSC % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \RequirePackage{pst-node} \newcommand{\hmsckeyword}{hmsc} \newcommand{\hmsckeywordstyle}[1]{\textbf{#1}} % This keyword can be changed by the \sethmsckeyword command (or by \renewcommand{\hmsckeyword}{...}): \newcommand{\sethmsckeyword}[1]{\def\hmsckeyword{#1}} \newcommand{\sethmsckeywordstyle}[1]{\def\hmsckeywordstyle{#1}}% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newif\if@ncsegline % % User command to draw a segmented line between two nodes (buggy). % % NOTE: this implementation is not complete yet. The optional arrows argument % only makes sense for forward arrows (and even then in a limited way). % usage: \ncsegline[settings]{arrows}{#1}[(x0,y0)...(xn,xy)]{#2} % settings (optional): pstricks settings for lines % arrows(optional): pstricks-style arrow defintions % #1: start node % (x0,y0)...(xn,yn) (optional): sequence of intermediate points % #2: end node \def\ncsegline{% \@ifstar{\def\@nclinecommand{\ncline*}\@ncseglinei}{\def\@nclinecommand{\ncline}\@ncseglinei}% } \def\ncseglinecheck@arrow#1#2{% \ncseglinecheck@@arrow#2-\@nil \if@ncsegline% % \message{(arrow: `#2')}% \edef\@ncseglinearrow{{#2}}% \def\next{#1}% \else% % \message{(no arrow `#2')}% \edef\@ncseglinearrow{{-}}% \def\next{#1{#2}}% \fi% \next% } \def\ncseglinecheck@@arrow#1-#2\@nil{% \ifx\@nil#2\@nil\@ncseglinefalse\else\@ncseglinetrue\fi} \def\@ncseglinei{% \@ifnextchar[{\@ncseglineReadSettings}{\def\@nclinesettings{[]}\ncseglinecheck@arrow{\@ncseglineii}}%] } \def\@ncseglineReadSettings[#1]{% \def\@nclinesettings{[#1]}% \ncseglinecheck@arrow{\@ncseglineii}% } \def\@ncseglineii#1{% \def\@ncsegargA{#1}% \@ifnextchar[{\@ncseglineiii}{\@ncseglineiv}% } \def\@ncseglineiii[#1]#2{% \@ncseglineA#1(\relax,\relax)% \def\@ncsegargB{#2}% \@ncseglinedraw% } \def\@ncseglineiv#1{% \def\@ncsegargB{#1}% \@ncseglinedraw% } \def\@ncseglinedraw{% \edef\@ncseglineattrs{\@nclinesettings\@ncseglinearrow}% \expandafter\@nclinecommand\@ncseglineattrs{\@ncsegargA}{\@ncsegargB}% } \def\@ncseglineA(#1,#2){% \ifx#1\relax% \def\next{\relax}% \else% % \message{(line seg)}% \pnode(#1,#2){#1#2}% \expandafter\@nclinecommand\@nclinesettings{-}{\@ncsegargA}{#1#2}% \edef\@ncsegargA{#1#2}% \def\next{\@ncseglineA}% \fi \next% } % User command to draw hmsc start symbols % usage: \hmscstartsymbol{#1}(#2,#3) % #1: nickname % #2: x-coordinate % #3: y-coordinate % % % sin(pi/3) =~ 0.866025403784 % \def\hmscstartsymbol#1(#2,#3){% %\message{(hmsc start symbol: #1)}% \setlength{\tmp@Xa}{#2\mscunit}% \setlength{\tmp@Ya}{#3\mscunit}% \setlength{\tmp@Xb}{\tmp@Xa}\addtolength{\tmp@Xb}{-.5\hmscstartsymbolwidth}% \setlength{\tmp@Xc}{\tmp@Xa}\addtolength{\tmp@Xc}{.5\hmscstartsymbolwidth}% \setlength{\tmp@Yb}{\tmp@Ya}\addtolength{\tmp@Yb}{0.866025403784\hmscstartsymbolwidth}% \pspolygon(\tmp@Xa,\tmp@Ya)(\tmp@Xb,\tmp@Yb)(\tmp@Xc,\tmp@Yb)% \pnode(#2,#3){#1}% } % User command to draw hmsc end symbols % usage: \hmscendsymbol{#1}(#2,#3) % #1: nickname % #2: x-coordinate % #3: y-coordinate % % % sin(pi/3) =~ 0.866025403784 % \def\hmscendsymbol#1(#2,#3){% %\message{(hmsc end symbol: #1)}% \setlength{\tmp@Xa}{#2\mscunit}% \setlength{\tmp@Ya}{#3\mscunit}% \setlength{\tmp@Xb}{\tmp@Xa}\addtolength{\tmp@Xb}{-.5\hmscstartsymbolwidth}% \setlength{\tmp@Xc}{\tmp@Xa}\addtolength{\tmp@Xc}{.5\hmscstartsymbolwidth}% \setlength{\tmp@Yb}{\tmp@Ya}\addtolength{\tmp@Yb}{-0.866025403784\hmscstartsymbolwidth}% \pspolygon(\tmp@Xa,\tmp@Ya)(\tmp@Xb,\tmp@Yb)(\tmp@Xc,\tmp@Yb)% \pnode(#2,#3){#1}% } % User command to draw a hmsc condition % usage: \hmsccondition{#1}{#2}(#3,#4) % #1: nickname % #2: text % #3: x-coordinate % #4: y-coordinate \def\hmsccondition#1#2(#3,#4){% \setlength{\tmp@X}{.5\hmscconditionwidth}% \setlength{\tmp@Y}{.5\hmscconditionheight}% \setlength{\tmp@Xa}{\tmp@X}\addtolength{\tmp@Xa}{.6\tmp@Y}% \rput(#3\mscunit,#4\mscunit){% \pspolygon(-\tmp@X,\tmp@Y)% (\tmp@X,\tmp@Y)% (\tmp@Xa,0)% (\tmp@X,-\tmp@Y)% (-\tmp@X,-\tmp@Y)% (-\tmp@Xa,0)}% \setlength{\tmp@X}{\hmscconditionwidth}% \setlength{\tmp@Y}{\hmscconditionheight}% \def\ctxt{\vbox to \tmp@Y{\vss\hbox to \tmp@X{\hss{}#2\hss}\vss}}% \rput(#3\mscunit,#4\mscunit){\rnode{#1}{\psframebox[% linestyle=none,% linewidth=0pt,% framesep=0pt,% border=0pt% ]{\ctxt}}}% } % User command to draw a hmsc reference % usage: \hmscreference{#1}{#2}(#3,#4) % #1: nickname % #2: text % #3: x-coordinate % #4: y-coordinate \def\hmscreference#1#2(#3,#4){% \setlength{\tmp@X}{\hmscreferencewidth}% \setlength{\tmp@Y}{\hmscreferenceheight}% \def\rtxt{\vbox to \tmp@Y{\vss\hbox to \tmp@X{\hss{}#2\hss}\vss}}% \rput(#3\mscunit,#4\mscunit){\rnode{#1}{\psframebox[% framearc=0.25,% framesep=0pt,% border=0pt% ]{\rtxt}}}% } % User command to draw hmsc connections % usage: \hmscconnection{#1}(#2,#3) % #1: nickname % #2: x-coordinate % #3: y-coordinate \def\hmscconnection#1(#2,#3){% \rput(#2,#3){\circlenode[framesep=0pt]{#1}{\rule{0pt}{2\hmscconnectionradius}}}% } % User command to draw arrows between hmsc-objects % Usage: \arrow{#1}[(x0,y0)...(xn,yn)]{#2} % #1: start hmsc object % (x0,y0)...(xn,yn) (optional): sequence of intermediate points % #2: end hmsc object \newcommand{\arrow}{ \ncsegline{->}% } % User environment to draw hmsc's % Usage: \begin{hmsc}{#1}(llx,lly((urx,ury)...\end{hmsc} % \def\hmsc@settitle{% \MSC@settitle{hmsc}% {\hmsc@llx}% {\hmsc@lly}% {\hmsc@urx}% {\hmsc@ury}% {\hmsc@titlejustification}% {\hmsckeywordstyle{\hmsckeyword}{} \hmsc@title}% % \setlength{\tmp@X}{\hmsc@llx + \leftnamedist}% % \setlength{\tmp@Y}{\hmsc@ury - \topnamedist}% % \rput[tl](\tmp@X,\tmp@Y){% % \hmsckeywordstyle{\hmsckeyword}{} \hmsc@title% % }% } \newenvironment{hmsc}[2][l] {\message{( \hmsckeyword: '#2'}% \def\hmsc@titlejustification{#1}% \def\hmsc@title{#2}% \hmsc@startenv}% {%\setlength{\tmp@X}{\hmsc@llx}\addtolength{\tmp@X}{\leftnamedist}% %\setlength{\tmp@Y}{\hmsc@ury}\addtolength{\tmp@Y}{-\topnamedist}% %\rput[tl](\tmp@X,\tmp@Y){\raisebox{\depth}[\totalheight][0pt]{\hmsckeywordstyle{\hmsckeyword} \hmsc@name}}% \hmsc@settitle% \ifthenelse{\equal{\msc@frame}{yes}}{% \psframe(\hmsc@llx,\hmsc@lly)(\hmsc@urx,\hmsc@ury)% }{\relax}% \end{pspicture}% \end{lrbox}% {% DEBUG: use this \fbox stuf to check the bounding box \setlength{\fboxrule}{0.01pt}% \setlength{\fboxsep}{1pt}% \color{white}\fbox{% \usebox{\mscbox}% }% }% \message{)}}% \def\hmsc@startenv(#1,#2)(#3,#4){% \newcommand{\hmsc@llx}{#1\mscunit}% \newcommand{\hmsc@lly}{#2\mscunit}% \newcommand{\hmsc@urx}{#3\mscunit}% \newcommand{\hmsc@ury}{#4\mscunit}% \begin{lrbox}{\mscbox}% \begin{pspicture}(\hmsc@llx,\hmsc@lly)(\hmsc@urx,\hmsc@ury)% \ifthenelse{\equal{\msc@grid}{yes}}{% \psgrid[subgriddiv=1,griddots=10](\hmsc@llx,\hmsc@lly)(\hmsc@urx,\hmsc@ury)% }{\relax}% } %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Initialisation of the msc package % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \set@mscvalueslarge \def\set@mscvalueslarge{% \psset{linewidth=0.8pt} % the lengths \setlength{\actionheight}{0.75\mscunit} \setlength{\actionwidth}{1.25\mscunit} \setlength{\bottomfootdist}{1\mscunit} \setlength{\msccommentdist}{1.5\mscunit} \setlength{\conditionheight}{0.75\mscunit} \setlength{\conditionoverlap}{0.6\mscunit} \setlength{\envinstdist}{2.5\mscunit} \setlength{\firstlevelheight}{0.75\mscunit} \setlength{\hmscconditionheight}{0.8\mscunit} \setlength{\hmscconditionwidth}{1.6\mscunit} \setlength{\hmscconnectionradius}{0.06\mscunit} \setlength{\hmscreferenceheight}{0.8\mscunit} \setlength{\hmscreferencewidth}{1.6\mscunit} \setlength{\hmscstartsymbolwidth}{0.85\mscunit} \setlength{\inlineoverlap}{1.5\mscunit} \setlength{\instbarwidth}{0pt} \setlength{\instdist}{3\mscunit} \setlength{\instfootheight}{0.25\mscunit} \setlength{\instheadheight}{.6\mscunit} \setlength{\instwidth}{1.75\mscunit} \setlength{\labeldist}{1ex} \setlength{\lastlevelheight}{0.5\mscunit} \setlength{\leftnamedist}{0.3\mscunit} \setlength{\levelheight}{.75\mscunit} \setlength{\lostsymbolradius}{.15\mscunit} \setlength{\markdist}{1\mscunit} \setlength{\measuredist}{0.75\mscunit} \setlength{\measuresymbolwidth}{.15\mscunit} \setlength{\mscdocreferenceheight}{0.8\mscunit} \setlength{\mscdocreferencewidth}{1.6\mscunit} \setlength{\referenceoverlap}{1.5\mscunit} \setlength{\regionbarwidth}{.5\mscunit} \setlength{\selfmesswidth}{.75\mscunit} \setlength{\stopwidth}{0.6\mscunit} \setlength{\timerwidth}{0.4\mscunit} \setlength{\topheaddist}{1.5\mscunit} \setlength{\topnamedist}{.3\mscunit} % some numeric parameters \messarrowscale{2} } % % % \set@mscvaluesnormal \def\set@mscvaluesnormal{% \psset{linewidth=0.7pt} % switch to a smaller font \small% % the lengths \setlength{\actionheight}{0.6\mscunit} \setlength{\actionwidth}{1.25\mscunit} \setlength{\bottomfootdist}{0.7\mscunit} \setlength{\msccommentdist}{1.1\mscunit} \setlength{\conditionheight}{0.6\mscunit} \setlength{\conditionoverlap}{0.5\mscunit} \setlength{\envinstdist}{2\mscunit} \setlength{\firstlevelheight}{0.6\mscunit} \setlength{\hmscconditionheight}{0.7\mscunit} \setlength{\hmscconditionwidth}{1.4\mscunit} \setlength{\hmscconnectionradius}{0.05\mscunit} \setlength{\hmscreferenceheight}{0.7\mscunit} \setlength{\hmscreferencewidth}{1.4\mscunit} \setlength{\hmscstartsymbolwidth}{0.7\mscunit} \setlength{\inlineoverlap}{1\mscunit} \setlength{\instbarwidth}{0pt} \setlength{\instdist}{2.2\mscunit} \setlength{\instfootheight}{0.2\mscunit} \setlength{\instheadheight}{.55\mscunit} \setlength{\instwidth}{1.6\mscunit} \setlength{\labeldist}{1ex} \setlength{\lastlevelheight}{0.4\mscunit} \setlength{\leftnamedist}{0.2\mscunit} \setlength{\levelheight}{.5\mscunit} \setlength{\lostsymbolradius}{.12\mscunit} \setlength{\markdist}{1\mscunit} \setlength{\measuredist}{0.6\mscunit} \setlength{\measuresymbolwidth}{.2\mscunit} \setlength{\mscdocreferenceheight}{0.7\mscunit} \setlength{\mscdocreferencewidth}{1.4\mscunit} \setlength{\referenceoverlap}{1\mscunit} \setlength{\regionbarwidth}{.4\mscunit} \setlength{\selfmesswidth}{.6\mscunit} \setlength{\stopwidth}{0.5\mscunit} \setlength{\timerwidth}{0.3\mscunit} \setlength{\topheaddist}{1.3\mscunit} \setlength{\topnamedist}{.2\mscunit} % some numeric parameters \messarrowscale{1.5} } % % \set@mscvaluessmall \def\set@mscvaluessmall{% \psset{linewidth=0.6pt} % switch to a smaller font \small% % the lengths \setlength{\actionheight}{0.5\mscunit} \setlength{\actionwidth}{1.2\mscunit} \setlength{\bottomfootdist}{0.5\mscunit} \setlength{\msccommentdist}{0.75\mscunit} \setlength{\conditionheight}{0.5\mscunit} \setlength{\conditionoverlap}{0.4\mscunit} \setlength{\envinstdist}{1.2\mscunit} \setlength{\firstlevelheight}{0.4\mscunit} \setlength{\hmscconditionheight}{0.6\mscunit} \setlength{\hmscconditionwidth}{1.2\mscunit} \setlength{\hmscconnectionradius}{0.04\mscunit} \setlength{\hmscreferenceheight}{0.6\mscunit} \setlength{\hmscreferencewidth}{1.2\mscunit} \setlength{\hmscstartsymbolwidth}{0.4\mscunit} \setlength{\inlineoverlap}{.75\mscunit} \setlength{\instbarwidth}{0pt} \setlength{\instdist}{1.5\mscunit} \setlength{\instfootheight}{0.15\mscunit} \setlength{\instheadheight}{0.5\mscunit} \setlength{\instwidth}{1.2\mscunit} \setlength{\labeldist}{0.8ex} \setlength{\lastlevelheight}{0.3\mscunit} \setlength{\leftnamedist}{0.1\mscunit} \setlength{\levelheight}{0.4\mscunit} \setlength{\lostsymbolradius}{.08\mscunit} \setlength{\markdist}{1\mscunit} \setlength{\measuredist}{0.4\mscunit} \setlength{\measuresymbolwidth}{.25\mscunit} \setlength{\mscdocreferenceheight}{0.6\mscunit} \setlength{\mscdocreferencewidth}{1.2\mscunit} \setlength{\referenceoverlap}{.75\mscunit} \setlength{\regionbarwidth}{.2\mscunit} \setlength{\selfmesswidth}{.4\mscunit} \setlength{\stopwidth}{0.3\mscunit} \setlength{\timerwidth}{0.2\mscunit} \setlength{\topheaddist}{1.2\mscunit} \setlength{\topnamedist}{.1\mscunit} % some numeric parameters \messarrowscale{1.2} } % \setmscvalues assigns compatible values to all msc-parameters % Currently, three sets of values are supported: large, normal % and small. \def\setmscvalues#1{% \ifthenelse{\equal{#1}{large}}{% \set@mscvalueslarge}{% \ifthenelse{\equal{#1}{normal}}{% \set@mscvaluesnormal}{% \ifthenelse{\equal{#1}{small}}{% \set@mscvaluessmall}{% \ifthenelse{\equal{#1}{measure}}{% \set@mscvaluesmeasure}{% \msc@unknownmscvalueserr{#1}}}}}% } % % initialisation of the msc-parameters \setmscvalues{normal} \setfootcolor{black} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Error and help messages % We use the standard LaTeX2e facilities to generate error and help % messages (for more info, see file lterror.dtx of LaTeX2e distribution). % % % nickname already defined \gdef\msc@nicknamedefinederr#1{% \PackageError{msc}{% error message nickname #1 already defined}{% help text You tried to use the nickname '#1' for a new\MessageBreak msc object (instance, reference, inline expression, etc.),\MessageBreak but the nickname is already assigned to another msc object.\MessageBreak press to continue (the new msc object will be ignored).}% } % % no such msc instance error \gdef\msc@instundefinederr#1{% \PackageError{msc}{% error message undefined msc instance: #1}{% help text You used '#1' as an msc instance nickname, but\MessageBreak there is no msc instance with that nickname.}% } % % unknown linestyle error \gdef\msc@unknownlinestyleerr#1{% \PackageError{msc}{% error message unknown linestyle: #1}{% help text Known msc linestyles are "solid", "dashed", and "dotted".\MessageBreak You used '#1'.}% } % % unknown region style error \gdef\msc@unknownregionstyleerr#1{% \PackageError{msc}{% error message unknown region style: #1}{% help text Known msc region styles are "normal", "coregion", "suspension", and "activation".\MessageBreak You used '#1'.}% } % % unknown self message label position error \gdef\msc@unknownselfmessposerr#1{% \PackageError{msc}{% error message unknown position for self message: #1}{% help text Known positions are "l" (left), "r" (right).\MessageBreak You used '#1'.}% } % % unknown self message label position error \gdef\msc@unknowntimerposerr#1{% \PackageError{msc}{% error message unknown timer position: #1}{% help text Known timer positions are "l" (left), "r" (right).\MessageBreak You used '#1'.}% } % % unknown self message label position error \gdef\msc@unknownmscvalueserr#1{% \PackageError{msc}{% error message unknown set of msc-values: #1}{% help text Known sets of msc-values are "normal" and "small".\MessageBreak You used '#1'.}% } % % no such msc reference error \gdef\msc@refundefinederr#1{% \PackageError{msc}{% error message undefined reference: #1}{% help text You used '#1' as a reference nickname, but\MessageBreak there is no reference with that nickname.}% } % % no such msc inline error \gdef\msc@inlundefinederr#1{% \PackageError{msc}{% error message undefined inline expression: #1}{% help text You used '#1' as a inline expression nickname, but\MessageBreak there is no inline expression with that nickname.}% } % % inline first right from last error \gdef\msc@inlfirstlasterror#1#2#3{% \PackageError{msc}{% error message first instance right from final instance\MessageBreak in inline expression #1}{% help text In the definition of inline expression '#1', you probably switched\MessageBreak the first msc instance, '#2', and the final msc instance, '#3',\MessageBreak since the first is located right from the final.}% } % % reference first rightt from last error \gdef\msc@reffirstlasterror#1#2#3{% \PackageError{msc}{% error message first instance right from final instance\MessageBreak in reference #1}{% help text In the definition of msc reference '#1', you probably switched\MessageBreak the first msc instance, '#2', and the final msc instance, '#3',\MessageBreak since the first is located right from the final.}% } % \gdef\msc@illegalmarkplacement#1{% \PackageError{msc}{% illegal mark placement specifier: #1}{% help text The four mark placement specifiers are:\MessageBreak tl (top-left)\MessageBreak bl (bottom-left)\MessageBreak tr (top-right)\MessageBreak br (bottom-right)} } \gdef\msc@illegalmesslabelpositionerr#1{% \PackageError{msc}{% illegal label position specifier: #1}{% help text Valid label position specifiers are:\MessageBreak t (top)\MessageBreak b (bottom)} } \gdef\msc@illegalselfmesspositionerr#1{% \PackageError{msc}{% illegal label position: #1}{% help text Valid label positions are:\MessageBreak t (top)\MessageBreak b (bottom)\MessageBreak l (left)\MessageBreak r (right)} } \gdef\msc@illegallostfoundlabelpositionerr#1{% \PackageError{msc}{% in lost/found message: illegal label position: #1}{% help text Valid label position are:\MessageBreak t (top)\MessageBreak b (bottom)} } %################################################################################ % \gdef\msc@illegaltitleplacement#1{% \PackageError{msc}{% illegal title placement specifier: #1}{% help text Valid title placement specifiers are:\MessageBreak l (left)\MessageBreak c (center)\MessageBreak r (right)} } %################################################################################ \gdef\hmsc@nicknamedefinederr#1{% \PackageError{msc}{% error message nickname #1 already defined}{% help text You tried to use the nickname '#1' for a new\MessageBreak hmsc object (startsymbol, endsymbol, reference, etc.),\MessageBreak but the nickname is already assigned to another hmsc object.\MessageBreak press to continue (the new hmsc object will be ignored).}% } % no such msc hmsc object error \gdef\hmsc@objectundefinederr#1{% \PackageError{msc}{% error message undefined hmsc object: #1}{% help text You used '#1' as an hmsc object nickname, but\MessageBreak there is no hmsc object with that nickname.}% }% % hmsc unknown connection type \gdef\hmsc@unknownconnectiontypeerror#1{% \PackageError{msc}{% error message Unknown HMSC connection type: #1}{% help text Known HMSC connection types are straight, rounded, and curved.}% } % % hmsc missing y coordinate in arrow specification \gdef\hmsc@missingycoord#1#2{% \PackageError{msc}{% error message Missing Y coordinate in arrow specification. You typed:\MessageBreak [#2]\MessageBreak which is parsed as the incomplete list of points:\MessageBreak #1\MessageBreak Remove the final X coordinate or add an Y coordinate}{% The points specifying an HMSC arrow should be given as a comma separated\MessageBreak list of X, Y coordinates. Furthermore, each X coordinate should\MessageBreak be followed by a Y coordinate.}% } % remarks % % Issuing pstricks drawing-commands inside a TeX-group in a pspicture environment % can result in ill-positioned objects. % % messages from/to the right environment should be defined after the last % instance is declared with \declinst