summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStephan Dilly <dilly.stephan@gmail.com>2021-05-24 02:15:52 +0200
committerStephan Dilly <dilly.stephan@gmail.com>2021-05-24 02:15:52 +0200
commita8bf31b0abdc1461189c42ae2c6e35e4bdc1ea98 (patch)
tree5468141d57f756d4cdfb15826f92615a32df429b /src
parentf73cfa01f1157929ef048e921df2458bec9f23fa (diff)
optimize all async job related clones away (#725)
Diffstat (limited to 'src')
-rw-r--r--src/components/revision_files.rs34
-rw-r--r--src/components/syntax_text.rs4
-rw-r--r--src/ui/syntax_text.rs41
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),
+ });
}
}
}