srs2dge_core/target/
belt.rs1use main_game_loop::as_async;
2use std::sync::Arc;
3use wgpu::{util::StagingBelt, Device};
4
5#[cfg(not(target_arch = "wasm32"))]
6use {
7 std::{
8 sync::mpsc::{channel, Sender, TryRecvError},
9 thread::JoinHandle,
10 },
11 wgpu::Maintain,
12};
13
14pub struct Belt {
17 belt: Option<StagingBelt>,
18
19 #[cfg(not(target_arch = "wasm32"))]
20 _poll: PollThread,
21}
22
23#[cfg(not(target_arch = "wasm32"))]
24struct PollThread {
25 poll_thread: Option<JoinHandle<()>>,
26 poll_stop: Sender<()>,
27}
28
29impl Belt {
32 #[cfg(not(target_arch = "wasm32"))]
33 pub fn new(device: Arc<Device>) -> Self {
34 let belt = Some(StagingBelt::new(128));
35 let _poll = PollThread::new(device);
36
37 Self { belt, _poll }
38 }
39
40 #[cfg(target_arch = "wasm32")]
41 pub fn new(_: Arc<Device>) -> Self {
42 let belt = Some(StagingBelt::new(128));
43
44 Self { belt }
45 }
46
47 pub fn get(&mut self) -> StagingBelt {
48 self.belt
49 .take()
50 .expect("Cannot start a second frame when the first hasn't been finished yet")
51 }
52
53 pub fn set(&mut self, mut belt: StagingBelt) {
54 as_async(belt.recall());
55 self.belt = Some(belt);
56 }
57}
58
59#[cfg(not(target_arch = "wasm32"))]
60impl PollThread {
61 pub fn new(device: Arc<Device>) -> Self {
62 let (poll_stop, poll_listen) = channel();
63 let poll_thread = Some(std::thread::spawn(move || loop {
64 match poll_listen.try_recv() {
65 Ok(()) | Err(TryRecvError::Disconnected) => break,
66 Err(TryRecvError::Empty) => {}
67 }
68
69 device.poll(Maintain::Wait);
70 #[cfg(target_arch = "wasm32")]
71 thread::yield_now();
72 }));
73
74 Self {
75 poll_stop,
76 poll_thread,
77 }
78 }
79}
80
81#[cfg(not(target_arch = "wasm32"))]
82impl Drop for PollThread {
83 fn drop(&mut self) {
84 self.poll_stop.send(()).unwrap();
85 self.poll_thread
86 .take()
87 .expect("Engine dropped twice")
88 .join()
89 .unwrap();
90 }
91}