mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-26 19:17:02 -06:00
Issue #345: AI Denoise in the activity stack
While a photo's AI Denoise picture is being made or waits its turn, the stack shows "AI Denoise" with the running photo's tiles as a percentage and its file name (no cross: what is made follows the Denoise amounts and Settings). The row goes when the queue is idle. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3f3c204987
commit
753ca97a4d
@@ -614,6 +614,7 @@ fn status(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
/// `denoise.pump {pace?}`: cheap to call every frame. Takes in what the background job has finished and keeps one going.
|
||||
fn pump(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
s.denoise_pump(Pace::parse(p.get("pace").and_then(Value::as_str)));
|
||||
s.denoise_track();
|
||||
Ok(json!({
|
||||
"active": s.denoise.active.is_some(),
|
||||
"running": s.denoise_running_json(),
|
||||
|
||||
@@ -890,6 +890,8 @@ pub(crate) struct State {
|
||||
pub generation: u64,
|
||||
/// Photos made since the session started.
|
||||
made: u64,
|
||||
/// AI Denoise's row in the activity stack, while a photo is being made or waits its turn.
|
||||
task: Option<crate::activity::TaskGuard>,
|
||||
}
|
||||
|
||||
impl Default for State {
|
||||
@@ -909,6 +911,7 @@ impl Default for State {
|
||||
failed: HashMap::new(),
|
||||
generation: 0,
|
||||
made: 0,
|
||||
task: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1354,6 +1357,31 @@ impl Session {
|
||||
self.denoise.running.is_some() || (!self.denoise.queue.is_empty() && self.denoise.active.is_some())
|
||||
}
|
||||
|
||||
/// Keep AI Denoise's row in the activity stack up to date (each `denoise.pump`): there while a photo is being made or
|
||||
/// waits its turn, with the running photo's tiles and its file name; gone when the queue is idle. It has no ✕: what is
|
||||
/// made follows the photos' Denoise amounts and Settings ▸ AI Denoise.
|
||||
pub(crate) fn denoise_track(&mut self) {
|
||||
if !self.denoise_busy() {
|
||||
self.denoise.task = None;
|
||||
return;
|
||||
}
|
||||
let task = self.denoise.task.get_or_insert_with(|| {
|
||||
let t = self.activity.start("denoise", "AI Denoise", crate::activity::Cancel::No);
|
||||
t.set_unit(crate::activity::Unit::Percent);
|
||||
t
|
||||
});
|
||||
match &self.denoise.running {
|
||||
Some(r) => {
|
||||
task.progress(r.progress.done.load(Ordering::Relaxed) as u64, r.progress.total.load(Ordering::Relaxed) as u64);
|
||||
task.detail(self.catalog.photo(r.photo).map_or("", |p| p.file_name.as_str()));
|
||||
}
|
||||
None => {
|
||||
task.progress(0, 0);
|
||||
task.detail("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Seconds the running job has been going, and its progress.
|
||||
pub(crate) fn denoise_running_json(&self) -> Value {
|
||||
match &self.denoise.running {
|
||||
|
||||
@@ -757,3 +757,35 @@ fn the_denoise_switch_validates_arguments_and_accepts_explicit_targets_without_s
|
||||
drop(x.s);
|
||||
let _ = std::fs::remove_dir_all(x.dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn denoise_row_while_queue_is_busy() {
|
||||
let mut x = setup("activity", true);
|
||||
let rows = |s: &Session| s.activity.list().into_iter().filter(|t| t.kind == "denoise").collect::<Vec<_>>();
|
||||
let r = x.s.execute("denoise.pump", &json!({"pace": "full"})).unwrap();
|
||||
assert!(rows(&x.s).is_empty(), "nothing to make, no row: {r}");
|
||||
set_amount(&mut x.s, 100.0);
|
||||
let mut shown = false;
|
||||
for _ in 0..600 {
|
||||
let r = x.s.execute("denoise.pump", &json!({"pace": "full"})).unwrap();
|
||||
let rows = rows(&x.s);
|
||||
// (what the pump left running or queued is what the row reflects until the next pump)
|
||||
if x.s.denoise_busy() {
|
||||
assert_eq!(rows.len(), 1, "{r}");
|
||||
assert_eq!((rows[0].label.as_str(), rows[0].cancellable, rows[0].unit), ("AI Denoise", false, crate::activity::Unit::Percent), "{r}");
|
||||
if !r["running"].is_null() {
|
||||
assert_eq!(rows[0].detail, "ramp.dng", "{r}");
|
||||
}
|
||||
shown = true;
|
||||
} else {
|
||||
assert!(rows.is_empty(), "{r}");
|
||||
}
|
||||
if r["ready"].as_u64() >= Some(1) {
|
||||
break;
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
}
|
||||
assert!(shown, "the photo never showed a row");
|
||||
assert!(rows(&x.s).is_empty(), "the row goes once the photo is made");
|
||||
let _ = std::fs::remove_dir_all(&x.dir);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user