Skip to content

Commit a8bf31b

Browse files
author
Stephan Dilly
committed
optimize all async job related clones away (#725)
1 parent f73cfa0 commit a8bf31b

File tree

4 files changed

+52
-35
lines changed

4 files changed

+52
-35
lines changed

async_utils/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ impl<J: 'static + AsyncJob, T: Copy + Send + 'static>
6666
false
6767
}
6868

69-
/// return clone of last result
70-
pub fn get_last(&self) -> Option<J> {
71-
if let Ok(last) = self.last.lock() {
72-
last.clone()
69+
///
70+
pub fn take_last(&self) -> Option<J> {
71+
if let Ok(mut last) = self.last.lock() {
72+
last.take()
7373
} else {
7474
None
7575
}

src/components/revision_files.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,7 @@ impl RevisionFilesComponent {
173173
}
174174
}
175175

176-
fn draw_tree<B: Backend>(
177-
&self,
178-
f: &mut Frame<B>,
179-
area: Rect,
180-
) -> Result<()> {
176+
fn draw_tree<B: Backend>(&self, f: &mut Frame<B>, area: Rect) {
181177
let tree_height = usize::from(area.height.saturating_sub(2));
182178

183179
let selection = self.tree.visual_selection();
@@ -203,18 +199,6 @@ impl RevisionFilesComponent {
203199
Self::tree_item_to_span(item, &self.theme, selected)
204200
});
205201

206-
f.render_widget(Clear, area);
207-
f.render_widget(
208-
Block::default()
209-
.borders(Borders::TOP)
210-
.title(Span::styled(
211-
format!(" {}", self.title),
212-
self.theme.title(true),
213-
))
214-
.border_style(self.theme.block(true)),
215-
area,
216-
);
217-
218202
let is_tree_focused = matches!(self.focus, Focus::Tree);
219203

220204
ui::draw_list_block(
@@ -235,8 +219,6 @@ impl RevisionFilesComponent {
235219
self.scroll_top.get(),
236220
);
237221
}
238-
239-
Ok(())
240222
}
241223
}
242224

@@ -259,7 +241,19 @@ impl DrawableComponent for RevisionFilesComponent {
259241
)
260242
.split(area);
261243

262-
self.draw_tree(f, chunks[0])?;
244+
f.render_widget(Clear, area);
245+
f.render_widget(
246+
Block::default()
247+
.borders(Borders::TOP)
248+
.title(Span::styled(
249+
format!(" {}", self.title),
250+
self.theme.title(true),
251+
))
252+
.border_style(self.theme.block(true)),
253+
area,
254+
);
255+
256+
self.draw_tree(f, chunks[0]);
263257

264258
self.current_file.draw(f, chunks[1])?;
265259
}

src/components/syntax_text.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,11 @@ impl SyntaxTextComponent {
6161
///
6262
pub fn update(&mut self, ev: AsyncNotification) {
6363
if ev == AsyncNotification::SyntaxHighlighting {
64-
if let Some(job) = self.async_highlighting.get_last() {
64+
if let Some(job) = self.async_highlighting.take_last() {
6565
if let Some((path, content)) =
6666
self.current_file.as_mut()
6767
{
68-
if let Some(syntax) = (*job.text).clone() {
68+
if let Some(syntax) = job.result() {
6969
if syntax.path() == Path::new(path) {
7070
*content = Either::Left(syntax);
7171
}

src/ui/syntax_text.rs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::{
55
ffi::OsStr,
66
ops::Range,
77
path::{Path, PathBuf},
8-
sync::Arc,
8+
sync::{Arc, Mutex},
99
};
1010
use syntect::{
1111
highlighting::{
@@ -145,27 +145,50 @@ fn syntact_style_to_tui(style: &Style) -> tui::style::Style {
145145
res
146146
}
147147

148+
enum JobState {
149+
Request((String, String)),
150+
Response(SyntaxText),
151+
}
152+
148153
#[derive(Clone, Default)]
149154
pub struct AsyncSyntaxJob {
150-
//TODO: can we merge input and text into a single enum to represent the state transition?
151-
pub input: Option<(String, String)>,
152-
pub text: Arc<Option<SyntaxText>>,
155+
state: Arc<Mutex<Option<JobState>>>,
153156
}
154157

155158
impl AsyncSyntaxJob {
156159
pub fn new(content: String, path: String) -> Self {
157160
Self {
158-
input: Some((content, path)),
159-
text: Arc::new(None),
161+
state: Arc::new(Mutex::new(Some(JobState::Request((
162+
content, path,
163+
))))),
164+
}
165+
}
166+
167+
pub fn result(&self) -> Option<SyntaxText> {
168+
if let Ok(mut state) = self.state.lock() {
169+
if let Some(state) = state.take() {
170+
return match state {
171+
JobState::Request(_) => None,
172+
JobState::Response(text) => Some(text),
173+
};
174+
}
160175
}
176+
177+
None
161178
}
162179
}
163180

164181
impl AsyncJob for AsyncSyntaxJob {
165182
fn run(&mut self) {
166-
if let Some((text, path)) = self.input.take() {
167-
let syntax = SyntaxText::new(text, Path::new(&path));
168-
self.text = Arc::new(Some(syntax));
183+
if let Ok(mut state) = self.state.lock() {
184+
*state = state.take().map(|state| match state {
185+
JobState::Request((content, path)) => {
186+
let syntax =
187+
SyntaxText::new(content, Path::new(&path));
188+
JobState::Response(syntax)
189+
}
190+
JobState::Response(res) => JobState::Response(res),
191+
});
169192
}
170193
}
171194
}

0 commit comments

Comments
 (0)