srs2dge_core/target/
belt.rs

1use 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
14//
15
16pub 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
29//
30
31impl 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}