mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-14 19:27:05 -04:00
#1070: a fresh import or opened project reads footage files again
The media layer keys decoded frames by path, and nothing dropped them when a new project (or a new import) named a file that another app had overwritten since, so a same-size overwrite showed the old pixels. Importing footage and replacing the project now make the media layer and the layer cache let go of the files involved. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
1 parent
470ea7a3af
commit
8e5605d0e6
3 files changed
+41
No files matched your search
@@ -445,6 +445,11 @@ fn add_footage(s: &mut Session, pending: PendingImport, probed: Vec<std::result:
|
||||
let mut asked: Vec<u64> = vec![];
|
||||
let made: Vec<ItemId> = comps.iter().map(|c| ItemId(*c)).collect();
|
||||
if !found.is_empty() {
|
||||
// The file may have been overwritten since an earlier import or project decoded it (the
|
||||
// media layer keys frames by path): a fresh import reads it again (#1070).
|
||||
for f in &found {
|
||||
s.forget_decoded(&f.footage);
|
||||
}
|
||||
s.edit("Import", None, |proj, st| {
|
||||
let mut selection = made;
|
||||
for f in found {
|
||||
|
||||
@@ -1016,6 +1016,15 @@ impl Session {
|
||||
Ok((img.width, img.height, img.to_rgba8()))
|
||||
}
|
||||
|
||||
/// Make the media layer and the layer cache let go of what they decoded from `footage`'s
|
||||
/// files (it keys frames by path, so an overwritten file would keep showing its old pixels).
|
||||
pub(crate) fn forget_decoded(&self, footage: &effectcraft_project::Footage) {
|
||||
for p in std::iter::once(&footage.path).chain(&footage.sequence) {
|
||||
self.footage.forget(p);
|
||||
}
|
||||
self.layer_cache.clear();
|
||||
}
|
||||
|
||||
/// Replace the whole project (open/new), resetting history and state.
|
||||
pub fn replace_project(&mut self, mut p: Project, path: Option<String>) {
|
||||
if self.stop_render()
|
||||
@@ -1042,6 +1051,14 @@ impl Session {
|
||||
self.script_ui.project_epoch = self.script_ui.project_epoch.wrapping_add(1);
|
||||
p.fix_next_id();
|
||||
upgrade_effects(&mut p);
|
||||
// The media layer keys decoded frames by path: files of the new project may have changed
|
||||
// since an earlier project decoded them (#1070).
|
||||
for it in p.items.values() {
|
||||
if let effectcraft_project::ItemKind::Footage(f) = &it.kind {
|
||||
self.forget_decoded(f);
|
||||
}
|
||||
}
|
||||
self.layer_cache.clear();
|
||||
self.project = Arc::new(p);
|
||||
self.history = History::default();
|
||||
self.state = EditorState { snapping: true, view_layout: 1, ..Default::default() };
|
||||
|
||||
@@ -194,3 +194,22 @@ fn image_sequences_reload_by_themselves_only_with_all_footage() {
|
||||
png(&b, 128);
|
||||
assert_eq!(s.execute_checked("footage.reloadChanged", json!({})).unwrap()["files"], json!(1));
|
||||
}
|
||||
|
||||
/// #1070: a file decoded in one project and overwritten with one of the same size is read again
|
||||
/// when a new project imports it (neither File ▸ Reload Footage nor the change watcher knows it).
|
||||
#[test]
|
||||
fn a_new_project_importing_an_overwritten_file_shows_the_new_pixels() {
|
||||
let path = tmp("overwritten.psd");
|
||||
std::fs::write(&path, flat(RED, false)).unwrap();
|
||||
let (mut s, _item, cid) = flat_in_comp(&path);
|
||||
assert!(near(pixel(&s, cid, 32, 24), RED));
|
||||
// Another app overwrites the file with the same number of bytes.
|
||||
save(&path, &flat(BLUE, false));
|
||||
s.execute_checked("file.newProject", json!({})).unwrap();
|
||||
let r = s.execute_checked("file.import", json!({"paths": [path.clone()]})).unwrap();
|
||||
let item = r["items"][0].as_u64().unwrap();
|
||||
s.execute_checked("comp.new", json!({"name": "C", "width": 64, "height": 48, "frameRate": 30, "duration": 1})).unwrap();
|
||||
s.execute_checked("layer.addItem", json!({"item": item})).unwrap();
|
||||
let cid = s.active_comp_id().unwrap();
|
||||
assert!(near(pixel(&s, cid, 32, 24), BLUE), "stale pixels from the earlier project: {:?}", pixel(&s, cid, 32, 24));
|
||||
}
|
||||
Reference in new issue
Block a user