use message passing instead of Arc to avoid panics

This commit is contained in:
2022-02-16 17:23:22 +01:00
parent 31e09f48eb
commit 06c34950a7
3 changed files with 261 additions and 154 deletions

View File

@@ -1,17 +1,41 @@
use std::collections::HashMap;
use std::fs;
use std::io::Write;
use std::path::Path;
use std::{collections::HashMap, fs::File};
use gtk::{gio::File, prelude::FileExt};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::constants::NONE_STRING_OPTION;
#[derive(Debug)]
pub enum Message {
FocusLevelChange(usize),
MarkFocus,
NextImage,
PreviousImage,
UI(UIMessage),
OpenFile(File),
}
// Messages that do not impact state
#[derive(Debug)]
pub enum UIMessage {
OpenFileChooser,
RefreshImages,
ToggleGrid,
DecrementFocus,
IncrementFocus,
ShowGrid(bool),
}
#[derive(Debug, Clone)]
pub struct State {
stacks: Vec<AnnotationZStack>,
stack_index: Option<usize>,
pub image_index: Option<usize>,
pub file_name: Option<String>,
focus_image_index: Option<usize>,
file_name: Option<String>,
pub root_path: Option<String>,
}
@@ -20,17 +44,71 @@ impl State {
State {
stacks: Vec::new(),
stack_index: None,
image_index: None,
focus_image_index: None,
file_name: None,
root_path: None,
}
}
pub fn set_image_index(&mut self, image_index: Option<usize>) {
self.image_index = image_index;
pub fn get_focus_image_index(&self) -> Option<usize> {
return self.focus_image_index;
}
pub fn update(&mut self, msg: &Message) {
match msg {
Message::OpenFile(file) => {
let filename = file.path().expect("Couldn't get file path");
let contents = fs::read_to_string(filename.clone())
.expect("Something went wrong reading the file");
//eprintln!("{}", contents);
let new_dataset: Vec<AnnotationZStack> = serde_json::from_str(&contents).unwrap();
self.replace_foucs_stacks(new_dataset);
self.file_name = filename.clone().as_path().file_name().map(|x| {
x.to_str()
.expect("failed to convert filname to str")
.to_string()
});
self.root_path = filename.clone().as_path().parent().map(|x| {
x.to_str()
.expect("failed to convert filname to str")
.to_string()
});
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));
eprintln!("{:?}", path);
}
(_, _) => {
eprintln!("Path not properly set");
}
}
}
Message::NextImage => {
self.skip();
}
Message::PreviousImage => {
self.previous();
}
Message::MarkFocus => {
self.mark_focus();
self.save();
self.skip();
}
Message::FocusLevelChange(lvl) => {
self.set_focus_image_index(Some(*lvl));
}
Message::UI(_) => {}
}
}
pub fn set_focus_image_index(&mut self, image_index: Option<usize>) {
self.focus_image_index = image_index;
}
pub fn get_current_annotation_image(&self) -> Option<AnnotationImage> {
match self.image_index {
match self.focus_image_index {
Some(image_index) => {
let stack = self.get_current_focus_stack();
match stack {
@@ -56,7 +134,7 @@ impl State {
if let Some(z_stack) = self.stacks.first() {
self.stack_index = Some(0);
self.image_index = if let Some(_) = z_stack.images.first() {
self.focus_image_index = if let Some(_) = z_stack.images.first() {
Some(0)
} else {
None
@@ -87,9 +165,9 @@ impl State {
}
pub fn mark_focus(&mut self) {
match (self.stack_index, self.image_index) {
match (self.stack_index, self.focus_image_index) {
(Some(stack_index), Some(_)) => {
self.stacks[stack_index].best_index = self.image_index;
self.stacks[stack_index].best_index = self.focus_image_index;
}
(_, _) => {}
}
@@ -99,16 +177,24 @@ impl State {
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 File::create(path) {
match fs::File::create(path) {
Ok(mut file) => {
use std::time::Instant;
let now = Instant::now();
let contents =
serde_json::to_string(&self.stacks).expect("Could not serialize data.");
let elapsed = now.elapsed();
println!("Elapsed: {:.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!("Elapsed: {:.2?}", elapsed);
}
Err(e) => {
eprintln!("{}", e.to_string());