%%
%% This is file `messagepassing.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% messagepassing.dtx  (with options: `package')
%% This is a generated file.
%% Copyright (C) 2022 by Martin Vassor
%% 
%% This file 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.
%% 

 \NeedsTeXFormat{LaTeX2e}
 \ProvidesPackage{messagepassing}[2022/02/18 v1.0 A package to draw message passing diagrams]
 \RequirePackage{tikz}
 \usetikzlibrary{quotes, calc, arrows.meta}
 \RequirePackage{xparse}
 \RequirePackage{float}


















\newcounter{processnb}
\setcounter{processnb}{0}
\newcounter{maxtime}

\pgfdeclarelayer{background}
\pgfsetlayers{background,main}

\newfloat{float_messagepassing}{t b h p}{.mp}
\floatname{float_messagepassing}{Execution}

\newif\ifmp@vertical\mp@verticalfalse
\DeclareOption{vertical}{
\mp@verticaltrue
}
\newif\ifmp@annotatevertical\mp@annotateverticalfalse
\DeclareOption{annotatevertical}{
\mp@annotateverticaltrue
}
\ProcessOptions\relax

\ifmp@vertical
\newcommand{\mp@processnameanchor}{south}
\newcommand{\mp@timeticksanchor}{east}
\newcommand{\mp@messagelabelanchor}{south}
\newcommand{\mp@stateintervalanchor}{north west}
\newcommand{\mp@checkpointanchor}{east}
\newcommand{\mp@verticalrotation}{270}
\ifmp@annotatevertical
\newcommand{\mp@annotaterotation}{270}
\else
\newcommand{\mp@annotaterotation}{0}
\fi
\else
\newcommand{\mp@processnameanchor}{east}
\newcommand{\mp@timeticksanchor}{north}
\newcommand{\mp@messagelabelanchor}{west}
\newcommand{\mp@stateintervalanchor}{south west}
\newcommand{\mp@checkpointanchor}{north}
\newcommand{\mp@verticalrotation}{0}
\newcommand{\mp@annotaterotation}{0}
\fi

\newcommand{\mp@oobcolor}{red}
\newcommand{\oobcolor}[1]{
\renewcommand\mp@oobcolor{#1}
}

\newcommand{\mp@colouredboxcolor}{red}
\newcommand{\colouredboxcolor}[1]{
\renewcommand\mp@colouredboxcolor{#1}
}

\newif\iftimeline

\ExplSyntaxOn
%% 1st argument: tikz arguments
%% 2nd argument: Float caption (turns in floating)
%% 3rd argument: Float placement (`p` by default)
%% 4th argument: Float label
\NewDocumentEnvironment{messagepassing} {o o o o}
{
\timelinefalse
\setcounter{processnb}{0}
\IfNoValueTF{#2} {
}{
\IfNoValueTF{#3}{
\begin{float_messagepassing}[p]
} {
\begin{float_messagepassing}[#3]
}
\begin{center}
}
\IfNoValueTF{#1}{
\begin{tikzpicture}[rotate=\mp@verticalrotation]
} {
\begin{tikzpicture}[rotate=\mp@verticalrotation, #1]
}
}{
%% Draw timeline if boolean is true
\iftimeline
\begin{pgfonlayer}{background}
\setcounter{maxtime}{\@maxtime}
\addtocounter{maxtime}{-1}
\coordinate (maxtime) at (\@maxtime, 0);

\addtocounter{processnb}{1}
\coordinate (timeline) at (0, -\value{processnb});
\draw (timeline) node [anchor=\mp@processnameanchor] {{\it time}};
\draw[->] (timeline) -- ($(timeline) + (maxtime)$);
\foreach \i in {0,...,\value{maxtime}} {
\draw ($(timeline) + (\i, 0) + (0, 0.1)$) -- ($(timeline) + (\i, 0) + (0, -0.1)$) node [anchor=\mp@timeticksanchor] {$\i$};
}
\end{pgfonlayer}
\else
\fi
\end{tikzpicture}
\IfNoValueTF{#2} {
\linebreak
} {
\end{center}
\caption{#2}
\IfNoValueTF{#4} {
}{
\label{#4}
}
\end{float_messagepassing}
}
}
\ExplSyntaxOff
%% #1: name
\newcommand{\newprocess}[1]{
\addtocounter{processnb}{1}
\coordinate (#1) at (0, -\value{processnb});
\draw (#1) node[anchor=\mp@processnameanchor] {$#1$};
}
%% #1: name
%% #2: width
\newcommand{\newprocesswithlength}[2]{
\newprocess{#1}
\processlength{#1}{#2}
}
%% #1: name
%% #2: state interval name
\newcommand{\newprocesswithstateinterval}[2]{
\newprocess{#1}
\stateinterval{#1}{0}{#2}
}
%% #1: name
%% #2: width
%% #3: crash name
\newcommand{\newprocesswithcrash}[3]{
\newprocess{#1}{#2}
\crash{#1}{#2}{#3}
}
%% #1: sender's name
%% #2: send date
%% #3: receiver's name
%% #4: receive date
\newcommand{\send}[4]{
\draw[->] (#1) +(#2, 0) -- ($ (#3) +(#4, 0) $);
}
%% #1: sender's name
%% #2: send date
%% #3: receiver's name
%% #4: receive date
%% #5: message name
\newcommand{\sendwithname}[5]{
\draw[->] (#1) +(#2, 0) -- ($ (#3) +(#4, 0) $) node[anchor=\mp@messagelabelanchor, pos=0.3] {#5};
}
%% #1: process name
%% #2: process width
\newcommand{\processlength}[2]{
\draw (#1) -- +(#2, 0);
}
%% #1: sender's name
%% #2: send date
%% #3: receiver's name
%% #4: receive date
%% #5: state interval name
\newcommand{\sendwithstateinterval}[5] {
\send{#1}{#2}{#3}{#4}
\stateinterval{#3}{#4}{#5}
}
%% #1: sender's name
%% #2: send date
%% #3: receiver's name
%% #4: receive date
%% #5: state interval name
%% #6: message name
\newcommand{\sendwithstateintervalandname}[6] {
\sendwithname{#1}{#2}{#3}{#4}{#6}
\stateinterval{#3}{#4}{#5}
}
%% #1: sender's name
%% #2: send date
%% #3: receiver's name
%% #4: receive date
%% #5: OoB message name
\newcommand{\sendoutofband}[5]{
\draw[->, color=\mp@oobcolor] (#1) +(#2, 0) -- ($ (#3) +(#4, 0) $) node[anchor=\mp@messagelabelanchor, pos=0.3] {#5};
}
%% #1: process's name
%% #2: state interval date
%% #3: state interval name
\newcommand{\stateinterval}[3] {
\stateintervalspecial{#1}{#2}{#3}{#3}
}
%% #1: process's name
%% #2: state interval date
%% #3: coordinate name
%% #4: state interval label
\newcommand{\stateintervalspecial}[4] {
\coordinate (#3) at ($ (#1) +(#2, 0) $);
\draw (#3) + (0, 0.1) -- +(0, -0.1) node[anchor=\mp@stateintervalanchor] {$#4$};
}
%% #1: process's name
%% #2: checkpoint date
%% #3: checkpoint name
\newcommand{\checkpoint}[3]{
\coordinate (#3) at ($ (#1) + (#2, 0) $);
\fill (#3) + (-0.05, 0.1) rectangle +(0.05, -0.1);
\draw (#3) + (0, -0.1) node[anchor=\mp@checkpointanchor] {$#3$};
}
%% #1: process's name
%% #2: checkpoint date
%% #3: checkpoint coordinate name
%% #4: checkpoint label
\newcommand{\checkpointspecial}[4]{
\coordinate (#3) at ($ (#1) + (#2, 0) $);
\fill (#3) + (-0.05, 0.1) rectangle +(0.05, -0.1);
\draw (#3) + (0, -0.1) node[anchor=\mp@checkpointanchor] {#4};
}
%% #1: process's name
%% #2: crash date
%% #3: crash name
\newcommand{\crash}[3]{
\coordinate (#3) at ($ (#1) + (#2, 0) $);
\draw (#3) + (-0.1, -0.1) -- +(0.1, 0.1);
\draw (#3) + (0.1, -0.1) -- +(-0.1, 0.1);
}
%% #1: process's name
%% #2: restart date
%% #3: restart length
\newcommand{\restart}[3]{
\draw (#1) + (#2, 0) --  ($ (#1) + (#2, 0) + (#3, 0) $);
}
%% #1: first process's name
%% #2: second process's name
%% #3: begining of the grey box
%% #4: end of the grey box
%% #5: caption
\newcommand{\colouredbox}[5]{
\begin{pgfonlayer}{background}
\fill[color=\mp@colouredboxcolor!20] ($(#1) + (#3, 0)$) rectangle ($(#2) + (#4, 0)$) node[midway, color = \mp@colouredboxcolor, rotate=\mp@annotaterotation]{#5};
\end{pgfonlayer}
}
%% #1: Timeline length
\newcommand{\drawtimeline}[1]{
\timelinetrue
\def\@maxtime{#1}
}
%% #1: process's name
%% #2: annotation date
%% #3: annotation
\newcommand{\annotate}[3]{
\annotatexplicit{#1}{#2}{#3}{#3}
}
%% Same than annotate, but with the coordinate name provided explicitly
%% #1: process's name
%% #2: annotation date
%% #3: annotation
%% #4: coordinate name
\newcommand{\annotatexplicit}[4]{
\coordinate (#4) at ($ (#1) +(#2, 0.1) $);
\draw (#4) node[rotate=\mp@annotaterotation, anchor=south] {#3};
}
\endinput
%%
%% End of file `messagepassing.sty'.
