Skip to content
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
246 changes: 173 additions & 73 deletions tokio-console/src/view/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ impl TaskView {
pub(crate) fn update_input(&mut self, _event: input::Event) {
// TODO :D
}

pub(crate) fn render(
&mut self,
styles: &view::Styles,
Expand Down Expand Up @@ -68,76 +67,172 @@ impl TaskView {
})
.collect();

let stats_area_check = Layout::default()
.direction(layout::Direction::Horizontal)
.constraints(
[
layout::Constraint::Percentage(50),
layout::Constraint::Percentage(50),
]
.as_ref(),
)
.split(area);

let location_heading = "Location: ";
let location_max_width = stats_area_check[0].width as usize - 2 - location_heading.len(); // NOTE: -2 for the border
let max_width_stats_area = area.width - 45;
let mut location_lines_vector: Vec<String> = task
.location()
.to_string()
.chars()
.collect::<Vec<char>>()
.chunks(max_width_stats_area as usize)
.map(|chunk| chunk.iter().collect())
.collect();
let no_of_lines_extra_required_to_accomadate_location = location_lines_vector.len() - 1;
let (
controls_area,
stats_area,
poll_dur_area,
scheduled_dur_area,
fields_area,
warnings_area,
) = if warnings.is_empty() {
let chunks = Layout::default()
.direction(layout::Direction::Vertical)
) = if task.location().len() > location_max_width {
if warnings.is_empty() {
let chunks = Layout::default()
.direction(layout::Direction::Vertical)
.constraints(
[
// controls
layout::Constraint::Length(controls.height()),
// task stats
layout::Constraint::Length(
10 + no_of_lines_extra_required_to_accomadate_location as u16,
),
// poll duration
layout::Constraint::Length(9),
// scheduled duration
layout::Constraint::Length(9),
// fields
layout::Constraint::Percentage(60),
]
.as_ref(),
)
.split(area);
(chunks[0], chunks[1], chunks[2], chunks[3], chunks[4], None)
} else {
let chunks = Layout::default()
.direction(layout::Direction::Vertical)
.constraints(
[
// controls
layout::Constraint::Length(controls.height()),
// warnings (add 2 for top and bottom borders)
layout::Constraint::Length(warnings.len() as u16 + 2),
// task stats
layout::Constraint::Length(
10 + no_of_lines_extra_required_to_accomadate_location as u16,
),
// poll duration
layout::Constraint::Length(9),
// scheduled duration
layout::Constraint::Length(9),
// fields
layout::Constraint::Percentage(60),
]
.as_ref(),
)
.split(area);

(
chunks[0],
chunks[2],
chunks[3],
chunks[4],
chunks[5],
Some(chunks[1]),
)
}
} else {
if warnings.is_empty() {
let chunks = Layout::default()
.direction(layout::Direction::Vertical)
.constraints(
[
// controls
layout::Constraint::Length(controls.height()),
// task stats
layout::Constraint::Length(10),
// poll duration
layout::Constraint::Length(9),
// scheduled duration
layout::Constraint::Length(9),
// fields
layout::Constraint::Percentage(60),
]
.as_ref(),
)
.split(area);
(chunks[0], chunks[1], chunks[2], chunks[3], chunks[4], None)
} else {
let chunks = Layout::default()
.direction(layout::Direction::Vertical)
.constraints(
[
// controls
layout::Constraint::Length(controls.height()),
// warnings (add 2 for top and bottom borders)
layout::Constraint::Length(warnings.len() as u16 + 2),
// task stats
layout::Constraint::Length(10),
// poll duration
layout::Constraint::Length(9),
// scheduled duration
layout::Constraint::Length(9),
// fields
layout::Constraint::Percentage(60),
]
.as_ref(),
)
.split(area);

(
chunks[0],
chunks[2],
chunks[3],
chunks[4],
chunks[5],
Some(chunks[1]),
)
}
};

let stats_area = if location_lines_vector.len() != 1 {
let area_needed_to_render_location = task.location().len() as u16;
Layout::default()
.direction(layout::Direction::Horizontal)
.constraints(
[
// controls
layout::Constraint::Length(controls.height()),
// task stats
layout::Constraint::Length(10),
// poll duration
layout::Constraint::Length(9),
// scheduled duration
layout::Constraint::Length(9),
// fields
layout::Constraint::Percentage(60),
layout::Constraint::Min(area_needed_to_render_location + 15), //Note: 15 is the length of "| Location: |"
layout::Constraint::Min(32),
]
.as_ref(),
)
.split(area);
(chunks[0], chunks[1], chunks[2], chunks[3], chunks[4], None)
.split(stats_area)
} else {
let chunks = Layout::default()
.direction(layout::Direction::Vertical)
Layout::default()
.direction(layout::Direction::Horizontal)
.constraints(
[
// controls
layout::Constraint::Length(controls.height()),
// warnings (add 2 for top and bottom borders)
layout::Constraint::Length(warnings.len() as u16 + 2),
// task stats
layout::Constraint::Length(10),
// poll duration
layout::Constraint::Length(9),
// scheduled duration
layout::Constraint::Length(9),
// fields
layout::Constraint::Percentage(60),
layout::Constraint::Percentage(50),
layout::Constraint::Percentage(50),
]
.as_ref(),
)
.split(area);

(
chunks[0],
chunks[2],
chunks[3],
chunks[4],
chunks[5],
Some(chunks[1]),
)
.split(stats_area)
// stats_area_check
};

let stats_area = Layout::default()
.direction(layout::Direction::Horizontal)
.constraints(
[
layout::Constraint::Percentage(50),
layout::Constraint::Percentage(50),
]
.as_ref(),
)
.split(stats_area);

// Just preallocate capacity for ID, name, target, total, busy, and idle.
let mut overview = Vec::with_capacity(8);
overview.push(Line::from(vec![
Expand All @@ -152,17 +247,13 @@ impl TaskView {

overview.push(Line::from(vec![bold("Target: "), Span::raw(task.target())]));

let title = "Location: ";
let location_max_width = stats_area[0].width as usize - 2 - title.len(); // NOTE: -2 for the border
let location = if task.location().len() > location_max_width {
let ellipsis = styles.if_utf8("\u{2026}", "...");
let start = task.location().len() - location_max_width + ellipsis.chars().count();
format!("{}{}", ellipsis, &task.location()[start..])
} else {
task.location().to_string()
};

overview.push(Line::from(vec![bold(title), Span::raw(location)]));
let first_line = location_lines_vector[0].clone();
location_lines_vector.remove(0);
let location_vector = vec![bold(location_heading), Span::raw(first_line)];
overview.push(Line::from(location_vector));
for line in location_lines_vector {
overview.push(Line::from(Span::raw(format!(" {}", line))));
}

let total = task.total(now);

Expand All @@ -185,28 +276,37 @@ impl TaskView {

let mut waker_stats = vec![Line::from(vec![
bold("Current wakers: "),
Span::from(format!("{} (", task.waker_count())),
bold("clones: "),
Span::from(format!("{}, ", task.waker_clones())),
bold("drops: "),
Span::from(format!("{})", task.waker_drops())),
Span::from(format!("{} ", task.waker_count())),
])];
let waker_stats_clones = vec![
bold(" Clones: "),
Span::from(format!("{}, ", task.waker_clones())),
];

let waker_stats_drops = vec![
bold(" Drops: "),
Span::from(format!("{}", task.waker_drops())),
];

let mut wakeups = vec![
let wakeups = vec![
bold("Woken: "),
Span::from(format!("{} times", task.wakes())),
];

let mut last_woken_line = vec![];

// If the task has been woken, add the time since wake to its stats as well.
if let Some(since) = task.since_wake(now) {
wakeups.reserve(3);
wakeups.push(Span::raw(", "));
wakeups.push(bold("last woken: "));
wakeups.push(styles.time_units(since, view::DUR_LIST_PRECISION, None));
wakeups.push(Span::raw(" ago"));
last_woken_line.reserve(3);
last_woken_line.push(bold("Last woken: "));
last_woken_line.push(styles.time_units(since, view::DUR_LIST_PRECISION, None));
last_woken_line.push(Span::raw(" ago"));
}

waker_stats.push(Line::from(waker_stats_clones));
waker_stats.push(Line::from(waker_stats_drops));
waker_stats.push(Line::from(wakeups));
waker_stats.push(Line::from(last_woken_line));

if task.self_wakes() > 0 {
waker_stats.push(Line::from(vec![
Expand Down