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:
@@ -9,3 +9,4 @@ pub const TOGGLE_NEIGHBOURS_TEXT_TOGGLED: &str = "Hide Neighbours";
|
|||||||
pub const TOGGLE_NEIGHBOURS_TEXT: &str = "Show 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(&skip_focus);
|
||||||
image_ui.window.add_action(&back_focus);
|
image_ui.window.add_action(&back_focus);
|
||||||
|
|
||||||
|
let _sender = sender.clone();
|
||||||
|
app.connect_shutdown(move |_| {
|
||||||
|
_sender.send(Message::Quit).unwrap();
|
||||||
|
});
|
||||||
|
|
||||||
image_ui.show();
|
image_ui.show();
|
||||||
receiver.attach(None, move |msg| {
|
receiver.attach(None, move |msg| {
|
||||||
eprintln!("Received message: {:?}", msg);
|
eprintln!("Received message: {:?}", msg);
|
||||||
|
|||||||
134
src/state/mod.rs
134
src/state/mod.rs
@@ -1,13 +1,13 @@
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::{collections::HashMap, time::Instant};
|
use std::{collections::HashMap, time::Instant};
|
||||||
|
|
||||||
use gtk::{gio::File, prelude::FileExt};
|
use gtk::{gio::File, prelude::FileExt};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use crate::constants::NONE_STRING_OPTION;
|
use crate::constants::{ANNOTATION_CACHE_FILE_ENDING, NONE_STRING_OPTION};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
@@ -17,6 +17,7 @@ pub enum Message {
|
|||||||
PreviousImage,
|
PreviousImage,
|
||||||
UI(UIMessage),
|
UI(UIMessage),
|
||||||
OpenFile(File),
|
OpenFile(File),
|
||||||
|
Quit,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Messages that do not impact state
|
// Messages that do not impact state
|
||||||
@@ -36,8 +37,23 @@ pub struct State {
|
|||||||
stack_index: Option<usize>,
|
stack_index: Option<usize>,
|
||||||
focus_image_index: Option<usize>,
|
focus_image_index: Option<usize>,
|
||||||
file_name: Option<String>,
|
file_name: Option<String>,
|
||||||
|
annotation_cache: Vec<LightAnnotation>,
|
||||||
pub root_path: Option<String>,
|
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 {
|
impl State {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@@ -46,6 +62,7 @@ impl State {
|
|||||||
stack_index: None,
|
stack_index: None,
|
||||||
focus_image_index: None,
|
focus_image_index: None,
|
||||||
file_name: None,
|
file_name: None,
|
||||||
|
annotation_cache: Vec::new(),
|
||||||
root_path: None,
|
root_path: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,6 +75,8 @@ impl State {
|
|||||||
match msg {
|
match msg {
|
||||||
Message::OpenFile(file) => {
|
Message::OpenFile(file) => {
|
||||||
self.open(file);
|
self.open(file);
|
||||||
|
self.integrate_tmp_file();
|
||||||
|
self.delete_tmp_file();
|
||||||
}
|
}
|
||||||
Message::NextImage => {
|
Message::NextImage => {
|
||||||
self.skip();
|
self.skip();
|
||||||
@@ -67,9 +86,13 @@ impl State {
|
|||||||
}
|
}
|
||||||
Message::MarkFocus => {
|
Message::MarkFocus => {
|
||||||
self.mark_focus();
|
self.mark_focus();
|
||||||
self.save();
|
self.save_tmp();
|
||||||
self.skip();
|
self.skip();
|
||||||
}
|
}
|
||||||
|
Message::Quit => {
|
||||||
|
self.save();
|
||||||
|
self.delete_tmp_file();
|
||||||
|
}
|
||||||
Message::FocusLevelChange(lvl) => {
|
Message::FocusLevelChange(lvl) => {
|
||||||
self.set_focus_image_index(Some(*lvl));
|
self.set_focus_image_index(Some(*lvl));
|
||||||
}
|
}
|
||||||
@@ -141,11 +164,47 @@ impl State {
|
|||||||
pub fn mark_focus(&mut self) {
|
pub fn mark_focus(&mut self) {
|
||||||
match (self.stack_index, self.focus_image_index) {
|
match (self.stack_index, self.focus_image_index) {
|
||||||
(Some(stack_index), Some(_)) => {
|
(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) {
|
pub fn open(&mut self, file: &File) {
|
||||||
let filename = file.path().expect("Couldn't get file path");
|
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()) {
|
match (self.root_path.clone(), self.file_name.clone()) {
|
||||||
(Some(root_path), Some(file_name)) => {
|
(Some(root_path), Some(file_name)) => {
|
||||||
let path = Path::new(&root_path).join(Path::new(&file_name));
|
Some(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());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
(_, _) => {
|
(_, _) => {
|
||||||
// TODO: error dialogue
|
|
||||||
eprintln!("No save path specified");
|
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) {
|
pub fn previous(&mut self) {
|
||||||
let len = self.stacks.len();
|
let len = self.stacks.len();
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
|
|||||||
@@ -275,6 +275,7 @@ impl ImageUI {
|
|||||||
}
|
}
|
||||||
self.update_focus_scale(&state);
|
self.update_focus_scale(&state);
|
||||||
}
|
}
|
||||||
|
Message::Quit => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn update_image(&self, annotation_image: &AnnotationImage, base_path: String) {
|
fn update_image(&self, annotation_image: &AnnotationImage, base_path: String) {
|
||||||
|
|||||||
Reference in New Issue
Block a user