diff --git a/src/dialogs/login_dialog.rs b/src/dialogs/login_dialog.rs index 0881493..5e7f4d9 100644 --- a/src/dialogs/login_dialog.rs +++ b/src/dialogs/login_dialog.rs @@ -52,25 +52,21 @@ impl Screen<(), LoginData> for LoginDialog { password: this.password_entry.get_text().unwrap().to_string(), }; - let c = glib::MainContext::default(); - let clone = this.clone(); - c.spawn_local(async move { - clone.handle.backend.set_login_data(data.clone()).await.unwrap(); - if clone.handle.backend.login().await.unwrap() { - clone.handle.pop(Some(data)); + spawn!(@clone this, async move { + this.handle.backend.set_login_data(data.clone()).await.unwrap(); + if this.handle.backend.login().await.unwrap() { + this.handle.pop(Some(data)); } else { - clone.widget.set_visible_child_name("content"); - clone.info_bar.set_revealed(true); + this.widget.set_visible_child_name("content"); + this.info_bar.set_revealed(true); } }); })); register_button.connect_clicked(clone!(@weak this => move |_| { - let context = glib::MainContext::default(); - let clone = this.clone(); - context.spawn_local(async move { - if let Some(data) = push!(clone.handle, RegisterDialog).await { - clone.handle.pop(Some(data)); + spawn!(@clone this, async move { + if let Some(data) = push!(this.handle, RegisterDialog).await { + this.handle.pop(Some(data)); } }); })); diff --git a/src/dialogs/register.rs b/src/dialogs/register.rs index 012ca34..5bfbeca 100644 --- a/src/dialogs/register.rs +++ b/src/dialogs/register.rs @@ -63,13 +63,11 @@ impl Screen<(), LoginData> for RegisterDialog { } else { this.widget.set_visible_child_name("loading"); - let context = glib::MainContext::default(); - let clone = this.clone(); - context.spawn_local(async move { - let username = clone.username_entry.get_text().unwrap().to_string(); - let email = clone.email_entry.get_text().unwrap().to_string(); - let captcha_id = clone.captcha_id.borrow().clone().unwrap(); - let answer = clone.captcha_entry.get_text().unwrap().to_string(); + spawn!(@clone this, async move { + let username = this.username_entry.get_text().unwrap().to_string(); + let email = this.email_entry.get_text().unwrap().to_string(); + let captcha_id = this.captcha_id.borrow().clone().unwrap(); + let answer = this.captcha_entry.get_text().unwrap().to_string(); let email = if email.len() == 0 { None @@ -86,15 +84,15 @@ impl Screen<(), LoginData> for RegisterDialog { }; // TODO: Handle errors. - if clone.handle.backend.register(registration).await.unwrap() { + if this.handle.backend.register(registration).await.unwrap() { let data = LoginData { username, password, }; - clone.handle.pop(Some(data)); + this.handle.pop(Some(data)); } else { - clone.widget.set_visible_child_name("content"); + this.widget.set_visible_child_name("content"); } }); } @@ -102,13 +100,11 @@ impl Screen<(), LoginData> for RegisterDialog { // Initialize - let context = glib::MainContext::default(); - let clone = this.clone(); - context.spawn_local(async move { - let captcha = clone.handle.backend.get_captcha().await.unwrap(); - clone.captcha_row.set_title(Some(&captcha.question)); - clone.captcha_id.replace(Some(captcha.id)); - clone.widget.set_visible_child_name("content"); + spawn!(@clone this, async move { + let captcha = this.handle.backend.get_captcha().await.unwrap(); + this.captcha_row.set_title(Some(&captcha.question)); + this.captcha_id.replace(Some(captcha.id)); + this.widget.set_visible_child_name("content"); }); this diff --git a/src/macros.rs b/src/macros.rs index 04ea01f..a449224 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -22,3 +22,40 @@ macro_rules! push { $handle.push::<_, _, $screen>($input) }; } + +/// Spawn a future on the GLib MainContext. +/// +/// This can be invoked in the following forms: +/// +/// 1. For spawning a future and nothing more: +/// +/// ``` +/// spawn!(async { +/// // Some code +/// }); +/// +/// 2. For spawning a future and cloning some data, that will be accessible +/// from the async code: +/// +/// ``` +/// spawn!(@clone data: Rc<_>, async move { +/// // Some code +/// }); +#[macro_export] +macro_rules! spawn { + ($future:expr) => { + { + let context = glib::MainContext::default(); + context.spawn_local($future); + + } + }; + (@clone $data:ident, $future:expr) => { + { + let context = glib::MainContext::default(); + let $data = Rc::clone(&$data); + context.spawn_local($future); + + } + }; +}