1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
3
4/// Code from https://doc.rust-lang.org/std/task/trait.Wake.html#examples
5mod executor {
6 use std::future::Future;
7 use std::sync::Arc;
8 use std::task::{Context, Poll, Wake};
9 use std::thread::{self, Thread};
10
11 /// A waker that wakes up the current thread when called.
12 struct ThreadWaker(Thread);
13
14 impl Wake for ThreadWaker {
15 fn wake(self: Arc<Self>) {
16 self.0.unpark();
17 }
18 }
19
20 /// Run a future to completion on the current thread.
21 pub fn block_on<T>(fut: impl Future<Output = T>) -> T {
22 // Pin the future so it can be polled.
23 let mut fut = Box::pin(fut);
24
25 // Create a new context to be passed to the future.
26 let t = thread::current();
27 let waker = Arc::new(ThreadWaker(t)).into();
28 let mut cx = Context::from_waker(&waker);
29
30 // Run the future to completion.
31 loop {
32 match fut.as_mut().poll(&mut cx) {
33 Poll::Ready(res) => return res,
34 Poll::Pending => thread::park(),
35 }
36 }
37 }
38}
39
40#[test]
41fn main() {
42 i_slint_backend_testing::init_with_event_loop();
43
44 slintResult<(), EventLoopError>::invoke_from_event_loop(|| {
45 let handle: JoinHandle = slint::spawn_local(fut:async { String::from("Hello") }).unwrap();
46 slint::spawn_local(fut:async move { panic!("Aborted task") }).unwrap().abort();
47 let handle2: JoinHandle = slint::spawn_local(fut:async move { handle.await + ", World" }).unwrap();
48 std::thread::spawn(move || {
49 let x: String = executor::block_on(fut:handle2);
50 assert_eq!(x, "Hello, World");
51 slint::quit_event_loop().unwrap();
52 });
53 })
54 .unwrap();
55 slint::run_event_loop().unwrap();
56}
57
58#[test]
59fn with_context() {
60 use i_slint_core::SlintContext;
61 let ctx: SlintContext = SlintContext::new(platform:Box::new(i_slint_backend_testing::TestingBackend::new()));
62 let handle: JoinHandle = ctx.spawn_local(fut:async { String::from("Hello") }).unwrap();
63 ctx.spawn_local(fut:async move { panic!("Aborted task") }).unwrap().abort();
64 let handle2: JoinHandle = ctx.spawn_local(fut:async move { handle.await + ", World" }).unwrap();
65 let proxy: Box = ctx.event_loop_proxy().unwrap();
66 std::thread::spawn(move || {
67 let x: String = executor::block_on(fut:handle2);
68 assert_eq!(x, "Hello, World");
69 proxy.quit_event_loop().unwrap();
70 });
71 ctx.run_event_loop().unwrap()
72}
73