@@ -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
156172let 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