Closed idanarye closed 3 years ago
The API I want is something like this:
ctx.spawn(async move {
// Do stuff inside Actix
woab::outside(async {
// Do stuff outside Actix
}).await;
// do stuff inside Actix again
}.into_actor(self))
This will be based on a little more manual function:
async fn outside(fut: Future) {
woab::wake_from_outside(|waker| {
glib::MainContext::ref_thread_default().spawn_local(async move {
fut.await;
waker.wake();
});
}).await;
}
(Not actual Rust code (don't have all the required annotations), I'll try to get return values to work, and I'll also try to ensure woab::outside
does not require move
)
The reason for wake_from_outside
is so we can write things like
let button: gtk::Button = get_the_button_from_somewhere();
ctx.spawn(async move {
woab::wake_from_outside(|waker| {
button.connect_clicked(|_| {
waker.wake();
});
}).await;
// Do things after the button was clicked
}.into_actor(self))
Actually, I think maybe woab::wake_from_outside
should not actually go outside Actix:
move
.schedule_outside
(or spawn_outside
, which I'm probably going to replace schedule_outside
with)Also, instead of using a waker I can probably just use Tokio's oneshot
- which will also make it easy to pass back data on wakeup. This will also make it trivial to pass back the async
block's result in woab::outside
.
In #28 @piegamesde mentioned a usecase where an actor would spawn a future on the GTK loop (specifically - outside Actix) that would interact with GTK and when done send a message back to the actor. This future cannot use Actix'
ActorFuture
to retake the actor, because that would make the future execute inside Actix and thus it won't be able to do GTK operations that trigger signals - unless it useswoab::schedule_outside
, which does offer a way to get back to the future.We need a way to allow futures spawned on the Actix loop to yield execution to something outside the Actix loop and
await
for that something to finish.