mirror of
https://github.com/13hannes11/focus_annotator.git
synced 2024-09-03 23:21:01 +02:00
saving to light tmp file to speed up annotation
This commit is contained in:
@@ -8,4 +8,5 @@ pub const NONE_STRING_OPTION: Option<String> = None;
|
||||
pub const TOGGLE_NEIGHBOURS_TEXT_TOGGLED: &str = "Hide Neighbours";
|
||||
pub const TOGGLE_NEIGHBOURS_TEXT: &str = "Show Neighbours";
|
||||
|
||||
pub const SCALE_STEP: f64 = 1.0;
|
||||
pub const SCALE_STEP: f64 = 1.0;
|
||||
pub const ANNOTATION_CACHE_FILE_ENDING: &str = "tmp_annotation";
|
||||
|
||||
@@ -132,6 +132,11 @@ fn build_ui(app: &Application) {
|
||||
image_ui.window.add_action(&skip_focus);
|
||||
image_ui.window.add_action(&back_focus);
|
||||
|
||||
let _sender = sender.clone();
|
||||
app.connect_shutdown(move |_| {
|
||||
_sender.send(Message::Quit).unwrap();
|
||||
});
|
||||
|
||||
image_ui.show();
|
||||
receiver.attach(None, move |msg| {
|
||||
eprintln!("Received message: {:?}", msg);
|
||||
|
||||
134
src/state/mod.rs
134
src/state/mod.rs
@@ -1,13 +1,13 @@
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{collections::HashMap, time::Instant};
|
||||
|
||||
use gtk::{gio::File, prelude::FileExt};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::constants::NONE_STRING_OPTION;
|
||||
use crate::constants::{ANNOTATION_CACHE_FILE_ENDING, NONE_STRING_OPTION};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Message {
|
||||
@@ -17,6 +17,7 @@ pub enum Message {
|
||||
PreviousImage,
|
||||
UI(UIMessage),
|
||||
OpenFile(File),
|
||||
Quit,
|
||||
}
|
||||
|
||||
// Messages that do not impact state
|
||||
@@ -36,8 +37,23 @@ pub struct State {
|
||||
stack_index: Option<usize>,
|
||||
focus_image_index: Option<usize>,
|
||||
file_name: Option<String>,
|
||||
annotation_cache: Vec<LightAnnotation>,
|
||||
pub root_path: Option<String>,
|
||||
}
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LightAnnotation {
|
||||
stack_index: usize,
|
||||
focus_image_index: usize,
|
||||
}
|
||||
|
||||
impl LightAnnotation {
|
||||
pub fn new(stack_index: usize, focus_image_index: usize) -> Self {
|
||||
LightAnnotation {
|
||||
stack_index,
|
||||
focus_image_index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl State {
|
||||
pub fn new() -> Self {
|
||||
@@ -46,6 +62,7 @@ impl State {
|
||||
stack_index: None,
|
||||
focus_image_index: None,
|
||||
file_name: None,
|
||||
annotation_cache: Vec::new(),
|
||||
root_path: None,
|
||||
}
|
||||
}
|
||||
@@ -58,6 +75,8 @@ impl State {
|
||||
match msg {
|
||||
Message::OpenFile(file) => {
|
||||
self.open(file);
|
||||
self.integrate_tmp_file();
|
||||
self.delete_tmp_file();
|
||||
}
|
||||
Message::NextImage => {
|
||||
self.skip();
|
||||
@@ -67,9 +86,13 @@ impl State {
|
||||
}
|
||||
Message::MarkFocus => {
|
||||
self.mark_focus();
|
||||
self.save();
|
||||
self.save_tmp();
|
||||
self.skip();
|
||||
}
|
||||
Message::Quit => {
|
||||
self.save();
|
||||
self.delete_tmp_file();
|
||||
}
|
||||
Message::FocusLevelChange(lvl) => {
|
||||
self.set_focus_image_index(Some(*lvl));
|
||||
}
|
||||
@@ -141,11 +164,47 @@ impl State {
|
||||
pub fn mark_focus(&mut self) {
|
||||
match (self.stack_index, self.focus_image_index) {
|
||||
(Some(stack_index), Some(_)) => {
|
||||
self.stacks[stack_index].best_index = self.focus_image_index;
|
||||
let best_index = self.focus_image_index;
|
||||
self.stacks[stack_index].best_index = best_index;
|
||||
if let Some(best_index) = best_index {
|
||||
self.annotation_cache
|
||||
.push(LightAnnotation::new(stack_index, best_index))
|
||||
}
|
||||
}
|
||||
(_, _) => {}
|
||||
}
|
||||
}
|
||||
pub fn integrate_tmp_file(&mut self) {
|
||||
self.get_file_path().map(|mut path| {
|
||||
path.set_extension(ANNOTATION_CACHE_FILE_ENDING);
|
||||
|
||||
if path.exists() {
|
||||
let contents =
|
||||
fs::read_to_string(path).expect("Something went wrong reading the file");
|
||||
|
||||
self.annotation_cache = serde_json::from_str(&contents).unwrap();
|
||||
self.integrate_annotation_cache();
|
||||
} else {
|
||||
eprintln!("Tmp annotation file {:?} does not exist", path);
|
||||
}
|
||||
});
|
||||
}
|
||||
fn integrate_annotation_cache(&mut self) {
|
||||
self.annotation_cache.iter().for_each(|annotation| {
|
||||
self.stacks.get_mut(annotation.stack_index).map(|x| {
|
||||
x.best_index = Some(annotation.focus_image_index);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
pub fn delete_tmp_file(&mut self) {
|
||||
self.get_file_path().map(|mut path| {
|
||||
path.set_extension(ANNOTATION_CACHE_FILE_ENDING);
|
||||
if path.exists() {
|
||||
fs::remove_file(path).unwrap();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn open(&mut self, file: &File) {
|
||||
let filename = file.path().expect("Couldn't get file path");
|
||||
@@ -183,40 +242,57 @@ impl State {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save(&self) {
|
||||
fn save_file<T: Serialize>(path: PathBuf, content: &T) {
|
||||
match fs::File::create(path) {
|
||||
Ok(mut file) => {
|
||||
let now = Instant::now();
|
||||
let contents = serde_json::to_string(content).expect("Could not serialize.");
|
||||
let elapsed = now.elapsed();
|
||||
println!("Serialization: {:.2?}", elapsed);
|
||||
|
||||
let now = Instant::now();
|
||||
match file.write(contents.as_bytes()) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"an error occured while saving annotation cache: {}",
|
||||
e.to_string()
|
||||
);
|
||||
}
|
||||
}
|
||||
let elapsed = now.elapsed();
|
||||
println!("Writing to file: {:.2?}", elapsed);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("{}", e.to_string());
|
||||
}
|
||||
};
|
||||
}
|
||||
fn get_file_path(&self) -> Option<PathBuf> {
|
||||
match (self.root_path.clone(), self.file_name.clone()) {
|
||||
(Some(root_path), Some(file_name)) => {
|
||||
let path = Path::new(&root_path).join(Path::new(&file_name));
|
||||
match fs::File::create(path) {
|
||||
Ok(mut file) => {
|
||||
let now = Instant::now();
|
||||
let contents =
|
||||
serde_json::to_string(&self.stacks).expect("Could not serialize data.");
|
||||
let elapsed = now.elapsed();
|
||||
println!("Serialization: {:.2?}", elapsed);
|
||||
|
||||
let now = Instant::now();
|
||||
match file.write(contents.as_bytes()) {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
eprintln!("an error occured while saving: {}", e.to_string());
|
||||
}
|
||||
}
|
||||
let elapsed = now.elapsed();
|
||||
println!("Writing to file: {:.2?}", elapsed);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("{}", e.to_string());
|
||||
}
|
||||
};
|
||||
Some(Path::new(&root_path).join(Path::new(&file_name)))
|
||||
}
|
||||
(_, _) => {
|
||||
// TODO: error dialogue
|
||||
eprintln!("No save path specified");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save_tmp(&self) {
|
||||
self.get_file_path().map(|mut path| {
|
||||
path.set_extension(ANNOTATION_CACHE_FILE_ENDING);
|
||||
State::save_file(path, &self.annotation_cache);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn save(&self) {
|
||||
self.get_file_path().map(|path| {
|
||||
State::save_file(path, &self.stacks);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn previous(&mut self) {
|
||||
let len = self.stacks.len();
|
||||
if len == 0 {
|
||||
|
||||
@@ -275,6 +275,7 @@ impl ImageUI {
|
||||
}
|
||||
self.update_focus_scale(&state);
|
||||
}
|
||||
Message::Quit => {}
|
||||
}
|
||||
}
|
||||
fn update_image(&self, annotation_image: &AnnotationImage, base_path: String) {
|
||||
|
||||
Reference in New Issue
Block a user