Choose swap lanes by motion direction
This commit is contained in:
parent
b109cdf6f2
commit
a712786ecf
2 changed files with 69 additions and 3 deletions
|
|
@ -217,6 +217,9 @@ Preferred approach:
|
|||
Current pure planner status:
|
||||
|
||||
- Two-window same-axis swaps use shrink lanes, move, then grow.
|
||||
- Swap lane choice follows motion direction, not node identity: right/down
|
||||
moving windows take the first lane, and left/up moving windows take the second
|
||||
lane.
|
||||
- Stack extraction/return patterns are covered in both horizontal and vertical
|
||||
orientations: peer/container space scales first, the extracted child moves
|
||||
only after space exists, and orthogonal growth happens in the final phase.
|
||||
|
|
|
|||
|
|
@ -173,7 +173,12 @@ fn plan_axis_crossing_lanes(
|
|||
}
|
||||
|
||||
let mut windows = request.windows.clone();
|
||||
windows.sort_by_key(|window| window.node_id.0);
|
||||
windows.sort_by_key(|window| lane_index_for_direction(*window, axis));
|
||||
if windows.windows(2).any(|pair| {
|
||||
lane_index_for_direction(pair[0], axis) == lane_index_for_direction(pair[1], axis)
|
||||
}) {
|
||||
return None;
|
||||
}
|
||||
let mut phase1 = vec![];
|
||||
let mut phase2 = vec![];
|
||||
let mut phase3 = vec![];
|
||||
|
|
@ -205,6 +210,15 @@ fn plan_axis_crossing_lanes(
|
|||
)
|
||||
}
|
||||
|
||||
fn lane_index_for_direction(window: MultiphaseWindow, axis: PhaseAxis) -> Option<usize> {
|
||||
let delta = main_start(window.to, axis) - main_start(window.from, axis);
|
||||
match delta.cmp(&0) {
|
||||
std::cmp::Ordering::Greater => Some(0),
|
||||
std::cmp::Ordering::Less => Some(1),
|
||||
std::cmp::Ordering::Equal => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn plan_space_then_orthogonal_growth(
|
||||
request: &MultiphaseRequest,
|
||||
axis: PhaseAxis,
|
||||
|
|
@ -627,6 +641,15 @@ mod tests {
|
|||
plan.phases.iter().map(|phase| phase.action).collect()
|
||||
}
|
||||
|
||||
fn step_to(plan: &MultiphasePlan, phase: usize, node_id: NodeId) -> Rect {
|
||||
plan.phases[phase]
|
||||
.steps
|
||||
.iter()
|
||||
.find(|step| step.node_id == node_id)
|
||||
.unwrap()
|
||||
.to
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn horizontal_swap_shrinks_moves_then_grows_without_overlap() {
|
||||
let req = request(vec![
|
||||
|
|
@ -679,8 +702,48 @@ mod tests {
|
|||
},
|
||||
]);
|
||||
let plan = plan_no_overlap(&req).unwrap();
|
||||
assert_eq!(plan.phases[0].steps[0].to, rect(100, 0, 200, 50));
|
||||
assert_eq!(plan.phases[0].steps[1].to, rect(0, 50, 100, 100));
|
||||
assert_eq!(step_to(&plan, 0, id(2)), rect(0, 0, 100, 50));
|
||||
assert_eq!(step_to(&plan, 0, id(1)), rect(100, 50, 200, 100));
|
||||
assert!(validate_plan_continuous(&req, &plan));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn horizontal_swap_lanes_follow_motion_direction_not_node_id() {
|
||||
let req = request(vec![
|
||||
MultiphaseWindow {
|
||||
node_id: id(1),
|
||||
from: rect(100, 0, 200, 100),
|
||||
to: rect(0, 0, 100, 100),
|
||||
},
|
||||
MultiphaseWindow {
|
||||
node_id: id(2),
|
||||
from: rect(0, 0, 100, 100),
|
||||
to: rect(100, 0, 200, 100),
|
||||
},
|
||||
]);
|
||||
let plan = plan_no_overlap(&req).unwrap();
|
||||
assert_eq!(step_to(&plan, 0, id(2)), rect(0, 0, 100, 50));
|
||||
assert_eq!(step_to(&plan, 0, id(1)), rect(100, 50, 200, 100));
|
||||
assert!(validate_plan_continuous(&req, &plan));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vertical_swap_lanes_follow_motion_direction_not_node_id() {
|
||||
let req = request(vec![
|
||||
MultiphaseWindow {
|
||||
node_id: id(1),
|
||||
from: rect(0, 100, 100, 200),
|
||||
to: rect(0, 0, 100, 100),
|
||||
},
|
||||
MultiphaseWindow {
|
||||
node_id: id(2),
|
||||
from: rect(0, 0, 100, 100),
|
||||
to: rect(0, 100, 100, 200),
|
||||
},
|
||||
]);
|
||||
let plan = plan_no_overlap(&req).unwrap();
|
||||
assert_eq!(step_to(&plan, 0, id(2)), rect(0, 0, 50, 100));
|
||||
assert_eq!(step_to(&plan, 0, id(1)), rect(50, 100, 100, 200));
|
||||
assert!(validate_plan_continuous(&req, &plan));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue