From 94d0eb286e84b4a899b1eabd027065be9b0cf002 Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Tue, 18 Jun 2024 20:32:39 +0200 Subject: [PATCH] added basis for lifelines --- gallery/example2.pdf | Bin 0 -> 18349 bytes gallery/example2.typ | 33 +++++++++++ src/diagram.typ | 14 ++++- src/renderer.typ | 134 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 174 insertions(+), 7 deletions(-) create mode 100644 gallery/example2.pdf create mode 100644 gallery/example2.typ diff --git a/gallery/example2.pdf b/gallery/example2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..364a2eea2447d33dadc38c2d2a73bb77043156ff GIT binary patch literal 18349 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 literal 0 HcmV?d00001 diff --git a/gallery/example2.typ b/gallery/example2.typ new file mode 100644 index 0000000..8f0e5fb --- /dev/null +++ b/gallery/example2.typ @@ -0,0 +1,33 @@ +#import "/src/lib.typ" as chronos + + +#chronos.diagram({ + import "/src/diagram.typ": * + _seq("User", "A", comment: "DoWork", enable-dst: true) + _seq("A", "B", comment: [#sym.quote.angle.l createRequest #sym.quote.angle.r], enable-dst: true) + _seq("B", "C", comment: "DoWork", enable-dst: true) + _seq("C", "B", comment: "WorkDone", destroy-src: true, dashed: true) + _seq("B", "A", comment: "RequestCreated", disable-src: true, dashed: true) + _seq("A", "User", comment: "Done", disable-src: true) +}) + +#chronos.diagram({ + import "/src/diagram.typ": * + _seq("User", "A", comment: "DoWork", enable-dst: true) + _seq("A", "A", comment: "Internal call", enable-dst: true) + _seq("A", "B", comment: [#sym.quote.angle.l createRequest #sym.quote.angle.r], enable-dst: true) + _seq("B", "A", comment: "RequestCreated", disable-src: true, disable-dst: true, dashed: true) + _seq("A", "User", comment: "Done", disable-src: true) +}) + +#chronos.diagram({ + import "/src/diagram.typ": * + _seq("alice", "bob", comment: "hello", enable-dst: true) + _seq("bob", "bob", comment: "self call", enable-dst: true) + _seq("bill", "bob", comment: "hello from thread 2", enable-dst: true) + _seq("bob", "george", comment: "create", enable-dst: true) + _seq("bob", "bill", comment: "done in thread 2", disable-src: true, dashed: true) + _seq("bob", "bob", comment: "rc", disable-src: true, dashed: true) + _seq("bob", "george", comment: "delete", destroy-dst: true) + _seq("bob", "alice", comment: "success", disable-src: true, dashed: true) +}) \ No newline at end of file diff --git a/src/diagram.typ b/src/diagram.typ index 31312c9..cd4c168 100644 --- a/src/diagram.typ +++ b/src/diagram.typ @@ -8,7 +8,12 @@ dashed: false, tip: "default", color: black, - flip: false + flip: false, + enable-dst: false, + disable-dst: false, + destroy-dst: false, + disable-src: false, + destroy-src: false, ) = { return (( type: "seq", @@ -18,7 +23,12 @@ dashed: dashed, tip: tip, color: color, - flip: flip + flip: flip, + enable-dst: enable-dst, + disable-dst: disable-dst, + destroy-dst: destroy-dst, + disable-src: disable-src, + destroy-src: destroy-src, ),) } diff --git a/src/renderer.typ b/src/renderer.typ index 0c4a00c..7bf0f10 100644 --- a/src/renderer.typ +++ b/src/renderer.typ @@ -5,9 +5,15 @@ #let PAR-PAD = (5pt, 3pt) #let PAR-SPACE = 10 #let COMMENT-PAD = 8 +#let LIFELINE-W = 10 #let get-columns-width(participants, elements) = { + participants = participants.map(p => { + p.insert("lifeline-lvl", 0) + p.insert("max-lifelines", 0) + p + }) let pars-i = get-participants-i(participants) let cells = () for elmt in elements { @@ -23,6 +29,23 @@ cell: box(com, inset: 3pt) ) ) + + if elmt.disable-src or elmt.destroy-src { + let p = participants.at(i1) + p.lifeline-lvl -= 1 + participants.at(i1) = p + } + if elmt.disable-dst { + let p = participants.at(i2) + p.lifeline-lvl -= 1 + participants.at(i2) = p + } + if elmt.enable-dst { + let p = participants.at(i2) + p.lifeline-lvl += 1 + p.max-lifelines = calc.max(p.max-lifelines, p.lifeline-lvl) + participants.at(i2) = p + } } } @@ -54,6 +77,15 @@ m.width / 1pt - widths.slice(0, cell.i2 - 1).sum() ) } + for (i, w) in widths.enumerate() { + let p1 = participants.at(i) + let p2 = participants.at(i + 1) + let w = w + p1.max-lifelines * LIFELINE-W / 2 + if p2.max-lifelines != 0 { + w += LIFELINE-W / 2 + } + widths.at(i) = w + } return widths } @@ -119,12 +151,68 @@ let y = -Y-SPACE let groups = () + let lifelines = participants.map(_ => ( + level: 0, + lines: () + )) // Draw sequences for elmt in elements { if elmt.type == "seq" { - let x1 = x-pos.at(pars-i.at(elmt.p1)) - let x2 = x-pos.at(pars-i.at(elmt.p2)) + let i1 = pars-i.at(elmt.p1) + let i2 = pars-i.at(elmt.p2) + + if elmt.comment != none { + y -= measure(box(elmt.comment)).height / 1pt + 6 + } + + if elmt.disable-src { + let src-line = lifelines.at(i1) + src-line.level -= 1 + src-line.lines.push(("disable", y, auto)) + lifelines.at(i1) = src-line + } + if elmt.destroy-src { + let src-line = lifelines.at(i1) + src-line.level -= 1 + src-line.lines.push(("destroy", y, auto)) + lifelines.at(i1) = src-line + } + + let ll-lvl1 = lifelines.at(i1).level * LIFELINE-W / 2 + + if elmt.disable-dst { + let dst-line = lifelines.at(i2) + dst-line.level -= 1 + dst-line.lines.push(("disable", y, auto)) + lifelines.at(i2) = dst-line + } + if elmt.destroy-dst { + let dst-line = lifelines.at(i2) + dst-line.level -= 1 + dst-line.lines.push(("destroy", y, auto)) + lifelines.at(i2) = dst-line + } + if elmt.enable-dst { + let dst-line = lifelines.at(i2) + dst-line.level += 1 + lifelines.at(i2) = dst-line + } + + let x1 = x-pos.at(i1) + let x2 = x-pos.at(i2) + + let ll-lvl2 = lifelines.at(i2).level * LIFELINE-W / 2 + + let f = if elmt.flip {-1} else {1} + if i1 <= i2 { + x1 += ll-lvl1 * f + x2 -= ll-lvl2 * f + } else { + x1 -= ll-lvl1 * f + x2 += ll-lvl2 * f + } + let style = ( mark: (end: "straight"), stroke: ( @@ -134,10 +222,11 @@ ) if elmt.p1 == elmt.p2 { + let x3 = x1 - ll-lvl1 + ll-lvl2 + x2 = if elmt.flip {x1 - 20} else {x1 + 20} if elmt.comment != none { - y -= measure(box(elmt.comment)).height / 1pt + 6 draw.content( (x1, y), elmt.comment, @@ -150,7 +239,7 @@ (x1, y), (x2, y), (x2, y - 10), - (x1, y - 10), + (x3, y - 10), ..style ) y -= 10 @@ -161,7 +250,6 @@ if x2 < x1 { x += COMMENT-PAD } - y -= measure(box(elmt.comment)).height / 1pt + 6 draw.content( (x, y), elmt.comment, @@ -176,6 +264,11 @@ ..style ) } + if elmt.enable-dst { + let dst-line = lifelines.at(i2) + dst-line.lines.push(("enable", y, auto)) + lifelines.at(i2) = dst-line + } y -= Y-SPACE } else if elmt.type == "grp" { @@ -244,6 +337,37 @@ (x, y), stroke: (dash: "dashed", paint: gray.darken(40%)) ) + + let rects = () + let destructions = () + let lines = () + for line in lifelines.at(i).lines { + let event = line.first() + if event == "enable" { + lines.push(line) + } else if event == "disable" or event == "destroy" { + let l = lines.pop() + let lvl = lines.len() + rects.push((x + lvl * LIFELINE-W / 2, l.at(1), line.at(1))) + if event == "destroy" { + destructions.push((x + lvl * LIFELINE-W / 2, line.at(1))) + } + } + } + + for rect in rects.rev() { + let (cx, y0, y1) = rect + draw.rect( + (cx - LIFELINE-W / 2, y0), + (cx + LIFELINE-W / 2, y1), + ) + } + for dest in destructions { + let (cx, cy) = dest + draw.line((cx - 8, cy - 8), (cx + 8, cy + 8), stroke: red + 2pt) + draw.line((cx - 8, cy + 8), (cx + 8, cy - 8), stroke: red + 2pt) + } + draw.content( (x, y), p.display-name,