refactor(layout): simplify split() function (#396)

Removes some unnecessary code and makes the function more readable.
Instead of creating a temporary result and mutating it, we just create
the result directly from the list of changes.
This commit is contained in:
hasezoey 2023-08-15 01:17:21 +02:00 committed by GitHub
parent 8c55158822
commit 519509945b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -273,27 +273,13 @@ impl Layout {
fn split(area: Rect, layout: &Layout) -> Rc<[Rect]> { fn split(area: Rect, layout: &Layout) -> Rc<[Rect]> {
let mut solver = Solver::new(); let mut solver = Solver::new();
let mut vars: HashMap<Variable, (usize, usize)> = HashMap::new();
let elements = layout let elements = layout
.constraints .constraints
.iter() .iter()
.map(|_| Element::new()) .map(|_| Element::new())
.collect::<Vec<Element>>(); .collect::<Vec<Element>>();
let mut res = layout
.constraints
.iter()
.map(|_| Rect::default())
.collect::<Rc<[Rect]>>();
let results = Rc::get_mut(&mut res).expect("newly created Rc should have no shared refs");
let dest_area = area.inner(&layout.margin); let dest_area = area.inner(&layout.margin);
for (i, e) in elements.iter().enumerate() {
vars.insert(e.x, (i, 0));
vars.insert(e.y, (i, 1));
vars.insert(e.width, (i, 2));
vars.insert(e.height, (i, 3));
}
let mut ccs: Vec<CassowaryConstraint> = let mut ccs: Vec<CassowaryConstraint> =
Vec::with_capacity(elements.len() * 4 + layout.constraints.len() * 6); Vec::with_capacity(elements.len() * 4 + layout.constraints.len() * 6);
for elt in &elements { for elt in &elements {
@ -379,33 +365,21 @@ fn split(area: Rect, layout: &Layout) -> Rc<[Rect]> {
} }
} }
solver.add_constraints(&ccs).unwrap(); solver.add_constraints(&ccs).unwrap();
for &(var, value) in solver.fetch_changes() { let changes: HashMap<Variable, f64> = solver.fetch_changes().iter().copied().collect();
let (index, attr) = vars[&var]; let mut results = elements
let value = if value.is_sign_negative() { .iter()
0 .map(|element| Rect {
} else { x: changes.get(&element.x).map(|&v| v as u16).unwrap_or(0),
value as u16 y: changes.get(&element.y).map(|&v| v as u16).unwrap_or(0),
}; width: changes.get(&element.width).map(|&v| v as u16).unwrap_or(0),
match attr { height: changes.get(&element.height).map(|&v| v as u16).unwrap_or(0),
0 => { })
results[index].x = value; .collect::<Rc<[Rect]>>();
}
1 => {
results[index].y = value;
}
2 => {
results[index].width = value;
}
3 => {
results[index].height = value;
}
_ => {}
}
}
if layout.expand_to_fill { if layout.expand_to_fill {
// Fix imprecision by extending the last item a bit if necessary // Fix imprecision by extending the last item a bit if necessary
if let Some(last) = results.last_mut() { // "unwrap" is safe, because the Rc at this point has no shared references
if let Some(last) = Rc::get_mut(&mut results).unwrap().last_mut() {
match layout.direction { match layout.direction {
Direction::Vertical => { Direction::Vertical => {
last.height = dest_area.bottom() - last.y; last.height = dest_area.bottom() - last.y;
@ -416,7 +390,8 @@ fn split(area: Rect, layout: &Layout) -> Rc<[Rect]> {
} }
} }
} }
res
results
} }
/// A container used by the solver inside split /// A container used by the solver inside split