Skip to content

Commit c7b8551

Browse files
committed
Rework jobs view & error handling improvements
Job status is now shown in the top menu bar, with a new Jobs window that can be toggled. Build and diff errors are now handled more gracefully. Fixes #40
1 parent bb039a1 commit c7b8551

File tree

5 files changed

+233
-78
lines changed

5 files changed

+233
-78
lines changed

objdiff-gui/src/app.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use crate::{
4040
frame_history::FrameHistory,
4141
function_diff::function_diff_ui,
4242
graphics::{graphics_window, GraphicsConfig, GraphicsViewState},
43-
jobs::jobs_ui,
43+
jobs::{jobs_menu_ui, jobs_window},
4444
rlwinm::{rlwinm_decode_window, RlwinmDecodeViewState},
4545
symbol_diff::{symbol_diff_ui, DiffViewState, View},
4646
},
@@ -62,6 +62,7 @@ pub struct ViewState {
6262
pub show_arch_config: bool,
6363
pub show_debug: bool,
6464
pub show_graphics: bool,
65+
pub show_jobs: bool,
6566
}
6667

6768
/// The configuration for a single object file.
@@ -483,6 +484,7 @@ impl eframe::App for App {
483484
show_arch_config,
484485
show_debug,
485486
show_graphics,
487+
show_jobs,
486488
} = view_state;
487489

488490
frame_history.on_new_frame(ctx.input(|i| i.time), frame.info().cpu_usage);
@@ -598,6 +600,10 @@ impl eframe::App for App {
598600
state.queue_reload = true;
599601
}
600602
});
603+
ui.separator();
604+
if jobs_menu_ui(ui, jobs, appearance) {
605+
*show_jobs = !*show_jobs;
606+
}
601607
});
602608
});
603609

@@ -618,7 +624,6 @@ impl eframe::App for App {
618624
egui::SidePanel::left("side_panel").show(ctx, |ui| {
619625
egui::ScrollArea::both().show(ui, |ui| {
620626
config_ui(ui, state, show_project_config, config_state, appearance);
621-
jobs_ui(ui, jobs, appearance);
622627
});
623628
});
624629

@@ -634,6 +639,7 @@ impl eframe::App for App {
634639
arch_config_window(ctx, state, show_arch_config, appearance);
635640
debug_window(ctx, show_debug, frame_history, appearance);
636641
graphics_window(ctx, show_graphics, frame_history, graphics_state, appearance);
642+
jobs_window(ctx, show_jobs, jobs, appearance);
637643

638644
self.post_update(ctx);
639645
}

objdiff-gui/src/jobs/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,15 @@ impl JobQueue {
8585
/// Clears all finished jobs.
8686
pub fn clear_finished(&mut self) {
8787
self.jobs.retain(|job| {
88-
!(job.should_remove
89-
&& job.handle.is_none()
90-
&& job.context.status.read().unwrap().error.is_none())
88+
!(job.handle.is_none() && job.context.status.read().unwrap().error.is_none())
9189
});
9290
}
9391

92+
/// Clears all errored jobs.
93+
pub fn clear_errored(&mut self) {
94+
self.jobs.retain(|job| job.context.status.read().unwrap().error.is_none());
95+
}
96+
9497
/// Removes a job from the queue given its ID.
9598
pub fn remove(&mut self, id: usize) { self.jobs.retain(|job| job.id != id); }
9699
}
@@ -107,7 +110,6 @@ pub struct JobState {
107110
pub handle: Option<JoinHandle<JobResult>>,
108111
pub context: JobContext,
109112
pub cancel: Sender<()>,
110-
pub should_remove: bool,
111113
}
112114

113115
#[derive(Default)]
@@ -163,7 +165,7 @@ fn start_job(
163165
});
164166
let id = JOB_ID.fetch_add(1, Ordering::Relaxed);
165167
log::info!("Started job {}", id);
166-
JobState { id, kind, handle: Some(handle), context, cancel: tx, should_remove: true }
168+
JobState { id, kind, handle: Some(handle), context, cancel: tx }
167169
}
168170

169171
fn update_status(

objdiff-gui/src/jobs/objdiff.rs

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{
44
sync::mpsc::Receiver,
55
};
66

7-
use anyhow::{anyhow, Context, Error, Result};
7+
use anyhow::{anyhow, Error, Result};
88
use objdiff_core::{
99
diff::{diff_objs, DiffObjConfig, ObjDiff},
1010
obj::{read, ObjInfo},
@@ -189,81 +189,118 @@ fn run_build(
189189
None
190190
};
191191

192-
let mut total = 3;
192+
let mut total = 1;
193193
if config.build_target && target_path_rel.is_some() {
194194
total += 1;
195195
}
196196
if config.build_base && base_path_rel.is_some() {
197197
total += 1;
198198
}
199-
let first_status = match target_path_rel {
199+
if target_path_rel.is_some() {
200+
total += 1;
201+
}
202+
if base_path_rel.is_some() {
203+
total += 1;
204+
}
205+
206+
let mut step_idx = 0;
207+
let mut first_status = match target_path_rel {
200208
Some(target_path_rel) if config.build_target => {
201209
update_status(
202210
context,
203211
format!("Building target {}", target_path_rel.display()),
204-
0,
212+
step_idx,
205213
total,
206214
&cancel,
207215
)?;
216+
step_idx += 1;
208217
run_make(&config.build_config, target_path_rel)
209218
}
210219
_ => BuildStatus::default(),
211220
};
212221

213-
let second_status = match base_path_rel {
222+
let mut second_status = match base_path_rel {
214223
Some(base_path_rel) if config.build_base => {
215224
update_status(
216225
context,
217226
format!("Building base {}", base_path_rel.display()),
218-
0,
227+
step_idx,
219228
total,
220229
&cancel,
221230
)?;
231+
step_idx += 1;
222232
run_make(&config.build_config, base_path_rel)
223233
}
224234
_ => BuildStatus::default(),
225235
};
226236

227237
let time = OffsetDateTime::now_utc();
228238

229-
let first_obj =
230-
match &obj_config.target_path {
231-
Some(target_path) if first_status.success => {
232-
update_status(
233-
context,
234-
format!("Loading target {}", target_path_rel.unwrap().display()),
235-
2,
236-
total,
237-
&cancel,
238-
)?;
239-
Some(read::read(target_path, &config.diff_obj_config).with_context(|| {
240-
format!("Failed to read object '{}'", target_path.display())
241-
})?)
239+
let first_obj = match &obj_config.target_path {
240+
Some(target_path) if first_status.success => {
241+
update_status(
242+
context,
243+
format!("Loading target {}", target_path_rel.unwrap().display()),
244+
step_idx,
245+
total,
246+
&cancel,
247+
)?;
248+
step_idx += 1;
249+
match read::read(target_path, &config.diff_obj_config) {
250+
Ok(obj) => Some(obj),
251+
Err(e) => {
252+
first_status = BuildStatus {
253+
success: false,
254+
stdout: format!("Loading object '{}'", target_path.display()),
255+
stderr: format!("{:#}", e),
256+
..Default::default()
257+
};
258+
None
259+
}
242260
}
243-
_ => None,
244-
};
261+
}
262+
Some(_) => {
263+
step_idx += 1;
264+
None
265+
}
266+
_ => None,
267+
};
245268

246269
let second_obj = match &obj_config.base_path {
247270
Some(base_path) if second_status.success => {
248271
update_status(
249272
context,
250273
format!("Loading base {}", base_path_rel.unwrap().display()),
251-
3,
274+
step_idx,
252275
total,
253276
&cancel,
254277
)?;
255-
Some(
256-
read::read(base_path, &config.diff_obj_config)
257-
.with_context(|| format!("Failed to read object '{}'", base_path.display()))?,
258-
)
278+
step_idx += 1;
279+
match read::read(base_path, &config.diff_obj_config) {
280+
Ok(obj) => Some(obj),
281+
Err(e) => {
282+
second_status = BuildStatus {
283+
success: false,
284+
stdout: format!("Loading object '{}'", base_path.display()),
285+
stderr: format!("{:#}", e),
286+
..Default::default()
287+
};
288+
None
289+
}
290+
}
291+
}
292+
Some(_) => {
293+
step_idx += 1;
294+
None
259295
}
260296
_ => None,
261297
};
262298

263-
update_status(context, "Performing diff".to_string(), 4, total, &cancel)?;
299+
update_status(context, "Performing diff".to_string(), step_idx, total, &cancel)?;
300+
step_idx += 1;
264301
let result = diff_objs(&config.diff_obj_config, first_obj.as_ref(), second_obj.as_ref(), None)?;
265302

266-
update_status(context, "Complete".to_string(), total, total, &cancel)?;
303+
update_status(context, "Complete".to_string(), step_idx, total, &cancel)?;
267304
Ok(Box::new(ObjDiffResult {
268305
first_status,
269306
second_status,
@@ -274,7 +311,7 @@ fn run_build(
274311
}
275312

276313
pub fn start_build(ctx: &egui::Context, config: ObjDiffConfig) -> JobState {
277-
start_job(ctx, "Object diff", Job::ObjDiff, move |context, cancel| {
314+
start_job(ctx, "Build", Job::ObjDiff, move |context, cancel| {
278315
run_build(&context, cancel, config).map(|result| JobResult::ObjDiff(Some(result)))
279316
})
280317
}

0 commit comments

Comments
 (0)