Support sections now
This commit is contained in:
parent
12ae4e4328
commit
9095be7026
|
@ -110,90 +110,106 @@ pub struct ConsoleUI {
|
||||||
terminal: Terminal,
|
terminal: Terminal,
|
||||||
console_size: Rect,
|
console_size: Rect,
|
||||||
menu_selection: MenuSelection,
|
menu_selection: MenuSelection,
|
||||||
content_selection: ListSelection,
|
section_selection: ListSelection,
|
||||||
|
first_section_id: usize,
|
||||||
|
second_section_id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConsoleUI {
|
impl ConsoleUI {
|
||||||
pub fn new(rx: EventReceiver, terminal: Terminal) -> ConsoleUI {
|
pub fn new(rx: EventReceiver, terminal: Terminal) -> ConsoleUI {
|
||||||
ConsoleUI{data: ConsoleUIData::default(), rx, terminal, console_size: Rect::default(), menu_selection: MenuSelection::Stats, content_selection: ListSelection::default()}
|
ConsoleUI{data: ConsoleUIData::default(), rx, terminal, console_size: Rect::default(), menu_selection: MenuSelection::Stats, section_selection: ListSelection::default(), first_section_id: 0, second_section_id: 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_data(&mut self, memory_map: &MemoryMap) -> Result<(), Error> {
|
pub fn update_data(&mut self, memory_map: &MemoryMap) -> Result<(), Error> {
|
||||||
self.data = ConsoleUIData::from(memory_map)?;
|
self.data = ConsoleUIData::from(memory_map)?;
|
||||||
|
|
||||||
if self.data.list.len() > 0 {
|
if self.data.section_info.len() > 0 {
|
||||||
if !self.content_selection.is_active() {
|
if !self.section_selection.is_active() {
|
||||||
self.content_selection.activate();
|
self.section_selection.activate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
self.content_selection.deactivate();
|
self.section_selection.deactivate();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self) -> Result<UIState, Error> {
|
pub fn update(&mut self) -> Result<UIState, Error> {
|
||||||
match self.rx.recv()? {
|
let input_result = {
|
||||||
Event::Input(event) => {
|
match self.rx.recv()? {
|
||||||
match event.code {
|
Event::Input(event) => {
|
||||||
KeyCode::Char('q') => Ok(UIState::Terminated),
|
match event.code {
|
||||||
KeyCode::Char('s') => {
|
KeyCode::Char('q') => Ok(UIState::Terminated),
|
||||||
self.menu_selection = MenuSelection::Stats;
|
KeyCode::Char('s') => {
|
||||||
Ok(UIState::Render)
|
self.menu_selection = MenuSelection::Stats;
|
||||||
},
|
|
||||||
KeyCode::Left => {
|
|
||||||
self.menu_selection = self.menu_selection.prev();
|
|
||||||
Ok(UIState::Render)
|
|
||||||
},
|
|
||||||
KeyCode::Right => {
|
|
||||||
self.menu_selection = self.menu_selection.next();
|
|
||||||
Ok(UIState::Render)
|
|
||||||
},
|
|
||||||
KeyCode::Down => {
|
|
||||||
if matches!(self.menu_selection, MenuSelection::Stats) {
|
|
||||||
self.content_selection.increment(self.data.list.len());
|
|
||||||
Ok(UIState::Render)
|
Ok(UIState::Render)
|
||||||
}
|
},
|
||||||
|
KeyCode::Left => {
|
||||||
else {
|
self.menu_selection = self.menu_selection.prev();
|
||||||
Ok(UIState::Alive)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
KeyCode::Up => {
|
|
||||||
if matches!(self.menu_selection, MenuSelection::Stats) {
|
|
||||||
self.content_selection.decrement(self.data.list.len());
|
|
||||||
Ok(UIState::Render)
|
Ok(UIState::Render)
|
||||||
}
|
},
|
||||||
|
KeyCode::Right => {
|
||||||
|
self.menu_selection = self.menu_selection.next();
|
||||||
|
Ok(UIState::Render)
|
||||||
|
},
|
||||||
|
KeyCode::Down => {
|
||||||
|
if matches!(self.menu_selection, MenuSelection::Stats) {
|
||||||
|
self.section_selection.increment(self.data.section_info.len());
|
||||||
|
Ok(UIState::Render)
|
||||||
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
Ok(UIState::Alive)
|
Ok(UIState::Alive)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
KeyCode::Enter => {
|
KeyCode::Up => {
|
||||||
if matches!(self.menu_selection, MenuSelection::Quit) {
|
if matches!(self.menu_selection, MenuSelection::Stats) {
|
||||||
Ok(UIState::Terminated)
|
self.section_selection.decrement(self.data.section_info.len());
|
||||||
}
|
Ok(UIState::Render)
|
||||||
else {
|
}
|
||||||
Ok(UIState::Alive)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => Ok(UIState::Alive)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Event::Tick => {
|
|
||||||
let terminal_size = self.terminal.size().expect("Getting size of terminal");
|
|
||||||
if terminal_size != self.console_size {
|
|
||||||
self.console_size = terminal_size;
|
|
||||||
Ok(UIState::Render)
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
else {
|
||||||
Ok(UIState::Alive)
|
Ok(UIState::Alive)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Event::ForceRender => Ok(UIState::Render)
|
KeyCode::Enter => {
|
||||||
}
|
if matches!(self.menu_selection, MenuSelection::Quit) {
|
||||||
|
Ok(UIState::Terminated)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Ok(UIState::Alive)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => Ok(UIState::Alive)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Event::Tick => {
|
||||||
|
let terminal_size = self.terminal.size().expect("Getting size of terminal");
|
||||||
|
if terminal_size != self.console_size {
|
||||||
|
self.console_size = terminal_size;
|
||||||
|
Ok(UIState::Render)
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
Ok(UIState::Alive)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Event::ForceRender => Ok(UIState::Render)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.first_section_id = {
|
||||||
|
if let Some(selection) = self.section_selection.selection {
|
||||||
|
selection
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
input_result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self) -> Result<(), Error> {
|
pub fn render(&mut self) -> Result<(), Error> {
|
||||||
|
@ -229,7 +245,8 @@ impl ConsoleUI {
|
||||||
frame.render_widget(menu_bar, main_layout[0]);
|
frame.render_widget(menu_bar, main_layout[0]);
|
||||||
match self.menu_selection {
|
match self.menu_selection {
|
||||||
MenuSelection::Stats => {
|
MenuSelection::Stats => {
|
||||||
Self::render_stats(frame, main_layout[1], &self.content_selection, &mut self.data);
|
// ToDo: v This is the same and we always have elements now
|
||||||
|
Self::render_stats(frame, main_layout[1], (&self.section_selection, self.first_section_id), &mut self.data);
|
||||||
},
|
},
|
||||||
MenuSelection::Quit => {
|
MenuSelection::Quit => {
|
||||||
frame.render_widget(Self::create_exit_message(), main_layout[1]);
|
frame.render_widget(Self::create_exit_message(), main_layout[1]);
|
||||||
|
@ -247,7 +264,7 @@ impl ConsoleUI {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_stats(frame: &mut ConsoleFrame, layout: Rect, content_selection: &ListSelection, data: &mut ConsoleUIData) {
|
fn render_stats(frame: &mut ConsoleFrame, layout: Rect, content_selection: (&ListSelection, usize), data: &mut ConsoleUIData) {
|
||||||
let layout = Layout::default().direction(Direction::Vertical).constraints([
|
let layout = Layout::default().direction(Direction::Vertical).constraints([
|
||||||
Constraint::Length(3),
|
Constraint::Length(3),
|
||||||
Constraint::Max(3),
|
Constraint::Max(3),
|
||||||
|
@ -256,8 +273,8 @@ impl ConsoleUI {
|
||||||
let content_list = List::new({
|
let content_list = List::new({
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
|
|
||||||
for item in &data.list {
|
for section in &data.section_info {
|
||||||
vec.push(ListItem::new(item.as_str()))
|
vec.push(ListItem::new(section.name.clone()))
|
||||||
}
|
}
|
||||||
vec
|
vec
|
||||||
}).style(Style::default().fg(Color::White))
|
}).style(Style::default().fg(Color::White))
|
||||||
|
@ -267,29 +284,18 @@ impl ConsoleUI {
|
||||||
.border_type(BorderType::Plain)
|
.border_type(BorderType::Plain)
|
||||||
)
|
)
|
||||||
.highlight_style(Style::default().bg(Color::Cyan));
|
.highlight_style(Style::default().bg(Color::Cyan));
|
||||||
let first_mem_gauge = Self::create_mem_gauge("Overall memory usage", data.highest_adr, Color::Cyan);
|
|
||||||
let second_mem_gauge = Self::create_mem_gauge_from(&data.overall_info, Color::Red);
|
let first_mem_gauge = Self::create_mem_gauge_from(&data.section_info[content_selection.1], Color::Cyan);
|
||||||
|
let second_mem_gauge = Self::create_mem_gauge_from(&data.section_info[0], Color::Red);
|
||||||
let mut list_state = ListState::default();
|
let mut list_state = ListState::default();
|
||||||
|
|
||||||
list_state.select(content_selection.selection);
|
list_state.select(content_selection.0.selection);
|
||||||
|
|
||||||
frame.render_stateful_widget(content_list, layout[0], &mut list_state);
|
frame.render_stateful_widget(content_list, layout[0], &mut list_state);
|
||||||
frame.render_widget(first_mem_gauge, layout[1]);
|
frame.render_widget(first_mem_gauge, layout[1]);
|
||||||
frame.render_widget(second_mem_gauge, layout[2]);
|
frame.render_widget(second_mem_gauge, layout[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_mem_gauge<'a>(name: &str, adr: u64, color: Color) -> Gauge<'a> {
|
|
||||||
const RAM_TOP:u64 = ConsoleUIData::HIGHEST_RAM_ADDRESS & !ConsoleUIData::RAM_BASE_ADDRESS;
|
|
||||||
|
|
||||||
let adr_masked = adr & !ConsoleUIData::RAM_BASE_ADDRESS;
|
|
||||||
let adr_ratio = (adr_masked as f64)/RAM_TOP as f64;
|
|
||||||
|
|
||||||
Gauge::default().block(Block::default().borders(Borders::ALL)
|
|
||||||
.title(format!("{} [0x{:x}/0x{:x}]", name, adr, ConsoleUIData::HIGHEST_RAM_ADDRESS)))
|
|
||||||
.gauge_style(Style::default().fg(color).bg(Color::Black).add_modifier(Modifier::BOLD))
|
|
||||||
.ratio(adr_ratio).label(format!("{}%", adr_ratio*100.0f64))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_mem_gauge_from<'a>(section_info: &SectionInfo, color: Color) -> Gauge<'a> {
|
fn create_mem_gauge_from<'a>(section_info: &SectionInfo, color: Color) -> Gauge<'a> {
|
||||||
let adr_ratio = section_info.get_size_ratio();
|
let adr_ratio = section_info.get_size_ratio();
|
||||||
Gauge::default().block(Block::default().borders(Borders::ALL)
|
Gauge::default().block(Block::default().borders(Borders::ALL)
|
||||||
|
@ -313,15 +319,12 @@ impl ConsoleUI {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct ConsoleUIData {
|
struct ConsoleUIData {
|
||||||
highest_adr: u64,
|
section_info: Vec<SectionInfo>
|
||||||
overall_info: SectionInfo,
|
|
||||||
list: Vec<String>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConsoleUIData {
|
impl ConsoleUIData {
|
||||||
pub const RAM_BASE_ADDRESS:u64 = 0x80000000;
|
pub const RAM_BASE_ADDRESS:u64 = 0x80000000;
|
||||||
pub const RAM_SIZE:usize = 2*1024*1024;
|
pub const RAM_SIZE:usize = 2*1024*1024;
|
||||||
pub const HIGHEST_RAM_ADDRESS:u64 = Self::RAM_BASE_ADDRESS + Self::RAM_SIZE as u64;
|
|
||||||
|
|
||||||
pub fn from(memory_map: &MemoryMap) -> Result<Self, Error> {
|
pub fn from(memory_map: &MemoryMap) -> Result<Self, Error> {
|
||||||
fn get_last_section_end_adr(memory_map: &MemoryMap) -> u64 {
|
fn get_last_section_end_adr(memory_map: &MemoryMap) -> u64 {
|
||||||
|
@ -331,21 +334,25 @@ impl ConsoleUIData {
|
||||||
0u64
|
0u64
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut new_self = ConsoleUIData::default();
|
let mut new_self = ConsoleUIData::default();
|
||||||
|
let highest_adr = get_last_section_end_adr(memory_map);
|
||||||
|
let program_size = (highest_adr - Self::RAM_BASE_ADDRESS) as usize;
|
||||||
|
|
||||||
new_self.highest_adr = get_last_section_end_adr(memory_map);
|
new_self.section_info.push(SectionInfo{
|
||||||
new_self.list = vec![String::from("<overall usage>")];
|
name: String::from("<overall usage>"),
|
||||||
for section in &memory_map.sections {
|
|
||||||
new_self.list.push(section.name.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Testing new data type
|
|
||||||
new_self.overall_info = SectionInfo{
|
|
||||||
name: "Schwimmflügel".to_string(),
|
|
||||||
start_adr: Self::RAM_BASE_ADDRESS,
|
start_adr: Self::RAM_BASE_ADDRESS,
|
||||||
size: (new_self.highest_adr - Self::RAM_BASE_ADDRESS) as usize,
|
size: program_size,
|
||||||
max_size: Self::RAM_SIZE
|
max_size: Self::RAM_SIZE
|
||||||
};
|
});
|
||||||
|
|
||||||
|
for section in &memory_map.sections {
|
||||||
|
new_self.section_info.push(SectionInfo{
|
||||||
|
name: section.name.clone(),
|
||||||
|
start_adr: section.adr,
|
||||||
|
size: section.size,
|
||||||
|
max_size: program_size
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Ok(new_self)
|
Ok(new_self)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue