diff options
author | Stephan Dilly <dilly.stephan@gmail.com> | 2021-05-24 02:15:52 +0200 |
---|---|---|
committer | Stephan Dilly <dilly.stephan@gmail.com> | 2021-05-24 02:15:52 +0200 |
commit | a8bf31b0abdc1461189c42ae2c6e35e4bdc1ea98 (patch) | |
tree | 5468141d57f756d4cdfb15826f92615a32df429b /src | |
parent | f73cfa01f1157929ef048e921df2458bec9f23fa (diff) |
optimize all async job related clones away (#725)
Diffstat (limited to 'src')
-rw-r--r-- | src/components/revision_files.rs | 34 | ||||
-rw-r--r-- | src/components/syntax_text.rs | 4 | ||||
-rw-r--r-- | src/ui/syntax_text.rs | 41 |
3 files changed, 48 insertions, 31 deletions
diff --git a/src/components/revision_files.rs b/src/components/revision_files.rs index 9d3fe4a9..6b1acac3 100644 --- a/src/components/revision_files.rs +++ b/src/components/revision_files.rs @@ -173,11 +173,7 @@ impl RevisionFilesComponent { } } - fn draw_tree<B: Backend>( - &self, - f: &mut Frame<B>, - area: Rect, - ) -> Result<()> { + fn draw_tree<B: Backend>(&self, f: &mut Frame<B>, area: Rect) { let tree_height = usize::from(area.height.saturating_sub(2)); let selection = self.tree.visual_selection(); @@ -203,18 +199,6 @@ impl RevisionFilesComponent { Self::tree_item_to_span(item, &self.theme, selected) }); - f.render_widget(Clear, area); - f.render_widget( - Block::default() - .borders(Borders::TOP) - .title(Span::styled( - format!(" {}", self.title), - self.theme.title(true), - )) - .border_style(self.theme.block(true)), - area, - ); - let is_tree_focused = matches!(self.focus, Focus::Tree); ui::draw_list_block( @@ -235,8 +219,6 @@ impl RevisionFilesComponent { self.scroll_top.get(), ); } - - Ok(()) } } @@ -259,7 +241,19 @@ impl DrawableComponent for RevisionFilesComponent { ) .split(area); - self.draw_tree(f, chunks[0])?; + f.render_widget(Clear, area); + f.render_widget( + Block::default() + .borders(Borders::TOP) + .title(Span::styled( + format!(" {}", self.title), + self.theme.title(true), + )) + .border_style(self.theme.block(true)), + area, + ); + + self.draw_tree(f, chunks[0]); self.current_file.draw(f, chunks[1])?; } diff --git a/src/components/syntax_text.rs b/src/components/syntax_text.rs index 4b02153f..9968d55c 100644 --- a/src/components/syntax_text.rs +++ b/src/components/syntax_text.rs @@ -61,11 +61,11 @@ impl SyntaxTextComponent { /// pub fn update(&mut self, ev: AsyncNotification) { if ev == AsyncNotification::SyntaxHighlighting { - if let Some(job) = self.async_highlighting.get_last() { + if let Some(job) = self.async_highlighting.take_last() { if let Some((path, content)) = self.current_file.as_mut() { - if let Some(syntax) = (*job.text).clone() { + if let Some(syntax) = job.result() { if syntax.path() == Path::new(path) { *content = Either::Left(syntax); } diff --git a/src/ui/syntax_text.rs b/src/ui/syntax_text.rs index 44a0efbf..dfdb3b93 100644 --- a/src/ui/syntax_text.rs +++ b/src/ui/syntax_text.rs @@ -5,7 +5,7 @@ use std::{ ffi::OsStr, ops::Range, path::{Path, PathBuf}, - sync::Arc, + sync::{Arc, Mutex}, }; use syntect::{ highlighting::{ @@ -145,27 +145,50 @@ fn syntact_style_to_tui(style: &Style) -> tui::style::Style { res } +enum JobState { + Request((String, String)), + Response(SyntaxText), +} + #[derive(Clone, Default)] pub struct AsyncSyntaxJob { - //TODO: can we merge input and text into a single enum to represent the state transition? - pub input: Option<(String, String)>, - pub text: Arc<Option<SyntaxText>>, + state: Arc<Mutex<Option<JobState>>>, } impl AsyncSyntaxJob { pub fn new(content: String, path: String) -> Self { Self { - input: Some((content, path)), - text: Arc::new(None), + state: Arc::new(Mutex::new(Some(JobState::Request(( + content, path, + ))))), + } + } + + pub fn result(&self) -> Option<SyntaxText> { + if let Ok(mut state) = self.state.lock() { + if let Some(state) = state.take() { + return match state { + JobState::Request(_) => None, + JobState::Response(text) => Some(text), + }; + } } + + None } } impl AsyncJob for AsyncSyntaxJob { fn run(&mut self) { - if let Some((text, path)) = self.input.take() { - let syntax = SyntaxText::new(text, Path::new(&path)); - self.text = Arc::new(Some(syntax)); + if let Ok(mut state) = self.state.lock() { + *state = state.take().map(|state| match state { + JobState::Request((content, path)) => { + let syntax = + SyntaxText::new(content, Path::new(&path)); + JobState::Response(syntax) + } + JobState::Response(res) => JobState::Response(res), + }); } } } |