mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-08 12:21:09 +03:00
Some optimizsations in TUI (#3325)
* Do not allocate String for static status, use Cow instead, eg we allocate "Running" string at every refresh * Use static dispatch for Views instead of Box<dyn View> * Update only the current view * Simplify Listener trait
This commit is contained in:
parent
a8b8dc3a7f
commit
731528c616
8 changed files with 56 additions and 52 deletions
|
@ -28,9 +28,9 @@ use std::collections::VecDeque;
|
||||||
pub struct TUILogsView;
|
pub struct TUILogsView;
|
||||||
|
|
||||||
impl TUILogsView {
|
impl TUILogsView {
|
||||||
pub fn create() -> Box<dyn View> {
|
pub fn create() -> impl View {
|
||||||
let logs_view = ResizedView::with_full_screen(LogBufferView::new(200).with_name("logs"));
|
let logs_view = ResizedView::with_full_screen(LogBufferView::new(200).with_name("logs"));
|
||||||
Box::new(logs_view.with_name(VIEW_LOGS))
|
logs_view.with_name(VIEW_LOGS)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(c: &mut Cursive, entry: LogEntry) {
|
pub fn update(c: &mut Cursive, entry: LogEntry) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ use crate::tui::constants::{
|
||||||
VIEW_PEER_SYNC, VIEW_VERSION,
|
VIEW_PEER_SYNC, VIEW_VERSION,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn create() -> Box<dyn View> {
|
pub fn create() -> impl View {
|
||||||
let mut main_menu = SelectView::new().h_align(HAlign::Left).with_name(MAIN_MENU);
|
let mut main_menu = SelectView::new().h_align(HAlign::Left).with_name(MAIN_MENU);
|
||||||
main_menu
|
main_menu
|
||||||
.get_mut()
|
.get_mut()
|
||||||
|
@ -83,5 +83,5 @@ pub fn create() -> Box<dyn View> {
|
||||||
.child(TextView::new("Enter : Select"))
|
.child(TextView::new("Enter : Select"))
|
||||||
.child(TextView::new("Esc : Back "))
|
.child(TextView::new("Esc : Back "))
|
||||||
.child(TextView::new("Q : Quit "));
|
.child(TextView::new("Q : Quit "));
|
||||||
Box::new(main_menu)
|
main_menu
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,9 +165,9 @@ impl TableViewItem<DiffColumn> for DiffBlock {
|
||||||
/// Mining status view
|
/// Mining status view
|
||||||
pub struct TUIMiningView;
|
pub struct TUIMiningView;
|
||||||
|
|
||||||
impl TUIStatusListener for TUIMiningView {
|
impl TUIMiningView {
|
||||||
/// Create the mining view
|
/// Create the mining view
|
||||||
fn create() -> Box<dyn View> {
|
pub fn create() -> impl View {
|
||||||
let devices_button = Button::new_raw("Mining Server Status", |s| {
|
let devices_button = Button::new_raw("Mining Server Status", |s| {
|
||||||
let _ = s.call_on_name("mining_stack_view", |sv: &mut StackView| {
|
let _ = s.call_on_name("mining_stack_view", |sv: &mut StackView| {
|
||||||
let pos = sv.find_layer_from_name("mining_device_view").unwrap();
|
let pos = sv.find_layer_from_name("mining_device_view").unwrap();
|
||||||
|
@ -307,9 +307,11 @@ impl TUIStatusListener for TUIMiningView {
|
||||||
let _ = c.focus_name(MAIN_MENU);
|
let _ = c.focus_name(MAIN_MENU);
|
||||||
});
|
});
|
||||||
|
|
||||||
Box::new(mining_view.with_name(VIEW_MINING))
|
mining_view.with_name(VIEW_MINING)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TUIStatusListener for TUIMiningView {
|
||||||
/// update
|
/// update
|
||||||
fn update(c: &mut Cursive, stats: &ServerStats) {
|
fn update(c: &mut Cursive, stats: &ServerStats) {
|
||||||
c.call_on_name("diff_cur_height", |t: &mut TextView| {
|
c.call_on_name("diff_cur_height", |t: &mut TextView| {
|
||||||
|
|
|
@ -121,8 +121,8 @@ impl TableViewItem<PeerColumn> for PeerStats {
|
||||||
|
|
||||||
pub struct TUIPeerView;
|
pub struct TUIPeerView;
|
||||||
|
|
||||||
impl TUIStatusListener for TUIPeerView {
|
impl TUIPeerView {
|
||||||
fn create() -> Box<dyn View> {
|
pub fn create() -> impl View {
|
||||||
let table_view = TableView::<PeerStats, PeerColumn>::new()
|
let table_view = TableView::<PeerStats, PeerColumn>::new()
|
||||||
.column(PeerColumn::Address, "Address", |c| c.width_percent(16))
|
.column(PeerColumn::Address, "Address", |c| c.width_percent(16))
|
||||||
.column(PeerColumn::State, "State", |c| c.width_percent(8))
|
.column(PeerColumn::State, "State", |c| c.width_percent(8))
|
||||||
|
@ -159,9 +159,11 @@ impl TUIStatusListener for TUIPeerView {
|
||||||
let _ = c.focus_name(MAIN_MENU);
|
let _ = c.focus_name(MAIN_MENU);
|
||||||
});
|
});
|
||||||
|
|
||||||
Box::new(peer_status_view)
|
peer_status_view
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TUIStatusListener for TUIPeerView {
|
||||||
fn update(c: &mut Cursive, stats: &ServerStats) {
|
fn update(c: &mut Cursive, stats: &ServerStats) {
|
||||||
let lp = stats
|
let lp = stats
|
||||||
.peer_stats
|
.peer_stats
|
||||||
|
|
|
@ -20,6 +20,7 @@ use cursive::traits::Identifiable;
|
||||||
use cursive::view::View;
|
use cursive::view::View;
|
||||||
use cursive::views::{LinearLayout, ResizedView, TextView};
|
use cursive::views::{LinearLayout, ResizedView, TextView};
|
||||||
use cursive::Cursive;
|
use cursive::Cursive;
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use crate::tui::constants::VIEW_BASIC_STATUS;
|
use crate::tui::constants::VIEW_BASIC_STATUS;
|
||||||
use crate::tui::types::TUIStatusListener;
|
use crate::tui::types::TUIStatusListener;
|
||||||
|
@ -32,11 +33,11 @@ const NANO_TO_MILLIS: f64 = 1.0 / 1_000_000.0;
|
||||||
pub struct TUIStatusView;
|
pub struct TUIStatusView;
|
||||||
|
|
||||||
impl TUIStatusView {
|
impl TUIStatusView {
|
||||||
fn update_sync_status(sync_status: SyncStatus) -> String {
|
pub fn update_sync_status(sync_status: SyncStatus) -> Cow<'static, str> {
|
||||||
match sync_status {
|
match sync_status {
|
||||||
SyncStatus::Initial => "Initializing".to_string(),
|
SyncStatus::Initial => Cow::Borrowed("Initializing"),
|
||||||
SyncStatus::NoSync => "Running".to_string(),
|
SyncStatus::NoSync => Cow::Borrowed("Running"),
|
||||||
SyncStatus::AwaitingPeers(_) => "Waiting for peers".to_string(),
|
SyncStatus::AwaitingPeers(_) => Cow::Borrowed("Waiting for peers"),
|
||||||
SyncStatus::HeaderSync {
|
SyncStatus::HeaderSync {
|
||||||
current_height,
|
current_height,
|
||||||
highest_height,
|
highest_height,
|
||||||
|
@ -46,7 +47,7 @@ impl TUIStatusView {
|
||||||
} else {
|
} else {
|
||||||
current_height * 100 / highest_height
|
current_height * 100 / highest_height
|
||||||
};
|
};
|
||||||
format!("Sync step 1/7: Downloading headers: {}%", percent)
|
Cow::Owned(format!("Sync step 1/7: Downloading headers: {}%", percent))
|
||||||
}
|
}
|
||||||
SyncStatus::TxHashsetDownload(stat) => {
|
SyncStatus::TxHashsetDownload(stat) => {
|
||||||
if stat.total_size > 0 {
|
if stat.total_size > 0 {
|
||||||
|
@ -55,23 +56,23 @@ impl TUIStatusView {
|
||||||
let fin = Utc::now().timestamp_nanos();
|
let fin = Utc::now().timestamp_nanos();
|
||||||
let dur_ms = (fin - start) as f64 * NANO_TO_MILLIS;
|
let dur_ms = (fin - start) as f64 * NANO_TO_MILLIS;
|
||||||
|
|
||||||
format!("Sync step 2/7: Downloading {}(MB) chain state for state sync: {}% at {:.1?}(kB/s)",
|
Cow::Owned(format!("Sync step 2/7: Downloading {}(MB) chain state for state sync: {}% at {:.1?}(kB/s)",
|
||||||
stat.total_size / 1_000_000,
|
stat.total_size / 1_000_000,
|
||||||
percent,
|
percent,
|
||||||
if dur_ms > 1.0f64 { stat.downloaded_size.saturating_sub(stat.prev_downloaded_size) as f64 / dur_ms as f64 } else { 0f64 },
|
if dur_ms > 1.0f64 { stat.downloaded_size.saturating_sub(stat.prev_downloaded_size) as f64 / dur_ms as f64 } else { 0f64 },
|
||||||
)
|
))
|
||||||
} else {
|
} else {
|
||||||
let start = stat.start_time.timestamp_millis();
|
let start = stat.start_time.timestamp_millis();
|
||||||
let fin = Utc::now().timestamp_millis();
|
let fin = Utc::now().timestamp_millis();
|
||||||
let dur_secs = (fin - start) / 1000;
|
let dur_secs = (fin - start) / 1000;
|
||||||
|
|
||||||
format!("Sync step 2/7: Downloading chain state for state sync. Waiting remote peer to start: {}s",
|
Cow::Owned(format!("Sync step 2/7: Downloading chain state for state sync. Waiting remote peer to start: {}s",
|
||||||
dur_secs,
|
dur_secs,
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SyncStatus::TxHashsetSetup => {
|
SyncStatus::TxHashsetSetup => {
|
||||||
"Sync step 3/7: Preparing chain state for validation".to_string()
|
Cow::Borrowed("Sync step 3/7: Preparing chain state for validation")
|
||||||
}
|
}
|
||||||
SyncStatus::TxHashsetRangeProofsValidation {
|
SyncStatus::TxHashsetRangeProofsValidation {
|
||||||
rproofs,
|
rproofs,
|
||||||
|
@ -82,10 +83,10 @@ impl TUIStatusView {
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
format!(
|
Cow::Owned(format!(
|
||||||
"Sync step 4/7: Validating chain state - range proofs: {}%",
|
"Sync step 4/7: Validating chain state - range proofs: {}%",
|
||||||
r_percent
|
r_percent
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
SyncStatus::TxHashsetKernelsValidation {
|
SyncStatus::TxHashsetKernelsValidation {
|
||||||
kernels,
|
kernels,
|
||||||
|
@ -96,16 +97,16 @@ impl TUIStatusView {
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
format!(
|
Cow::Owned(format!(
|
||||||
"Sync step 5/7: Validating chain state - kernels: {}%",
|
"Sync step 5/7: Validating chain state - kernels: {}%",
|
||||||
k_percent
|
k_percent
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
SyncStatus::TxHashsetSave => {
|
SyncStatus::TxHashsetSave => {
|
||||||
"Sync step 6/7: Finalizing chain state for state sync".to_string()
|
Cow::Borrowed("Sync step 6/7: Finalizing chain state for state sync")
|
||||||
}
|
}
|
||||||
SyncStatus::TxHashsetDone => {
|
SyncStatus::TxHashsetDone => {
|
||||||
"Sync step 6/7: Finalized chain state for state sync".to_string()
|
Cow::Borrowed("Sync step 6/7: Finalized chain state for state sync")
|
||||||
}
|
}
|
||||||
SyncStatus::BodySync {
|
SyncStatus::BodySync {
|
||||||
current_height,
|
current_height,
|
||||||
|
@ -116,16 +117,14 @@ impl TUIStatusView {
|
||||||
} else {
|
} else {
|
||||||
current_height * 100 / highest_height
|
current_height * 100 / highest_height
|
||||||
};
|
};
|
||||||
format!("Sync step 7/7: Downloading blocks: {}%", percent)
|
Cow::Owned(format!("Sync step 7/7: Downloading blocks: {}%", percent))
|
||||||
}
|
}
|
||||||
SyncStatus::Shutdown => "Shutting down, closing connections".to_string(),
|
SyncStatus::Shutdown => Cow::Borrowed("Shutting down, closing connections"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl TUIStatusListener for TUIStatusView {
|
|
||||||
/// Create basic status view
|
/// Create basic status view
|
||||||
fn create() -> Box<dyn View> {
|
pub fn create() -> impl View {
|
||||||
let basic_status_view = ResizedView::with_full_screen(
|
let basic_status_view = ResizedView::with_full_screen(
|
||||||
LinearLayout::new(Orientation::Vertical)
|
LinearLayout::new(Orientation::Vertical)
|
||||||
.child(
|
.child(
|
||||||
|
@ -232,9 +231,11 @@ impl TUIStatusListener for TUIStatusView {
|
||||||
.child(TextView::new(" ").with_name("basic_network_info")),
|
.child(TextView::new(" ").with_name("basic_network_info")),
|
||||||
), //.child(logo_view)
|
), //.child(logo_view)
|
||||||
);
|
);
|
||||||
Box::new(basic_status_view.with_name(VIEW_BASIC_STATUS))
|
basic_status_view.with_name(VIEW_BASIC_STATUS)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TUIStatusListener for TUIStatusView {
|
||||||
fn update(c: &mut Cursive, stats: &ServerStats) {
|
fn update(c: &mut Cursive, stats: &ServerStats) {
|
||||||
let basic_status = TUIStatusView::update_sync_status(stats.sync_status);
|
let basic_status = TUIStatusView::update_sync_status(stats.sync_status);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
//! Types specific to the UI module
|
//! Types specific to the UI module
|
||||||
|
|
||||||
use crate::servers::ServerStats;
|
use crate::servers::ServerStats;
|
||||||
use cursive::view::View;
|
|
||||||
use cursive::Cursive;
|
use cursive::Cursive;
|
||||||
|
|
||||||
/// Main message struct to communicate between the UI and
|
/// Main message struct to communicate between the UI and
|
||||||
|
@ -28,8 +27,6 @@ pub enum UIMessage {
|
||||||
/// and updates itself
|
/// and updates itself
|
||||||
|
|
||||||
pub trait TUIStatusListener {
|
pub trait TUIStatusListener {
|
||||||
/// create the view, to return to the main UI controller
|
|
||||||
fn create() -> Box<dyn View>;
|
|
||||||
/// Update according to status update contents
|
/// Update according to status update contents
|
||||||
fn update(c: &mut Cursive, stats: &ServerStats);
|
fn update(c: &mut Cursive, stats: &ServerStats);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,17 @@ use cursive::theme::{BaseColor, BorderStyle, Color, Theme};
|
||||||
use cursive::traits::Boxable;
|
use cursive::traits::Boxable;
|
||||||
use cursive::traits::Identifiable;
|
use cursive::traits::Identifiable;
|
||||||
use cursive::utils::markup::StyledString;
|
use cursive::utils::markup::StyledString;
|
||||||
use cursive::views::{BoxedView, CircularFocus, Dialog, LinearLayout, Panel, StackView, TextView};
|
use cursive::views::{
|
||||||
|
CircularFocus, Dialog, LinearLayout, Panel, SelectView, StackView, TextView, ViewRef,
|
||||||
|
};
|
||||||
use cursive::Cursive;
|
use cursive::Cursive;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::{thread, time};
|
use std::{thread, time};
|
||||||
|
|
||||||
|
use super::constants::MAIN_MENU;
|
||||||
use crate::built_info;
|
use crate::built_info;
|
||||||
use crate::servers::Server;
|
use crate::servers::Server;
|
||||||
use crate::tui::constants::ROOT_STACK;
|
use crate::tui::constants::{ROOT_STACK, VIEW_BASIC_STATUS, VIEW_MINING, VIEW_PEER_SYNC};
|
||||||
use crate::tui::types::{TUIStatusListener, UIMessage};
|
use crate::tui::types::{TUIStatusListener, UIMessage};
|
||||||
use crate::tui::{logs, menu, mining, peers, status, version};
|
use crate::tui::{logs, menu, mining, peers, status, version};
|
||||||
use grin_util::logger::LogEntry;
|
use grin_util::logger::LogEntry;
|
||||||
|
@ -106,7 +109,7 @@ impl UI {
|
||||||
.child(Panel::new(TextView::new(title_string).full_width()))
|
.child(Panel::new(TextView::new(title_string).full_width()))
|
||||||
.child(
|
.child(
|
||||||
LinearLayout::new(Orientation::Horizontal)
|
LinearLayout::new(Orientation::Horizontal)
|
||||||
.child(Panel::new(BoxedView::new(main_menu)))
|
.child(Panel::new(main_menu))
|
||||||
.child(Panel::new(root_stack)),
|
.child(Panel::new(root_stack)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -144,12 +147,17 @@ impl UI {
|
||||||
|
|
||||||
// Process any pending UI messages
|
// Process any pending UI messages
|
||||||
while let Some(message) = self.ui_rx.try_iter().next() {
|
while let Some(message) = self.ui_rx.try_iter().next() {
|
||||||
|
let menu: ViewRef<SelectView<&str>> = self.cursive.find_name(MAIN_MENU).unwrap();
|
||||||
|
if let Some(selection) = menu.selection() {
|
||||||
match message {
|
match message {
|
||||||
UIMessage::UpdateStatus(update) => {
|
UIMessage::UpdateStatus(update) => match *selection {
|
||||||
status::TUIStatusView::update(&mut self.cursive, &update);
|
VIEW_BASIC_STATUS => {
|
||||||
mining::TUIMiningView::update(&mut self.cursive, &update);
|
status::TUIStatusView::update(&mut self.cursive, &update)
|
||||||
peers::TUIPeerView::update(&mut self.cursive, &update);
|
}
|
||||||
version::TUIVersionView::update(&mut self.cursive, &update);
|
VIEW_MINING => mining::TUIMiningView::update(&mut self.cursive, &update),
|
||||||
|
VIEW_PEER_SYNC => peers::TUIPeerView::update(&mut self.cursive, &update),
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,19 +18,16 @@ use cursive::direction::Orientation;
|
||||||
use cursive::traits::Identifiable;
|
use cursive::traits::Identifiable;
|
||||||
use cursive::view::View;
|
use cursive::view::View;
|
||||||
use cursive::views::{LinearLayout, ResizedView, TextView};
|
use cursive::views::{LinearLayout, ResizedView, TextView};
|
||||||
use cursive::Cursive;
|
|
||||||
|
|
||||||
use crate::tui::constants::VIEW_VERSION;
|
use crate::tui::constants::VIEW_VERSION;
|
||||||
use crate::tui::types::TUIStatusListener;
|
|
||||||
|
|
||||||
use crate::info_strings;
|
use crate::info_strings;
|
||||||
use crate::servers::ServerStats;
|
|
||||||
|
|
||||||
pub struct TUIVersionView;
|
pub struct TUIVersionView;
|
||||||
|
|
||||||
impl TUIStatusListener for TUIVersionView {
|
impl TUIVersionView {
|
||||||
/// Create basic status view
|
/// Create basic status view
|
||||||
fn create() -> Box<dyn View> {
|
pub fn create() -> Box<dyn View> {
|
||||||
let (basic_info, detailed_info) = info_strings();
|
let (basic_info, detailed_info) = info_strings();
|
||||||
let basic_status_view = ResizedView::with_full_screen(
|
let basic_status_view = ResizedView::with_full_screen(
|
||||||
LinearLayout::new(Orientation::Vertical)
|
LinearLayout::new(Orientation::Vertical)
|
||||||
|
@ -40,7 +37,4 @@ impl TUIStatusListener for TUIVersionView {
|
||||||
);
|
);
|
||||||
Box::new(basic_status_view.with_name(VIEW_VERSION))
|
Box::new(basic_status_view.with_name(VIEW_VERSION))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// update
|
|
||||||
fn update(_c: &mut Cursive, _stats: &ServerStats) {}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue