% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % $Id: lsc.sty,v 1.34 2006/02/23 12:57:15 berndw Exp $ % % LSC -- A LaTeX style for typesetting Live Sequence Charts % % Author: Bernd Westphal % % Copyright (c) 2005-2006 Bernd Westphal. All rights reserved. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 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 the copyright holder. % % This work consists of the files README, lsc.sty, lsc.tex, lsc.bib. % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{lsc}[2005/12/30 Typesetting LSCs] \RequirePackage{ifthen,pstricks,pst-node} % Structure: % % - global constants: % % Commands and lengths that parameterise the appearance of LSCs in general. % If one knows what one is doing, one may redefine them, e.g. to obtain % smaller or wider instance line boxes. % % - constant within lsc environment: % % Commands and lengths that are set anew in each Lsc/FullLsc environment and % remain constant within this environment, e.g. the total width and height % of the pspicture environment. There's typically no sense in changing any % of these. % % - constant within instance: % % Commands and lengths that are set anew in each lscinst/lsccreateinst % environment and remain constant within this environment, e.g. whether this % instance line needs a footer or not. There's typically no sense in % changing any of these. % % - global variables % % Commands and lengths that are redefined during construction of the Lsc. % Currently only the current X and Y drawing position. % % - "local" variables % % Commands and lengths that are used by single commands, e.g. to compute the % dimension of pre-chart kandisses or timer hourglasses. % % - helper macros % % Many exported commands are actually only checking parameters for well- % formedness and then call helper macros which do the work. Some work % macros even have own helper macros to factor out common code. % There's typically no sense in calling any of these from user code. % % - exported interface % % The commands and environments that are provided to the user. % % Notes: % % - things with multiple ends, like message arrows, local invariants, wide % conditions etc. share the following philosophy: % % - they get an ID by the user and internally define macros whose name % comprises the ID and which typically capture the corresponding X and Y % coordinates % % - when the element is drawn, these macros are used and afterwards cleared % % globally constant: % % % % % % % % % % % % % % % % % % % % % % % % % % % % \newcommand{\lsc@true}{true} \newcommand{\lsc@false}{false} %% width for a single instance line and height of a single location % \newlength{\lscLocationWidth} \pssetlength{\lscLocationWidth}{3} \newlength{\lscLocationHeight} \pssetlength{\lscLocationHeight}{1} %% the height of the black footer boxes in MSC-mode is determined by a \rule % of height \lscFooterHeightFactor * \lscLocationHeight % % Note: this is a command, not a length, hence it is set by, e.g., % \renewcommand{\lscFooterHeightFactor}{0.10} % \newcommand{\lscFooterHeightFactor}{0.20} %% half width of the square around the kill symbol 'X' % \newlength{\lscKillLength} \pssetlength{\lscKillLength}{0.33} %% position of local invariants to the left of the LSC % \newlength{\lsc@liL} \pssetlength{\lsc@liL}{0.2\lscLocationWidth} %% offset of the dotted line indicating coregion and width of the coregion % line % \newlength{\lsc@coregoffset} \pssetlength{\lsc@coregoffset}{0.15} % \newlength{\lsc@coregwidth} \pssetlength{\lsc@coregwidth}{1pt} %% offset of message labels from the message arrows % \newlength{\lsc@labelsep} \pssetlength{\lsc@labelsep}{1.5pt} %% radius of dots used to indicate exclusive/inclusive beginning and ending % of local invariants % \newlength{\lsc@dotradius} \pssetlength{\lsc@dotradius}{0.1} %% radius of circles used to mark atoms % \newlength{\lsc@atomradius} \pssetlength{\lsc@atomradius}{0.35} %% radius of circles used to mark simultaneous regions % \newlength{\lsc@simregradius} \pssetlength{\lsc@simregradius}{0.125} %% vertical distance between baseline of the label text and the create arrow % \newlength{\lsc@createoffset} \pssetlength{\lsc@createoffset}{0.3} \newlength{\lsc@instheadframesep} \pssetlength{\lsc@instheadframesep}{2pt} %% parameters of the hourglass used for timers: % % I _______ % I \ / % I \ / % I \ / % I<-----------X - % I / \ | % I / \ | hgheight % I /_____\ _ % I |-w-| % |--hgoffset--| % \newlength{\lsc@hgwidth} \pssetlength{\lsc@hgwidth}{0.125} \newlength{\lsc@hgheight} \pssetlength{\lsc@hgheight}{1.5\lsc@hgwidth} \newlength{\lsc@hgoffset} \pssetlength{\lsc@hgoffset}{4\lsc@hgwidth} %% parameters of the instance head boxes and precharts: % a \rule of depth \lsc@instheadruledepth and height \lsc@instheadruleheight % defines the shape of the instance head box, the \lsc@pccorrection is the % length _above_ 0 (this is the bottom end of the instance head boxes) that % the upper line of the prechart or universal/existential box should lie s.t. % it comprises the instance head nicely. % \lsc@pccorrection could have been defined as follows (and is not for % historical reasons): % % -\lsc@instheadruledepth % + \lsc@instheadruleheight % + \lsc@distancebetweeninstanceheadbox and prechart % \newlength{\lsc@instheadruledepth} \pssetlength{\lsc@instheadruledepth}{-0.8ex} \newlength{\lsc@instheadruleheight} \pssetlength{\lsc@instheadruleheight}{3ex} \newlength{\lsc@pccorrection} \pssetlength{\lsc@pccorrection}{5.55ex} %% half width of environment instance line % \newlength{\lsc@envlinewidth} \pssetlength{\lsc@envlinewidth}{0.1} %% baselineskip correction within the name/ac/am/i box % \newlength{\lsc@acamboxblskipcorrection} \setlength{\lsc@acamboxblskipcorrection}{-1.00\smallskipamount} %% width, colour, and linestyle of the line used to draw cuts % \newlength{\lscCutWidth} \setlength{\lscCutWidth}{3pt} % \newcommand{\lscCutColour}{red} % \newcommand{\lscCutLinestyle}{solid} %% strings for comparison in \if\else\fi % \def\lsc@hot{hot}% \def\lsc@cold{cold}% % \def\lsc@l{l}% \def\lsc@r{r}% % \def\lsc@ra{ra}% \def\lsc@rb{rb}% \def\lsc@la{la}% \def\lsc@lb{lb}% % \def\lsc@b{b}% \def\lsc@f{f}% % \def\lsc@incl{incl}% \def\lsc@excl{excl}% % \def\lsc@noboxSD{noboxSD}% \def\lsc@SD{SD}% \def\lsc@MSC{MSC}% \def\lsc@esymSD{esymSD}% \def\lsc@esymMSC{esymMSC}% % \def\lsc@universal{universal}% \def\lsc@existential{existential}% \def\lsc@none{none}% % \def\lsc@empty{}% \def\lsc@weak{weak}% \def\lsc@permissive{permissive}% \def\lsc@strict{strict}% % \def\lsc@initial{initial}% \def\lsc@invariant{invariant}% \def\lsc@iterative{iterative}% % % constant within lsc environment: % % % % % % % % % % % % % % % % % % % % % %% position of local invariants to the right of the LSC % \newlength{\lsc@liR} %% width of all instance lines within current pspicture (the pspicture may be % wider if there is a prechart) % \newlength{\lsc@width} %% boundaries of current lsc's pspicture coordinate system % \newlength{\lsc@ulX} \newlength{\lsc@ulY} \newlength{\lsc@lrX} \newlength{\lsc@lrY} % % constant within instance: % % % % % % % % % % % % % % % % % % % % % % % % %% true if the instance should be drawn in MSC, false if SD style requested % \newboolean{lsc@MSC} % % global variables: % % % % % % % % % % % % % % % % % % % % % % % % % % % % %% current x/y position in the pspicture set up by the lsc environment % (variables) % \newlength{\lsc@X} \newlength{\lsc@Y} % % "local" variables: % % % % % % % % % % % % % % % % % % % % % % % % % % % % %% used by many macros that draw condtion "kandises": % % _________________________ % / \ % / \ _ % \ / | kheight % \_________________________/ _ % | kwidth | % | kxwidth | % % _______________ % \ % \ % / % /______________ % | kxxwidth | % | kxwidth | % % % kdepth is only a helper to compute the kheight, kxxwidth is only use by the % puzzle pieces for wide conditions. % \newsavebox{\lsc@kbox} \newlength{\lsc@kdepth} \newlength{\lsc@kwidth} \newlength{\lsc@kheight} \newlength{\lsc@kxwidth} \newlength{\lsc@kxxwidth} %% used for the computation of boundaries in FullLsc % \newsavebox{\lsc@acambox} \newlength{\lsc@acamheight} %% used by the macro drawing local invariants % \newlength{\lsc@liX} \newlength{\lsc@licondY} %% used by the macro drawing the surrounding frame % \newlength{\lsc@frameheight} \newlength{\lsc@frametop} %% used for positioning the destination end of create arrows % \newlength{\lsc@createinstX} \newlength{\lsc@createinstY} \newlength{\lsc@createinstW} %% used in \lsc@namedCut to compute the vertical difference between last and % current cut (if this is small, don't draw the vertical line) % \newlength{\lsc@cutvdiff} %% used by the macro drawing coregions % \newlength{\lsc@crX} % % helper macros: % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %% define height and depth of instance head boxes % \newcommand{\lsc@instheadrule}% {\rule[\lsc@instheadruledepth]{0ex}{\lsc@instheadruleheight}} %% draw the "kandis" for conditions -- used for single-instance conditions and % local invariants, not for conditions spanning multiple instance lines; % drawback: the angle of vertexes is kept constant, this causes the "kandis" % to grow wider with higher content % % \lsc@kandis[]{} % \newcommand{\lsc@kandis}[2][]{% \sbox{\lsc@kbox}{#2}% \settowidth{\lsc@kwidth}{\usebox{\lsc@kbox}}% \setlength{\lsc@kwidth}{.5\lsc@kwidth}% % \addtolength{\lsc@kwidth}{\fboxsep}% \settoheight{\lsc@kheight}{\usebox{\lsc@kbox}}% \settodepth{\lsc@kdepth}{\usebox{\lsc@kbox}}% \addtolength{\lsc@kheight}{\lsc@kdepth}% % \addtolength{\lsc@kheight}{\fboxsep}% \setlength{\lsc@kxwidth}{\lsc@kwidth}% \addtolength{\lsc@kxwidth}{\lsc@kheight}% \begin{pspicture}(-\lsc@kxwidth,\lsc@kheight)(\lsc@kxwidth,-\lsc@kheight)% \pspolygon[#1](-\lsc@kxwidth,0)% (-\lsc@kwidth,\lsc@kheight)% (\lsc@kwidth,\lsc@kheight)% (\lsc@kxwidth,0)% (\lsc@kwidth,-\lsc@kheight)% (-\lsc@kwidth,-\lsc@kheight)% \rput(0,0){\usebox{\lsc@kbox}}% \end{pspicture}% } % \newcommand{\lsc@hotkandis}[1]{% \lsc@kandis[fillstyle=solid,linestyle=solid]{#1}} % \newcommand{\lsc@coldkandis}[1]{% \lsc@kandis[fillstyle=solid,linestyle=dashed]{#1}} %% save coordinates of message sending and reception (values are accessed by % _name_ later) % % The easy solution consisting of just placing nodes and later connecting % them by lines does not work since then label end up positioned upside-down % below arrows for those messages going from right to left. Hence we need to % have both coordinates to draw the line the right way. % % \lsc@msg{a|i}{snd|rcv}{id} % \newcommand{\lsc@msg}[3]{% \expandafter\ifx\csname lsc@#1msg#3#2X\endcsname\relax% \expandafter\xdef\csname lsc@#1msg#3#2X\endcsname{\the\lsc@X}% \expandafter\xdef\csname lsc@#1msg#3#2Y\endcsname{\the\lsc@Y}% \else% \errmessage{LSC error: #3: message location already defined!}% \fi% } % % remove all helper definitions again to be able to detect errors with later % messages who use the same name % % \lsc@clearmsg{a|i}{id} % \newcommand{\lsc@clearmsg}[2]{% \global\expandafter\let\csname lsc@#1msg#2sndX\endcsname\relax% \global\expandafter\let\csname lsc@#1msg#2sndY\endcsname\relax% \global\expandafter\let\csname lsc@#1msg#2rcvX\endcsname\relax% \global\expandafter\let\csname lsc@#1msg#2rcvY\endcsname\relax% } %% draw a simultaneous-region "kuller" (circle) -- whether it goes to front or % back is determined by the hook that is defined to be this command % \newcommand{\lsc@simregionkuller}{% \rput(\lsc@X,\lsc@Y){% \pscircle*{\lsc@simregradius}}} %% save coordinates of conditions spanning multiple instance lines; if first % called for a name, the coordinates of the leftmost end are stored, the % coordinates of the rightmost end are overwritten each time, leaving the % actual rightmost values in the end; the Y-coordinate is only stored on the % first call (values are accessed by _name_ later) % % \lsc@widecondloc{} % \newcommand{\lsc@widecondloc}[1]{% \expandafter\ifx\csname lsc@wc#1leftmostX\endcsname\relax% \expandafter\xdef\csname lsc@wc#1leftmostX\endcsname{\the\lsc@X}% \expandafter\xdef\csname lsc@wc#1Y\endcsname{\the\lsc@Y}% \fi% \expandafter\xdef\csname lsc@wc#1rightmostX\endcsname{\the\lsc@X}}% %% write a white block as part of the background of a condition spanning % multiple instance lines; in other words, the background of these conditions % is not drawn at once but separately on each instance line % % The trick for getting the outline right is to draw "puzzles": on the % leftmost instance, a % _______ % / | \ % \___|___/ % % piece is drawn and on all other instances a % _________ % \ | \ % /____|___/ % % pieces. This even gets wide conditions covering only a single instance % line right. % % \lsc@lscfirstblock % \newcommand{\lsc@firstblock}{% \pssetlength{\lsc@kxwidth}{0.5\lscLocationWidth}% \pssetlength{\lsc@kwidth}{\lsc@kxwidth}% \psaddtolength{\lsc@kwidth}{-0.35\lscLocationHeight}% \pssetlength{\lsc@kheight}{0.7\lscLocationHeight}% \rput(\lsc@X,\lsc@Y){% \pspolygon*[linecolor=white]% (-\lsc@kxwidth,-0.5\lsc@kheight)% (-\lsc@kwidth,0)% (\lsc@kwidth,0)% (\lsc@kxwidth,-0.5\lsc@kheight)% (\lsc@kwidth,-\lsc@kheight)% (-\lsc@kwidth,-\lsc@kheight)}}% % \lsc@lscotherblock % \newcommand{\lsc@otherblock}{% \pssetlength{\lsc@kxwidth}{0.5\lscLocationWidth}% \pssetlength{\lsc@kwidth}{\lsc@kxwidth}% \psaddtolength{\lsc@kwidth}{-0.35\lscLocationHeight}% \pssetlength{\lsc@kxxwidth}{\lsc@kxwidth}% \psaddtolength{\lsc@kxxwidth}{0.35\lscLocationHeight}% \pssetlength{\lsc@kheight}{0.7\lscLocationHeight}% \rput(\lsc@X,\lsc@Y){% \pspolygon*[linecolor=white]% (-\lsc@kxwidth,-0.5\lsc@kheight)% (-\lsc@kxxwidth,0)% (\lsc@kwidth,0)% (\lsc@kxwidth,-0.5\lsc@kheight)% (\lsc@kwidth,-\lsc@kheight)% (-\lsc@kxxwidth,-\lsc@kheight)}}% %% set cut colour and width of a named cut and draw a named cut -- explicitly % named cuts get names of the form 'lsc@cutnamed...Y', the unnamed cut has % names of the form 'lsc@cutinternalY' % % \lsc@setCutColour{}{} % \newcommand{\lsc@setCutColour}[2]{% \expandafter\def\csname lsc@cut#1Colour\endcsname{#2}} % \lsc@setCutWidth{}{} % \newcommand{\lsc@setCutWidth}[2]{% \expandafter\def\csname lsc@cut#1Width\endcsname{#2}} % \lsc@setCutLinestyle{}{} % \newcommand{\lsc@setCutLinestyle}[2]{% \expandafter\def\csname lsc@cut#1Linestyle\endcsname{#2}} %% drawing a cut with name comprises drawing a line in colour % \lsc@cutColour with width \lsc@cutWidth at the current Y location % over the full location width. If we are _not_ on the first instance, % then firstly a line at the leftmost boundary of the current location is % drawn from \lsc@cutY, the vertical position of the last cut segment, to % the current Y location. % % \lsc@namedCut{} % \newcommand{\lsc@namedCut}[1]{% % % if the linestyle is 'none', explicitly don't do anything -- otherwise the % 'c-c' line ends are drawn anyway... % \ifthenelse{\equal{\csname lsc@cut#1Linestyle\endcsname}{none}}{% \relax% }{{% \psset{linecolor=\csname lsc@cut#1Colour\endcsname,% linewidth=\csname lsc@cut#1Width\endcsname,% linestyle=\csname lsc@cut#1Linestyle\endcsname,% arrows=c-c}% % % if we are not on the first instance, consider to draw a vertical line % \ifthenelse{\equal{\lsc@firstinst}{\lsc@false}}{% % % it's not sufficient to check the last and the current Y position for % equality since minimal deviations have the effect that the vertical line % is drawn (and consequently creates the ugly artefact) % \ifthenelse{\lengthtest{\csname lsc@cut#1Y\endcsname > \lsc@Y}}{% \pssetlength{\lsc@cutvdiff}{\csname lsc@cut#1Y\endcsname} \addtolength{\lsc@cutvdiff}{-\lsc@Y} }{% \pssetlength{\lsc@cutvdiff}{\lsc@Y} \addtolength{\lsc@cutvdiff}{-\csname lsc@cut#1Y\endcsname} }% \ifthenelse{\lengthtest{\lsc@cutvdiff < \csname lsc@cut#1Width\endcsname}}{% % skip: don't draw vertical line when at (roughly) same height }{% \rput(-0.5\lscLocationWidth,0){% \psline(\lsc@X,\csname lsc@cut#1Y\endcsname)(\lsc@X,\lsc@Y)}% }% }{}% % % draw horizontal line % \rput(\lsc@X,\lsc@Y){% \psline(-0.5\lscLocationWidth,0)(0.5\lscLocationWidth,0)}% \expandafter\xdef\csname lsc@cut#1Y\endcsname{\the\lsc@Y}% }}% } %% helper macros for scheduling, drawing, and clearing hooks % \newcommand{\lsc@schedhook}[2]{% \global\expandafter\def\csname lsc@draw#1hook\endcsname{#2}% } % \newcommand{\lsc@clearhook}[1]{% \global\expandafter\let\csname lsc@draw#1hook\endcsname\relax}% % \newcommand{\lsc@clearhooks}{% \lsc@clearhook{actcond}% \lsc@clearhook{atom}% \lsc@clearhook{bgblock}% \lsc@clearhook{bgsimreg}% \lsc@clearhook{fgblock}% \lsc@clearhook{fgsimreg}% \lsc@clearhook{timer}% } % \newcommand{\lsc@flushhook}[1]{% \csname lsc@draw#1hook\endcsname% \lsc@clearhook{#1}% } %% do the things that have to be done before the instance line is drawn, % currently this comprises only the drawing of a multi-instance line % condition background if one is scheduled for drawing and a simregion % kuller. Used by ordinary and environment instance lines. % ('Scheduling' is done by defining macros.) % \newcommand{\lsc@linePrelude}{% \lsc@flushhook{bgsimreg}% \lsc@flushhook{bgblock}}% %% do the things that have to be done after the instance line is drawn, % currently drawing the following things given in order from back to front % (if scheduled): % - background of multi-instance line conditions % - condition or action (implies that there can be either a condition or an % action at a location) % - timer % - atom circle % % Used by ordinary and environment instance lines. % \newcommand{\lsc@linePostlude}[1]{% \lsc@flushhook{fgblock}% \lsc@flushhook{actcond}% \lsc@flushhook{timer}% \lsc@flushhook{atom}% \lsc@flushhook{fgsimreg}% \global\advance\lsc@Y by-#1\lscLocationHeight}% %% macros to draw instance lines, ordinary and environment % % \lsc@line{}{solid|dashed}{} % \newcommand{\lsc@line}[3]{% \lsc@linePrelude% \rput(\lsc@X,\lsc@Y){% % % use \pcline only if really needed -- it make small dvi files % significantly larger (adds about 0.5k per small LSC) % \psset{linestyle=#2}% \ifthenelse{\equal{#1}{}}{% \psline(0,-#3\lscLocationHeight)% }{% \pcline(0,0)(0,-#3\lscLocationHeight)% \lput[l]{0}{\ {#1}}% }% } \lsc@linePostlude{#3}% } % % \lsc@envline{}{solid|none}{} % \newcommand{\lsc@envline}[3]{% \lsc@linePrelude% \rput(\lsc@X,\lsc@Y){% % % if there is a timing interval, position it to the right of the rightmost % edge of the box % \ifthenelse{\equal{#1}{}}{% }{% \rput(\lsc@envlinewidth,0){% \pcline[linestyle=none](0,0)(0,-#3\lscLocationHeight)}% \lput[l]{0}{\ {#1}}% }% % % the instance line itself as a criss-cross filled box % \pspolygon[linestyle=none,fillstyle=hlines]% (-\lsc@envlinewidth,0)% (\lsc@envlinewidth,0)% (\lsc@envlinewidth,-#3\lscLocationHeight)% (-\lsc@envlinewidth,-#3\lscLocationHeight)% % % if it's hot, add a solid line over the middle of the box % \psline[linestyle=#2](0,-#3\lscLocationHeight)% }% \lsc@linePostlude{#3}% } %% see whether the labels for both ends of the create arrow have been defined % and if so draw the arrow. Used by the lscCreate command and the % lsccreateinst instance line. % % \lsc@createarrow{} % \newcommand{\lsc@createarrow}[1]{% \expandafter\ifx\csname lsc@createsrc#1\endcsname\relax% \relax% \else\expandafter\ifx\csname lsc@createdest#1\endcsname\relax% \relax% \else% \ncline{->}{\csname lsc@createsrc#1node\endcsname}{\csname lsc@createdest#1node\endcsname}% \global\expandafter\let\csname lsc@createsrc#1\endcsname\relax% \global\expandafter\let\csname lsc@createdest#1\endcsname\relax% \fi\fi% } %% the first two macros only draw the hourglass and hour-X of timer set/reset % and timeout, the third macro constructs a timer symbol with label and the % latter three macros are actually used by the exported macros. % \newcommand{\lsc@hourglass}{% \pspolygon[fillstyle=solid]% (-\lsc@hgwidth,\lsc@hgheight)% (\lsc@hgwidth,\lsc@hgheight)% (-\lsc@hgwidth,-\lsc@hgheight)% (\lsc@hgwidth,-\lsc@hgheight)}% % \newcommand{\lsc@hourx}{% \psline(-\lsc@hgwidth,\lsc@hgheight)% (\lsc@hgwidth,-\lsc@hgheight)% \psline(-\lsc@hgwidth,-\lsc@hgheight)% (\lsc@hgwidth,\lsc@hgheight)}% % % \lsc@timer{}{}{}{} % % The label is placed to the left of the symbol if is % negative and to the right otherwise. % % For , currently only \lsc@hgoffset or -\lsc@hgoffset are used, % for only '-' or '<-' and for \lsc@hourglass or \lsc@hourx. % \newcommand{\lsc@timer}[4]{% \rput(\lsc@X,\lsc@Y){% \rput(#1,0){% {#3}% \ifthenelse{\lengthtest{#1 < 0pt}}{% \rput[r](-1.5\lsc@hgwidth,0){{#4}}% }{% \rput[l](1.5\lsc@hgwidth,0){{#4}}% }}% \psline{#2}(0,0)(#1,0)}}% % \newcommand{\lsc@timerset}[3]{% \lsc@timer{#1}{-}{\lsc@hourglass}{{#2}({#3})}} % \newcommand{\lsc@timerreset}[2]{% \lsc@timer{#1}{-}{\lsc@hourx}{{#2}}} % \newcommand{\lsc@timeout}[2]{% \lsc@timer{#1}{<-}{\lsc@hourglass}{{#2}}} %% draw hot and cold single-instance condition % \newcommand{\lsc@cond}[1]{% \rput[t](\lsc@X,\lsc@Y){#1}} % \newcommand{\lsc@hotcond}[1]{% \lsc@cond{\lsc@hotkandis{#1}}}% % \newcommand{\lsc@coldcond}[1]{% \lsc@cond{\lsc@coldkandis{#1}}}% %% macros to draw the message arrow -- checks whether both ends are defined % % \lsc@msgarrow{a|i}{}{}{