From 711b6d97ff7a1dc020fb900c859b7e4328e5dca2 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Sun, 11 Oct 2020 21:13:15 +0200 Subject: [PATCH] Use async functions for backend --- Cargo.toml | 2 + src/backend.rs | 347 +++++++++-------------------- src/dialogs/ensemble_editor.rs | 13 +- src/dialogs/ensemble_selector.rs | 62 +++--- src/dialogs/instrument_editor.rs | 13 +- src/dialogs/instrument_selector.rs | 62 +++--- src/dialogs/person_editor.rs | 13 +- src/dialogs/person_selector.rs | 62 +++--- src/dialogs/recording_editor.rs | 13 +- src/dialogs/work_editor.rs | 11 +- src/dialogs/work_selector.rs | 26 ++- src/window.rs | 142 +++++++----- 12 files changed, 346 insertions(+), 420 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index beb9fa2..e0e6961 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,8 @@ edition = "2018" anyhow = "1.0.33" diesel = { version = "1.4.5", features = ["sqlite"] } diesel_migrations = "1.4.0" +futures = "0.3.6" +futures-channel = "0.3.5" gio = "0.9.1" glib = "0.10.2" gtk = { version = "0.9.2", features = ["v3_24"] } diff --git a/src/backend.rs b/src/backend.rs index 9dc1632..389432b 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -1,6 +1,7 @@ use super::database::*; use anyhow::Result; -use glib::Sender; +use futures_channel::oneshot; +use futures_channel::oneshot::Sender; enum BackendAction { UpdatePerson(Person, Sender>), @@ -157,265 +158,123 @@ impl Backend { } } - pub fn update_person) -> () + 'static>(&self, person: Person, callback: F) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(UpdatePerson(person, sender)) - .expect("Failed to send action to database thread!"); + pub async fn update_person(&self, person: Person) -> Result<()> { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(UpdatePerson(person, sender)); + receiver.await? } - pub fn get_person) -> () + 'static>(&self, id: i64, callback: F) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(GetPerson(id, sender)) - .expect("Failed to send action to database thread!"); + pub async fn get_person(&self, id: i64) -> Result { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(GetPerson(id, sender)); + receiver.await? } - pub fn delete_person) -> () + 'static>(&self, id: i64, callback: F) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(DeletePerson(id, sender)) - .expect("Failed to send action to database thread!"); + pub async fn delete_person(&self, id: i64) -> Result<()> { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(DeletePerson(id, sender)); + receiver.await? } - pub fn get_persons>) -> () + 'static>(&self, callback: F) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(GetPersons(sender)) - .expect("Failed to send action to database thread!"); + pub async fn get_persons(&self) -> Result> { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(GetPersons(sender)); + receiver.await? } - pub fn update_instrument) -> () + 'static>( + pub async fn update_instrument(&self, instrument: Instrument) -> Result<()> { + let (sender, receiver) = oneshot::channel(); + self.action_sender + .send(UpdateInstrument(instrument, sender)); + receiver.await? + } + + pub async fn get_instrument(&self, id: i64) -> Result { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(GetInstrument(id, sender)); + receiver.await? + } + + pub async fn delete_instrument(&self, id: i64) -> Result<()> { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(DeleteInstrument(id, sender)); + receiver.await? + } + + pub async fn get_instruments(&self) -> Result> { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(GetInstruments(sender)); + receiver.await? + } + + pub async fn update_work(&self, work_insertion: WorkInsertion) -> Result<()> { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(UpdateWork(work_insertion, sender)); + receiver.await? + } + + pub async fn get_work_descriptions(&self, person_id: i64) -> Result> { + let (sender, receiver) = oneshot::channel(); + self.action_sender + .send(GetWorkDescriptions(person_id, sender)); + receiver.await? + } + + pub async fn update_ensemble(&self, ensemble: Ensemble) -> Result<()> { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(UpdateEnsemble(ensemble, sender)); + receiver.await? + } + + pub async fn get_ensemble(&self, id: i64) -> Result { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(GetEnsemble(id, sender)); + receiver.await? + } + + pub async fn delete_ensemble(&self, id: i64) -> Result<()> { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(DeleteEnsemble(id, sender)); + receiver.await? + } + + pub async fn get_ensembles(&self) -> Result> { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(GetEnsembles(sender)); + receiver.await? + } + + pub async fn update_recording(&self, recording_insertion: RecordingInsertion) -> Result<()> { + let (sender, receiver) = oneshot::channel(); + self.action_sender + .send(UpdateRecording(recording_insertion, sender)); + receiver.await? + } + + pub async fn get_recordings_for_person( &self, - instrument: Instrument, - callback: F, - ) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - + person_id: i64, + ) -> Result> { + let (sender, receiver) = oneshot::channel(); self.action_sender - .send(UpdateInstrument(instrument, sender)) - .expect("Failed to send action to database thread!"); + .send(GetRecordingsForPerson(person_id, sender)); + receiver.await? } - pub fn get_instrument) -> () + 'static>(&self, id: i64, callback: F) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(GetInstrument(id, sender)) - .expect("Failed to send action to database thread!"); - } - - pub fn delete_instrument) -> () + 'static>(&self, id: i64, callback: F) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(DeleteInstrument(id, sender)) - .expect("Failed to send action to database thread!"); - } - - pub fn get_instruments>) -> () + 'static>(&self, callback: F) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(GetInstruments(sender)) - .expect("Failed to send action to database thread!"); - } - - pub fn update_work) -> () + 'static>(&self, work: WorkInsertion, callback: F) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(UpdateWork(work, sender)) - .expect("Failed to send action to database thread!"); - } - - pub fn get_work_descriptions>) -> () + 'static>( + pub async fn get_recordings_for_ensemble( &self, - id: i64, - callback: F, - ) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - + ensemble_id: i64, + ) -> Result> { + let (sender, receiver) = oneshot::channel(); self.action_sender - .send(GetWorkDescriptions(id, sender)) - .expect("Failed to send action to database thread!"); + .send(GetRecordingsForEnsemble(ensemble_id, sender)); + receiver.await? } - pub fn update_ensemble) -> () + 'static>( - &self, - ensemble: Ensemble, - callback: F, - ) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - + pub async fn get_recordings_for_work(&self, work_id: i64) -> Result> { + let (sender, receiver) = oneshot::channel(); self.action_sender - .send(UpdateEnsemble(ensemble, sender)) - .expect("Failed to send action to database thread!"); - } - - pub fn get_ensemble) -> () + 'static>(&self, id: i64, callback: F) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(GetEnsemble(id, sender)) - .expect("Failed to send action to database thread!"); - } - - pub fn delete_ensemble) -> () + 'static>(&self, id: i64, callback: F) { - let (sender, receiver) = glib::MainContext::channel::>(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(DeleteEnsemble(id, sender)) - .expect("Failed to send action to database thread!"); - } - - pub fn get_ensembles>) -> () + 'static>(&self, callback: F) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(GetEnsembles(sender)) - .expect("Failed to send action to database thread!"); - } - - pub fn update_recording) -> () + 'static>( - &self, - recording: RecordingInsertion, - callback: F, - ) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(UpdateRecording(recording, sender)) - .expect("Failed to send action to database thread!"); - } - - pub fn get_recordings_for_person>) -> () + 'static>( - &self, - id: i64, - callback: F, - ) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(GetRecordingsForPerson(id, sender)) - .expect("Failed to send action to database thread!"); - } - - pub fn get_recordings_for_ensemble>) -> () + 'static>( - &self, - id: i64, - callback: F, - ) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(GetRecordingsForEnsemble(id, sender)) - .expect("Failed to send action to database thread!"); - } - - pub fn get_recordings_for_work>) -> () + 'static>( - &self, - id: i64, - callback: F, - ) { - let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); - - receiver.attach(None, move |result| { - callback(result); - glib::Continue(true) - }); - - self.action_sender - .send(GetRecordingsForWork(id, sender)) - .expect("Failed to send action to database thread!"); + .send(GetRecordingsForWork(work_id, sender)); + receiver.await? } } diff --git a/src/dialogs/ensemble_editor.rs b/src/dialogs/ensemble_editor.rs index aef8f43..c0fbeff 100644 --- a/src/dialogs/ensemble_editor.rs +++ b/src/dialogs/ensemble_editor.rs @@ -9,6 +9,7 @@ pub struct EnsembleEditor where F: Fn(Ensemble) -> () + 'static, { + backend: Rc, window: gtk::Window, callback: F, id: i64, @@ -42,6 +43,7 @@ where }; let result = Rc::new(EnsembleEditor { + backend: backend, window: window, callback: callback, id: id, @@ -58,10 +60,13 @@ where name: result.name_entry.get_text().to_string(), }; - backend.update_ensemble(ensemble.clone(), clone!(@strong result => move |_| { - result.window.close(); - (result.callback)(ensemble.clone()); - })); + let clone = result.clone(); + let c = glib::MainContext::default(); + c.spawn_local(async move { + clone.backend.update_ensemble(ensemble.clone()).await.unwrap(); + clone.window.close(); + (clone.callback)(ensemble.clone()); + }); })); result.window.set_transient_for(Some(parent)); diff --git a/src/dialogs/ensemble_selector.rs b/src/dialogs/ensemble_selector.rs index b399609..b3ee5dd 100644 --- a/src/dialogs/ensemble_selector.rs +++ b/src/dialogs/ensemble_selector.rs @@ -41,40 +41,40 @@ where list: list, }); - result - .backend - .get_ensembles(clone!(@strong result => move |ensembles| { - let ensembles = ensembles.unwrap(); + let c = glib::MainContext::default(); + let clone = result.clone(); + c.spawn_local(async move { + let ensembles = clone.backend.get_ensembles().await.unwrap(); - for (index, ensemble) in ensembles.iter().enumerate() { - let label = gtk::Label::new(Some(&ensemble.name)); - label.set_halign(gtk::Align::Start); - let row = SelectorRow::new(index.try_into().unwrap(), &label); - row.show_all(); - result.list.insert(&row, -1); - } + for (index, ensemble) in ensembles.iter().enumerate() { + let label = gtk::Label::new(Some(&ensemble.name)); + label.set_halign(gtk::Align::Start); + let row = SelectorRow::new(index.try_into().unwrap(), &label); + row.show_all(); + clone.list.insert(&row, -1); + } - result - .list - .connect_row_activated(clone!(@strong result, @strong ensembles => move |_, row| { - result.window.close(); - let row = row.get_child().unwrap().downcast::().unwrap(); - let index: usize = row.get_index().try_into().unwrap(); - (result.callback)(ensembles[index].clone()); - })); + clone.list.connect_row_activated( + clone!(@strong clone, @strong ensembles => move |_, row| { + clone.window.close(); + let row = row.get_child().unwrap().downcast::().unwrap(); + let index: usize = row.get_index().try_into().unwrap(); + (clone.callback)(ensembles[index].clone()); + }), + ); - result - .list - .set_filter_func(Some(Box::new(clone!(@strong result => move |row| { - let row = row.get_child().unwrap().downcast::().unwrap(); - let index: usize = row.get_index().try_into().unwrap(); - let search = result.search_entry.get_text().to_string().to_lowercase(); - search.is_empty() || ensembles[index] - .name - .to_lowercase() - .contains(&search) - })))); - })); + clone + .list + .set_filter_func(Some(Box::new(clone!(@strong clone => move |row| { + let row = row.get_child().unwrap().downcast::().unwrap(); + let index: usize = row.get_index().try_into().unwrap(); + let search = clone.search_entry.get_text().to_string().to_lowercase(); + search.is_empty() || ensembles[index] + .name + .to_lowercase() + .contains(&search) + })))); + }); result .search_entry diff --git a/src/dialogs/instrument_editor.rs b/src/dialogs/instrument_editor.rs index 1174351..15a6225 100644 --- a/src/dialogs/instrument_editor.rs +++ b/src/dialogs/instrument_editor.rs @@ -9,6 +9,7 @@ pub struct InstrumentEditor where F: Fn(Instrument) -> () + 'static, { + backend: Rc, window: gtk::Window, callback: F, id: i64, @@ -42,6 +43,7 @@ where }; let result = Rc::new(InstrumentEditor { + backend: backend, window: window, callback: callback, id: id, @@ -58,10 +60,13 @@ where name: result.name_entry.get_text().to_string(), }; - backend.update_instrument(instrument.clone(), clone!(@strong result => move |_| { - result.window.close(); - (result.callback)(instrument.clone()); - })); + let c = glib::MainContext::default(); + let clone = result.clone(); + c.spawn_local(async move { + clone.backend.update_instrument(instrument.clone()).await.unwrap(); + clone.window.close(); + (clone.callback)(instrument.clone()); + }); })); result.window.set_transient_for(Some(parent)); diff --git a/src/dialogs/instrument_selector.rs b/src/dialogs/instrument_selector.rs index 5d708eb..02fea94 100644 --- a/src/dialogs/instrument_selector.rs +++ b/src/dialogs/instrument_selector.rs @@ -41,41 +41,41 @@ where list: list, }); - result - .backend - .get_instruments(clone!(@strong result => move |instruments| { - let instruments = instruments.unwrap(); + let c = glib::MainContext::default(); + let clone = result.clone(); + c.spawn_local(async move { + let instruments = clone.backend.get_instruments().await.unwrap(); - for (index, instrument) in instruments.iter().enumerate() { - let label = gtk::Label::new(Some(&instrument.name)); - label.set_halign(gtk::Align::Start); - let row = SelectorRow::new(index.try_into().unwrap(), &label); - row.show_all(); - result.list.insert(&row, -1); - } + for (index, instrument) in instruments.iter().enumerate() { + let label = gtk::Label::new(Some(&instrument.name)); + label.set_halign(gtk::Align::Start); + let row = SelectorRow::new(index.try_into().unwrap(), &label); + row.show_all(); + clone.list.insert(&row, -1); + } - result - .list - .connect_row_activated(clone!(@strong result, @strong instruments => move |_, row| { - result.window.close(); - let row = row.get_child().unwrap().downcast::().unwrap(); - let index: usize = row.get_index().try_into().unwrap(); - (result.callback)(instruments[index].clone()); - })); + clone.list.connect_row_activated( + clone!(@strong clone, @strong instruments => move |_, row| { + clone.window.close(); + let row = row.get_child().unwrap().downcast::().unwrap(); + let index: usize = row.get_index().try_into().unwrap(); + (clone.callback)(instruments[index].clone()); + }), + ); - result - .list - .set_filter_func(Some(Box::new(clone!(@strong result => move |row| { - let row = row.get_child().unwrap().downcast::().unwrap(); - let index: usize = row.get_index().try_into().unwrap(); - let search = result.search_entry.get_text().to_string(); + clone + .list + .set_filter_func(Some(Box::new(clone!(@strong clone => move |row| { + let row = row.get_child().unwrap().downcast::().unwrap(); + let index: usize = row.get_index().try_into().unwrap(); + let search = clone.search_entry.get_text().to_string(); - search.is_empty() || instruments[index] - .name - .to_lowercase() - .contains(&result.search_entry.get_text().to_string().to_lowercase()) - })))); - })); + search.is_empty() || instruments[index] + .name + .to_lowercase() + .contains(&clone.search_entry.get_text().to_string().to_lowercase()) + })))); + }); result .search_entry diff --git a/src/dialogs/person_editor.rs b/src/dialogs/person_editor.rs index f47cb7a..7783f19 100644 --- a/src/dialogs/person_editor.rs +++ b/src/dialogs/person_editor.rs @@ -9,6 +9,7 @@ pub struct PersonEditor where F: Fn(Person) -> () + 'static, { + backend: Rc, window: gtk::Window, callback: F, id: i64, @@ -44,6 +45,7 @@ where }; let result = Rc::new(PersonEditor { + backend: backend, window: window, callback: callback, id: id, @@ -62,10 +64,13 @@ where last_name: result.last_name_entry.get_text().to_string(), }; - backend.update_person(person.clone(), clone!(@strong result => move |_| { - result.window.close(); - (result.callback)(person.clone()); - })); + let c = glib::MainContext::default(); + let clone = result.clone(); + c.spawn_local(async move { + clone.backend.update_person(person.clone()).await.unwrap(); + clone.window.close(); + (clone.callback)(person.clone()); + }); })); result.window.set_transient_for(Some(parent)); diff --git a/src/dialogs/person_selector.rs b/src/dialogs/person_selector.rs index 5575b3c..379e18e 100644 --- a/src/dialogs/person_selector.rs +++ b/src/dialogs/person_selector.rs @@ -41,40 +41,40 @@ where list: list, }); - result - .backend - .get_persons(clone!(@strong result => move |persons| { - let persons = persons.unwrap(); + let c = glib::MainContext::default(); + let clone = result.clone(); + c.spawn_local(async move { + let persons = clone.backend.get_persons().await.unwrap(); - for (index, person) in persons.iter().enumerate() { - let label = gtk::Label::new(Some(&person.name_lf())); - label.set_halign(gtk::Align::Start); - let row = SelectorRow::new(index.try_into().unwrap(), &label); - row.show_all(); - result.list.insert(&row, -1); - } + for (index, person) in persons.iter().enumerate() { + let label = gtk::Label::new(Some(&person.name_lf())); + label.set_halign(gtk::Align::Start); + let row = SelectorRow::new(index.try_into().unwrap(), &label); + row.show_all(); + clone.list.insert(&row, -1); + } - result - .list - .connect_row_activated(clone!(@strong result, @strong persons => move |_, row| { - result.window.close(); - let row = row.get_child().unwrap().downcast::().unwrap(); - let index: usize = row.get_index().try_into().unwrap(); - (result.callback)(persons[index].clone()); - })); + clone.list.connect_row_activated( + clone!(@strong clone, @strong persons => move |_, row| { + clone.window.close(); + let row = row.get_child().unwrap().downcast::().unwrap(); + let index: usize = row.get_index().try_into().unwrap(); + (clone.callback)(persons[index].clone()); + }), + ); - result - .list - .set_filter_func(Some(Box::new(clone!(@strong result => move |row| { - let row = row.get_child().unwrap().downcast::().unwrap(); - let index: usize = row.get_index().try_into().unwrap(); - let search = result.search_entry.get_text().to_string().to_lowercase(); - search.is_empty() || persons[index] - .name_lf() - .to_lowercase() - .contains(&search) - })))); - })); + clone + .list + .set_filter_func(Some(Box::new(clone!(@strong clone => move |row| { + let row = row.get_child().unwrap().downcast::().unwrap(); + let index: usize = row.get_index().try_into().unwrap(); + let search = clone.search_entry.get_text().to_string().to_lowercase(); + search.is_empty() || persons[index] + .name_lf() + .to_lowercase() + .contains(&search) + })))); + }); result .search_entry diff --git a/src/dialogs/recording_editor.rs b/src/dialogs/recording_editor.rs index 9d1f3d4..862943f 100644 --- a/src/dialogs/recording_editor.rs +++ b/src/dialogs/recording_editor.rs @@ -84,11 +84,14 @@ where comment: result.comment_entry.get_text().to_string(), performances: result.performers.borrow().to_vec(), }; - - result.backend.update_recording(recording.clone().into(), clone!(@strong result => move |_| { - result.window.close(); - (result.callback)(recording.clone()); - })); + + let c = glib::MainContext::default(); + let clone = result.clone(); + c.spawn_local(async move { + clone.backend.update_recording(recording.clone().into()).await.unwrap(); + clone.window.close(); + (clone.callback)(recording.clone()); + }); })); work_button.connect_clicked(clone!(@strong result => move |_| { diff --git a/src/dialogs/work_editor.rs b/src/dialogs/work_editor.rs index 187fb34..56b7ab0 100644 --- a/src/dialogs/work_editor.rs +++ b/src/dialogs/work_editor.rs @@ -185,10 +185,13 @@ where sections: sections, }; - result.backend.update_work(work.clone().into(), clone!(@strong result => move |_| { - result.window.close(); - (result.callback)(work.clone()); - })); + let c = glib::MainContext::default(); + let clone = result.clone(); + c.spawn_local(async move { + clone.backend.update_work(work.clone().into()).await.unwrap(); + clone.window.close(); + (clone.callback)(work.clone()); + }); })); composer_button.connect_clicked(clone!(@strong result => move |_| { diff --git a/src/dialogs/work_selector.rs b/src/dialogs/work_selector.rs index f3dd599..f71a1fe 100644 --- a/src/dialogs/work_selector.rs +++ b/src/dialogs/work_selector.rs @@ -122,10 +122,12 @@ where match state { Loading => { - self.backend - .get_persons(clone!(@strong self as self_ => move |persons| { - self_.clone().set_state(Persons(persons.unwrap())); - })); + let c = glib::MainContext::default(); + let clone = self.clone(); + c.spawn_local(async move { + let persons = clone.backend.get_persons().await.unwrap(); + clone.clone().set_state(Persons(persons)); + }); self.sidebar_stack.set_visible_child_name("loading"); self.stack.set_visible_child_name("empty_screen"); @@ -181,12 +183,16 @@ where PersonLoading(person) => { self.header.set_title(Some(&person.name_fl())); - self.backend.get_work_descriptions( - person.id, - clone!(@strong self as self_ => move |works| { - self_.clone().set_state(Person(works.unwrap())); - }), - ); + let c = glib::MainContext::default(); + let clone = self.clone(); + c.spawn_local(async move { + let works = clone + .backend + .get_work_descriptions(person.id) + .await + .unwrap(); + clone.clone().set_state(Person(works)); + }); self.content_stack.set_visible_child_name("loading"); self.stack.set_visible_child_name("person_screen"); diff --git a/src/window.rs b/src/window.rs index e8d15ea..62dbf67 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,6 +1,7 @@ use super::backend::Backend; use super::database::*; use super::dialogs::*; +use futures::prelude::*; use gio::prelude::*; use glib::clone; use gtk::prelude::*; @@ -196,12 +197,15 @@ impl Window { "edit-person", Some(glib::VariantTy::new("x").unwrap()), clone!(@strong result => move |_, id| { - result.backend.get_person(id.unwrap().get().unwrap(), clone!(@strong result => move |person| { - let person = person.unwrap(); + let id = id.unwrap().get().unwrap(); + let result = result.clone(); + let c = glib::MainContext::default(); + c.spawn_local(async move { + let person = result.backend.get_person(id).await.unwrap(); PersonEditor::new(result.backend.clone(), &result.window, Some(person), clone!(@strong result => move |_| { result.clone().set_state(Loading); })).show(); - })); + }); }) ); @@ -210,9 +214,13 @@ impl Window { "delete-person", Some(glib::VariantTy::new("x").unwrap()), clone!(@strong result => move |_, id| { - result.backend.delete_person(id.unwrap().get().unwrap(), clone!(@strong result => move |_| { + let id = id.unwrap().get().unwrap(); + let result = result.clone(); + let c = glib::MainContext::default(); + c.spawn_local(async move { + result.backend.delete_person(id).await.unwrap(); result.clone().set_state(Loading); - })); + }); }) ); @@ -221,12 +229,15 @@ impl Window { "edit-ensemble", Some(glib::VariantTy::new("x").unwrap()), clone!(@strong result => move |_, id| { - result.backend.get_ensemble(id.unwrap().get().unwrap(), clone!(@strong result => move |ensemble| { - let ensemble = ensemble.unwrap(); + let id = id.unwrap().get().unwrap(); + let result = result.clone(); + let c = glib::MainContext::default(); + c.spawn_local(async move { + let ensemble = result.backend.get_ensemble(id).await.unwrap(); EnsembleEditor::new(result.backend.clone(), &result.window, Some(ensemble), clone!(@strong result => move |_| { result.clone().set_state(Loading); })).show(); - })); + }); }) ); @@ -235,9 +246,13 @@ impl Window { "delete-ensemble", Some(glib::VariantTy::new("x").unwrap()), clone!(@strong result => move |_, id| { - result.backend.delete_ensemble(id.unwrap().get().unwrap(), clone!(@strong result => move |_| { + let id = id.unwrap().get().unwrap(); + let result = result.clone(); + let c = glib::MainContext::default(); + c.spawn_local(async move { + result.backend.delete_ensemble(id).await.unwrap(); result.clone().set_state(Loading); - })); + }); }) ); @@ -298,24 +313,24 @@ impl Window { match state { Loading => { - self.backend - .get_persons(clone!(@strong self as self_ => move |persons| { - let persons = persons.unwrap(); - self_.backend.get_ensembles(clone!(@strong self_ => move |ensembles| { - let ensembles = ensembles.unwrap(); - let mut poes: Vec = Vec::new(); + let self_ = self.clone(); + let c = glib::MainContext::default(); + c.spawn_local(async move { + let persons = self_.backend.get_persons().await.unwrap(); + let ensembles = self_.backend.get_ensembles().await.unwrap(); - for person in &persons { - poes.push(PersonOrEnsemble::Person(person.clone())); - } + let mut poes: Vec = Vec::new(); - for ensemble in &ensembles { - poes.push(PersonOrEnsemble::Ensemble(ensemble.clone())); - } + for person in &persons { + poes.push(PersonOrEnsemble::Person(person.clone())); + } - self_.clone().set_state(Selection(poes)); - })); - })); + for ensemble in &ensembles { + poes.push(PersonOrEnsemble::Ensemble(ensemble.clone())); + } + + self_.clone().set_state(Selection(poes)); + }); self.sidebar_stack.set_visible_child_name("loading"); self.main_stack.set_visible_child_name("empty_screen"); @@ -392,19 +407,26 @@ impl Window { self.overview_header_menu_button.set_menu_model(Some(&menu)); - self.backend.get_work_descriptions( - person.id, - clone!(@strong self as self_, @strong poe => move |works| { - let works = works.unwrap(); - self_.backend.get_recordings_for_person( - person.id, - clone!(@strong self_, @strong poe => move |recordings| { - let recordings = recordings.unwrap(); - self_.clone().set_state(OverviewScreen(poe.clone(), works.clone(), recordings, String::from(""))); - }), - ); - }), - ); + let self_ = self.clone(); + let c = glib::MainContext::default(); + c.spawn_local(async move { + let works = self_ + .backend + .get_work_descriptions(person.id) + .await + .unwrap(); + let recordings = self_ + .backend + .get_recordings_for_person(person.id) + .await + .unwrap(); + self_.clone().set_state(OverviewScreen( + poe.clone(), + works.clone(), + recordings, + String::from(""), + )); + }); } PersonOrEnsemble::Ensemble(ensemble) => { self.overview_header.set_title(Some(&ensemble.name)); @@ -427,13 +449,21 @@ impl Window { self.overview_header_menu_button.set_menu_model(Some(&menu)); - self.backend.get_recordings_for_ensemble( - ensemble.id, - clone!(@strong self as self_ => move |recordings| { - let recordings = recordings.unwrap(); - self_.clone().set_state(OverviewScreen(poe.clone(), Vec::new(), recordings, String::from(""))); - }), - ); + let self_ = self.clone(); + let c = glib::MainContext::default(); + c.spawn_local(async move { + let recordings = self_ + .backend + .get_recordings_for_ensemble(ensemble.id) + .await + .unwrap(); + self_.clone().set_state(OverviewScreen( + poe.clone(), + Vec::new(), + recordings, + String::from(""), + )); + }); } } @@ -552,13 +582,21 @@ impl Window { .set_title(Some(&work.composer.name_fl())); self.work_details_header.set_subtitle(Some(&work.title)); - self.backend.get_recordings_for_work( - work.id, - clone!(@strong self as self_ => move |recordings| { - let recordings = recordings.unwrap(); - self_.clone().set_state(WorkScreen(poe.clone(), work.clone(), recordings, String::new())); - }), - ); + let c = glib::MainContext::default(); + let self_ = self.clone(); + c.spawn_local(async move { + let recordings = self_ + .backend + .get_recordings_for_work(work.id) + .await + .unwrap(); + self_.clone().set_state(WorkScreen( + poe.clone(), + work.clone(), + recordings, + String::new(), + )); + }); self.work_details_stack.set_visible_child_name("loading"); self.main_stack