Add macro to spawn futures

This commit is contained in:
Elias Projahn 2021-02-02 10:12:30 +01:00
parent 59171e705b
commit 23d260687c
3 changed files with 59 additions and 30 deletions

View file

@ -52,25 +52,21 @@ impl Screen<(), LoginData> for LoginDialog {
password: this.password_entry.get_text().unwrap().to_string(), password: this.password_entry.get_text().unwrap().to_string(),
}; };
let c = glib::MainContext::default(); spawn!(@clone this, async move {
let clone = this.clone(); this.handle.backend.set_login_data(data.clone()).await.unwrap();
c.spawn_local(async move { if this.handle.backend.login().await.unwrap() {
clone.handle.backend.set_login_data(data.clone()).await.unwrap(); this.handle.pop(Some(data));
if clone.handle.backend.login().await.unwrap() {
clone.handle.pop(Some(data));
} else { } else {
clone.widget.set_visible_child_name("content"); this.widget.set_visible_child_name("content");
clone.info_bar.set_revealed(true); this.info_bar.set_revealed(true);
} }
}); });
})); }));
register_button.connect_clicked(clone!(@weak this => move |_| { register_button.connect_clicked(clone!(@weak this => move |_| {
let context = glib::MainContext::default(); spawn!(@clone this, async move {
let clone = this.clone(); if let Some(data) = push!(this.handle, RegisterDialog).await {
context.spawn_local(async move { this.handle.pop(Some(data));
if let Some(data) = push!(clone.handle, RegisterDialog).await {
clone.handle.pop(Some(data));
} }
}); });
})); }));

View file

@ -63,13 +63,11 @@ impl Screen<(), LoginData> for RegisterDialog {
} else { } else {
this.widget.set_visible_child_name("loading"); this.widget.set_visible_child_name("loading");
let context = glib::MainContext::default(); spawn!(@clone this, async move {
let clone = this.clone(); let username = this.username_entry.get_text().unwrap().to_string();
context.spawn_local(async move { let email = this.email_entry.get_text().unwrap().to_string();
let username = clone.username_entry.get_text().unwrap().to_string(); let captcha_id = this.captcha_id.borrow().clone().unwrap();
let email = clone.email_entry.get_text().unwrap().to_string(); let answer = this.captcha_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();
let email = if email.len() == 0 { let email = if email.len() == 0 {
None None
@ -86,15 +84,15 @@ impl Screen<(), LoginData> for RegisterDialog {
}; };
// TODO: Handle errors. // TODO: Handle errors.
if clone.handle.backend.register(registration).await.unwrap() { if this.handle.backend.register(registration).await.unwrap() {
let data = LoginData { let data = LoginData {
username, username,
password, password,
}; };
clone.handle.pop(Some(data)); this.handle.pop(Some(data));
} else { } 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 // Initialize
let context = glib::MainContext::default(); spawn!(@clone this, async move {
let clone = this.clone(); let captcha = this.handle.backend.get_captcha().await.unwrap();
context.spawn_local(async move { this.captcha_row.set_title(Some(&captcha.question));
let captcha = clone.handle.backend.get_captcha().await.unwrap(); this.captcha_id.replace(Some(captcha.id));
clone.captcha_row.set_title(Some(&captcha.question)); this.widget.set_visible_child_name("content");
clone.captcha_id.replace(Some(captcha.id));
clone.widget.set_visible_child_name("content");
}); });
this this

View file

@ -22,3 +22,40 @@ macro_rules! push {
$handle.push::<_, _, $screen>($input) $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);
}
};
}