Extract store invalidation detection into separate AppState
This commit is contained in:
parent
0e7e54bf71
commit
46f5bc38b8
4 changed files with 75 additions and 50 deletions
|
|
@ -1,18 +1,25 @@
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use gdn::{ids::NoteId, store::Store};
|
use gdn::ids::NoteId;
|
||||||
use tauri::{AppHandle, Emitter, State};
|
use tauri::{AppHandle, Emitter, State};
|
||||||
|
|
||||||
use crate::types::{EventNotesStoreUpdate, Note};
|
use crate::{
|
||||||
|
state::AppState,
|
||||||
|
types::{EventNotesStoreUpdate, Note},
|
||||||
|
};
|
||||||
|
|
||||||
// API methods are sorted alphabetically.
|
// API methods are sorted alphabetically.
|
||||||
|
|
||||||
fn update_if_required(store: &mut Store, app: &AppHandle) {
|
fn update_if_required(state: &mut AppState, app: &AppHandle) {
|
||||||
if let Some(store_id) = store.needs_update() {
|
let store_id = state.store.id();
|
||||||
|
if state.store_last_id == Some(store_id) {
|
||||||
|
// No update necessary if the id hasn't changed
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let payload = EventNotesStoreUpdate { store_id };
|
let payload = EventNotesStoreUpdate { store_id };
|
||||||
app.emit("notes_store_update", payload).unwrap();
|
app.emit("notes_store_update", payload).unwrap();
|
||||||
store.update();
|
state.store_last_id = Some(store_id)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|
@ -21,10 +28,12 @@ pub fn note_child_add(
|
||||||
child_id: NoteId,
|
child_id: NoteId,
|
||||||
child_position: isize,
|
child_position: isize,
|
||||||
app: AppHandle,
|
app: AppHandle,
|
||||||
store: State<'_, Arc<Mutex<Store>>>,
|
state: State<'_, Arc<Mutex<AppState>>>,
|
||||||
) {
|
) {
|
||||||
let mut guard = store.lock().unwrap();
|
let mut guard = state.lock().unwrap();
|
||||||
guard.add_child_at_position(id, child_id, child_position);
|
guard
|
||||||
|
.store
|
||||||
|
.add_child_at_position(id, child_id, child_position);
|
||||||
update_if_required(&mut guard, &app);
|
update_if_required(&mut guard, &app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,10 +45,12 @@ pub fn note_child_move(
|
||||||
to_id: NoteId,
|
to_id: NoteId,
|
||||||
to_position: isize,
|
to_position: isize,
|
||||||
app: AppHandle,
|
app: AppHandle,
|
||||||
store: State<'_, Arc<Mutex<Store>>>,
|
state: State<'_, Arc<Mutex<AppState>>>,
|
||||||
) {
|
) {
|
||||||
let mut guard = store.lock().unwrap();
|
let mut guard = state.lock().unwrap();
|
||||||
guard.move_child_by_id_to_position(child_id, from_id, from_iteration, to_id, to_position);
|
guard
|
||||||
|
.store
|
||||||
|
.move_child_by_id_to_position(child_id, from_id, from_iteration, to_id, to_position);
|
||||||
update_if_required(&mut guard, &app);
|
update_if_required(&mut guard, &app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,10 +60,12 @@ pub fn note_child_remove(
|
||||||
child_id: NoteId,
|
child_id: NoteId,
|
||||||
child_iteration: usize,
|
child_iteration: usize,
|
||||||
app: AppHandle,
|
app: AppHandle,
|
||||||
store: State<'_, Arc<Mutex<Store>>>,
|
state: State<'_, Arc<Mutex<AppState>>>,
|
||||||
) {
|
) {
|
||||||
let mut guard = store.lock().unwrap();
|
let mut guard = state.lock().unwrap();
|
||||||
guard.remove_child_by_id(id, child_id, child_iteration);
|
guard
|
||||||
|
.store
|
||||||
|
.remove_child_by_id(id, child_id, child_iteration);
|
||||||
update_if_required(&mut guard, &app);
|
update_if_required(&mut guard, &app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,32 +74,33 @@ pub fn note_children_set(
|
||||||
id: NoteId,
|
id: NoteId,
|
||||||
children: Vec<NoteId>,
|
children: Vec<NoteId>,
|
||||||
app: AppHandle,
|
app: AppHandle,
|
||||||
store: State<'_, Arc<Mutex<Store>>>,
|
state: State<'_, Arc<Mutex<AppState>>>,
|
||||||
) {
|
) {
|
||||||
let mut guard = store.lock().unwrap();
|
let mut guard = state.lock().unwrap();
|
||||||
guard.set_children(id, children);
|
guard.store.set_children(id, children);
|
||||||
update_if_required(&mut guard, &app);
|
update_if_required(&mut guard, &app);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn note_create(text: String, app: AppHandle, store: State<'_, Arc<Mutex<Store>>>) -> Note {
|
pub fn note_create(text: String, app: AppHandle, state: State<'_, Arc<Mutex<AppState>>>) -> Note {
|
||||||
let mut guard = store.lock().unwrap();
|
let mut guard = state.lock().unwrap();
|
||||||
let id = guard.create(text);
|
let id = guard.store.create(text);
|
||||||
|
let note = guard.store.get(id).unwrap().into();
|
||||||
update_if_required(&mut guard, &app);
|
update_if_required(&mut guard, &app);
|
||||||
guard.get(id).unwrap().into()
|
note
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn note_delete(id: NoteId, app: AppHandle, store: State<'_, Arc<Mutex<Store>>>) {
|
pub fn note_delete(id: NoteId, app: AppHandle, state: State<'_, Arc<Mutex<AppState>>>) {
|
||||||
let mut guard = store.lock().unwrap();
|
let mut guard = state.lock().unwrap();
|
||||||
guard.delete(id);
|
guard.store.delete(id);
|
||||||
update_if_required(&mut guard, &app);
|
update_if_required(&mut guard, &app);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn note_get(id: NoteId, store: State<'_, Arc<Mutex<Store>>>) -> Option<Note> {
|
pub fn note_get(id: NoteId, state: State<'_, Arc<Mutex<AppState>>>) -> Option<Note> {
|
||||||
let guard = store.lock().unwrap();
|
let guard = state.lock().unwrap();
|
||||||
guard.get(id).map(|it| it.into())
|
guard.store.get(id).map(|it| it.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|
@ -94,16 +108,16 @@ pub fn note_text_set(
|
||||||
id: NoteId,
|
id: NoteId,
|
||||||
text: String,
|
text: String,
|
||||||
app: AppHandle,
|
app: AppHandle,
|
||||||
store: State<'_, Arc<Mutex<Store>>>,
|
state: State<'_, Arc<Mutex<AppState>>>,
|
||||||
) {
|
) {
|
||||||
let mut guard = store.lock().unwrap();
|
let mut guard = state.lock().unwrap();
|
||||||
guard.set_text(id, text);
|
guard.store.set_text(id, text);
|
||||||
update_if_required(&mut guard, &app);
|
update_if_required(&mut guard, &app);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn notes_clear(app: AppHandle, store: State<'_, Arc<Mutex<Store>>>) {
|
pub fn notes_clear(app: AppHandle, state: State<'_, Arc<Mutex<AppState>>>) {
|
||||||
let mut guard = store.lock().unwrap();
|
let mut guard = state.lock().unwrap();
|
||||||
guard.clear();
|
guard.store.clear();
|
||||||
update_if_required(&mut guard, &app);
|
update_if_required(&mut guard, &app);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,21 @@
|
||||||
use serde_json as _; // Silence unused dependency warning
|
use serde_json as _; // Silence unused dependency warning
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use gdn::store::Store;
|
use crate::state::AppState;
|
||||||
|
|
||||||
mod api;
|
mod api;
|
||||||
|
mod state;
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
|
let state = Arc::new(Mutex::new(AppState::new()));
|
||||||
|
|
||||||
|
// TODO Launch store loading task
|
||||||
|
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.plugin(tauri_plugin_opener::init())
|
.plugin(tauri_plugin_opener::init())
|
||||||
.manage(Arc::new(Mutex::new(Store::new())))
|
.manage(state)
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
api::note_child_add,
|
api::note_child_add,
|
||||||
api::note_child_move,
|
api::note_child_move,
|
||||||
|
|
|
||||||
15
gdn-app/src-tauri/src/state.rs
Normal file
15
gdn-app/src-tauri/src/state.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
use gdn::store::Store;
|
||||||
|
|
||||||
|
pub struct AppState {
|
||||||
|
pub store: Store,
|
||||||
|
pub store_last_id: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppState {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
store: Store::new(),
|
||||||
|
store_last_id: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -38,8 +38,7 @@ pub struct RichNote {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Store {
|
pub struct Store {
|
||||||
last_id: u64,
|
id: u64,
|
||||||
curr_id: u64,
|
|
||||||
notes: HashMap<NoteId, RawNote>,
|
notes: HashMap<NoteId, RawNote>,
|
||||||
parents: HashMap<NoteId, HashMap<NoteId, usize>>,
|
parents: HashMap<NoteId, HashMap<NoteId, usize>>,
|
||||||
}
|
}
|
||||||
|
|
@ -74,16 +73,8 @@ impl Store {
|
||||||
Repo { notes }
|
Repo { notes }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn needs_update(&self) -> Option<u64> {
|
pub fn id(&self) -> u64 {
|
||||||
if self.last_id != self.curr_id {
|
self.id
|
||||||
Some(self.curr_id)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update(&mut self) {
|
|
||||||
self.last_id = self.curr_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, id: NoteId) -> Option<RichNote> {
|
pub fn get(&self, id: NoteId) -> Option<RichNote> {
|
||||||
|
|
@ -104,7 +95,7 @@ impl Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick(&mut self) {
|
fn tick(&mut self) {
|
||||||
self.curr_id += 1;
|
self.id += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_consistent_and_tick(&mut self) {
|
fn make_consistent_and_tick(&mut self) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue