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 |
5 | mod 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 ] |
41 | fn 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 ] |
59 | fn 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 | |