Skip to content

Commit adc3260

Browse files
committed
add an example
1 parent 12af897 commit adc3260

File tree

1 file changed

+45
-8
lines changed

1 file changed

+45
-8
lines changed

crates/bevy_tasks/src/thread_executor.rs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,45 @@ use std::{
77
use async_executor::{Executor, Task};
88
use futures_lite::Future;
99

10-
/// An executor that can only be ticked on the thread it was instantiated on.
11-
#[derive(Debug)]
10+
/// An executor that can only be ticked on the thread it was instantiated on. But
11+
/// can spawn `Send` tasks from other threads.
12+
///
13+
/// # Example
14+
/// ```rust
15+
/// # use std::sync::{Arc, atomic::{AtomicI32, Ordering}};
16+
/// use bevy_tasks::ThreadExecutor;
17+
///
18+
/// let thread_executor = ThreadExecutor::new();
19+
/// let count = Arc::new(AtomicI32::new(0));
20+
///
21+
/// // create some owned values that can be moved into another thread
22+
/// let thread_executor_clone = thread_executor.clone();
23+
/// let count_clone = count.clone();
24+
/// let thread_spawner = thread_executor.spawner();
25+
///
26+
/// std::thread::scope(|scope| {
27+
/// scope.spawn(|| {
28+
/// // we cannot get the ticker from another thread
29+
/// let not_thread_ticker = thread_executor_clone.ticker();
30+
/// assert!(not_thread_ticker.is_none());
31+
///
32+
/// // but we can spawn tasks from another thread
33+
/// thread_spawner.spawn(async move {
34+
/// count_clone.fetch_add(1, Ordering::Relaxed);
35+
/// }).detach();
36+
/// });
37+
/// });
38+
///
39+
/// // the tasks do not make progress unless the executor is manually ticked
40+
/// assert_eq!(count.load(Ordering::Relaxed), 0);
41+
///
42+
/// // tick the ticker until task finishes
43+
/// let thread_ticker = thread_executor.ticker().unwrap();
44+
/// thread_ticker.try_tick();
45+
/// assert_eq!(count.load(Ordering::Relaxed), 1);
46+
/// ```
47+
///
48+
#[derive(Debug, Clone)]
1249
pub struct ThreadExecutor {
1350
executor: Arc<Executor<'static>>,
1451
thread_id: ThreadId,
@@ -24,7 +61,7 @@ impl Default for ThreadExecutor {
2461
}
2562

2663
impl ThreadExecutor {
27-
/// createa a new `[ThreadExecutor]`
64+
/// create a new `[ThreadExecutor]`
2865
pub fn new() -> Self {
2966
Self::default()
3067
}
@@ -54,23 +91,23 @@ impl ThreadExecutor {
5491
#[derive(Debug)]
5592
pub struct ThreadSpawner<'a>(Arc<Executor<'a>>);
5693
impl<'a> ThreadSpawner<'a> {
57-
/// Spawn a task on the main thread
94+
/// Spawn a task on the thread executor
5895
pub fn spawn<T: Send + 'a>(&self, future: impl Future<Output = T> + Send + 'a) -> Task<T> {
5996
self.0.spawn(future)
6097
}
6198
}
6299

63-
/// Used to tick the [`ThreadExecutor`]
100+
/// Used to tick the [`ThreadExecutor`]. The executor does not
101+
/// make progress unless it is manually ticked on the thread it was
102+
/// created on.
64103
#[derive(Debug)]
65104
pub struct ThreadTicker {
66105
executor: Arc<Executor<'static>>,
67106
// make type not send or sync
68107
_marker: PhantomData<*const ()>,
69108
}
70109
impl ThreadTicker {
71-
/// Tick the main thread executor.
72-
/// This needs to be called manually on the thread if it is not being used with
73-
/// a `[TaskPool::scope]`.
110+
/// Tick the thread executor.
74111
pub fn tick(&self) -> impl Future<Output = ()> + '_ {
75112
self.executor.tick()
76113
}

0 commit comments

Comments
 (0)