-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsync.rs
More file actions
92 lines (77 loc) · 2.62 KB
/
sync.rs
File metadata and controls
92 lines (77 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use core::panic;
use std::{sync::{Arc, Mutex}, borrow::Borrow, cell::RefCell};
use wasm_bindgen::prelude::*;
use js_sys::Promise;
use wasm_bindgen_futures::{JsFuture, future_to_promise};
use futures::channel::oneshot;
use bevy_ecs::world::World;
pub fn execute_world_tasks(world: &mut World) {
EXECUTION_CHANNEL.with(|rx| {
let rx = &rx.borrow().1;
while let Ok(task) = rx.borrow().try_recv() {
(task.task)(world);
}
});
}
struct WorldTask {
task: Box<dyn FnOnce(&mut World) + 'static>,
}
// Convert a oneshot::Receiver into a JavaScript Promise
fn rx_to_promise(rx: oneshot::Receiver<()>) -> Promise {
future_to_promise(async move {
match rx.await {
Ok(_) => Ok(JsValue::NULL),
Err(e) => panic!("rx_to_promise: Panic with {e:?}"),
}
})
}
pub async fn execute_in_world<
T: 'static,
F: FnOnce(&mut World) -> T + 'static,
>(
task: F,
) -> T {
let (tx, rx) = oneshot::channel();
let output = Arc::new(Mutex::new(None));
let output_cloned = output.clone();
let boxed_task = Box::new(move |world: &mut World| {
let mut output = output_cloned.lock().unwrap();
*output = Some(task(world));
tx.send(()).expect("Failed to send task complete.");
});
let world_task = WorldTask { task: boxed_task };
{
EXECUTION_CHANNEL.with(|channel| {
channel.borrow().0.borrow_mut().send(world_task).unwrap();
});
}
JsFuture::from(rx_to_promise(rx)).await.unwrap();
let mut output = output.lock().unwrap();
output.take().unwrap()
}
use std::sync::mpsc::{ Sender, Receiver };
thread_local! {
pub static EXECUTION_CHANNEL: (RefCell<Sender<WorldTask>>, RefCell<Receiver<WorldTask>>) = {
let (tx, rx) = std::sync::mpsc::channel();
(RefCell::new(tx), RefCell::new(rx))
};
}
pub enum ExecutionChannel {
FrameStart,
FrameEnd,
}
// For native
// lazy_static::lazy_static! {
// static ref CHANNEL_FRAME_START: (Mutex<std::sync::mpsc::Sender<WorldTask>>, Mutex<std::sync::mpsc::Receiver<WorldTask>>) = {
// let (rx, tx) = std::sync::mpsc::channel();
// (Mutex::new(rx), Mutex::new(tx))
// };
// static ref CHANNEL_FRAME_END: (Mutex<std::sync::mpsc::Sender<WorldTask>>, Mutex<std::sync::mpsc::Receiver<WorldTask>>) = {
// let (rx, tx) = std::sync::mpsc::channel();
// (Mutex::new(rx), Mutex::new(tx))
// };
// static ref CHANNEL_RENDER_APP: (Mutex<std::sync::mpsc::Sender<WorldTask>>, Mutex<std::sync::mpsc::Receiver<WorldTask>>) = {
// let (rx, tx) = std::sync::mpsc::channel();
// (Mutex::new(rx), Mutex::new(tx))
// };
// }