Skip to content

Commit 05371a8

Browse files
committed
Use relative y positions during layout
This will make it possible in future to position fibers based on their size. Before, we needed to know a fiber's final position before calculating its height.
1 parent 8941ee3 commit 05371a8

File tree

1 file changed

+31
-14
lines changed

1 file changed

+31
-14
lines changed

lib/layout.ml

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,15 @@ let as_string = function
104104
| `String s -> s
105105
| _ -> failwith "Not a string"
106106

107-
let rec layout_item ~duration ~y (i : item) =
108-
if debug_layout then Fmt.epr "%d is at %d@." i.id y;
109-
i.y <- y;
107+
(* Walk the tree rooted at [i], calculating heights and positions.
108+
Note: visited items have their [y] fields set to their position relative to
109+
their parent. This gets turned into an absolute position later. *)
110+
let rec layout_item ~duration (i : item) =
111+
i.y <- 0;
110112
i.height <- 1;
111113
i.end_cc_label <- None;
112114
let intervals = ref [] in
115+
(* Position CCs at the same place as [i]. *)
113116
i.events |> Array.iter (fun (ts, e) ->
114117
match e with
115118
| Log _ | Error _ ->
@@ -122,13 +125,14 @@ let rec layout_item ~duration ~y (i : item) =
122125
if i.end_cc_label = None then (
123126
i.end_cc_label <- Some ts;
124127
);
125-
layout_item ~duration ~y child;
128+
layout_item ~duration child;
126129
i.height <- max i.height child.height;
127130
let stop = Option.value child.end_time ~default:duration in
128131
intervals := { Itv.value = child; start = ts; stop } :: !intervals;
129132
);
130133
if i.end_cc_label = None then i.end_cc_label <- i.end_time;
131-
let start_fibers = List.length !intervals in
134+
let n_ccs = List.length !intervals in
135+
(* Position fibers where there is space, not overlapping CCs or other fibers. *)
132136
i.events |> Array.iter (fun (ts, e) ->
133137
match e with
134138
| Log _ | Error _ | Create_cc _ -> ()
@@ -140,36 +144,49 @@ let rec layout_item ~duration ~y (i : item) =
140144
let intervals = List.rev !intervals in
141145
let itv = Itv.create intervals in
142146
let height = ref i.height in
143-
intervals |> List.to_seq |> Seq.drop start_fibers |> Seq.iter (fun (interval : _ Itv.interval) ->
144-
let y = ref (i.y + 1) in
147+
intervals |> List.to_seq |> Seq.drop n_ccs |> Seq.iter (fun (interval : _ Itv.interval) ->
148+
let y = ref 1 in
145149
let adjust other =
146150
y := max !y (other.y + other.height);
147151
in
148152
Itv.iter_overlaps adjust interval.start interval.stop itv;
149153
let f = interval.Itv.value in
150-
layout_item ~duration ~y:!y f;
151-
height := max !height (f.y - i.y + f.height);
154+
layout_item ~duration f;
155+
f.y <- !y;
156+
height := max !height (f.y + f.height);
152157
);
153-
i.height <- !height;
154-
if debug_layout then Fmt.epr "%d is at %d+%d@." i.id y i.height
158+
i.height <- !height
159+
160+
(* Walk the tree rooted at [i] converting relative [y] values to absolute ones,
161+
using [parent] for zero. *)
162+
let rec make_y_absolute i parent =
163+
i.y <- i.y + parent;
164+
if debug_layout then Fmt.epr "%d is at %d (height %d)@." i.id i.y i.height;
165+
i.events |> Array.iter (fun (_ts, e) ->
166+
match e with
167+
| Log _ | Error _ -> ()
168+
| Add_fiber { parent = _; child }
169+
| Create_cc (_, child) -> make_y_absolute child i.y
170+
)
155171

156172
let layout_ring ~duration (ring : Ring.t) =
157173
let max_y = ref 1 in
158174
let visit_domain root =
159175
root.Ring.cc |> Option.iter @@ fun (_ts, (i : item)) ->
160-
i.y <- ring.y + 1;
176+
i.y <- 1;
161177
i.height <- 1;
162178
i.end_cc_label <- None;
163179
i.events |> Array.iter (fun (_ts, e) ->
164180
match e with
165181
| Log _ | Error _ | Create_cc _ -> ()
166182
| Add_fiber { parent = _; child } ->
167-
layout_item ~duration ~y:(ring.y + i.height) child;
168-
i.height <- child.y - ring.y + child.height;
183+
layout_item ~duration child;
184+
i.height <- max i.height (child.y + child.height);
169185
if i.end_cc_label = None then (
170186
i.end_cc_label <- child.end_cc_label;
171187
);
172188
);
189+
make_y_absolute i ring.y;
173190
max_y := max !max_y (i.y + i.height - 1);
174191
in
175192
List.iter visit_domain ring.roots;

0 commit comments

Comments
 (0)