pebble/rendering/sync.rs
1/// The sending half of a one-shot backend initialisation channel.
2///
3/// Pass this to [`Backend::init`](crate::rendering::backend::Backend::init) so
4/// the (potentially async) init task can deliver the finished backend.
5pub struct InitSender<T>(oneshot::Sender<T>);
6
7impl<T: 'static + Send> InitSender<T> {
8 /// Send the completed backend to the waiting receiver.
9 ///
10 /// Logs a warning if the receiver was already dropped.
11 pub fn send(self, value: T) {
12 if self.0.send(value).is_err() {
13 tracing::warn!("GPU Backend finished init but receiver was dropped");
14 }
15 }
16}
17
18/// The receiving half of a one-shot backend initialisation channel.
19pub struct InitReceiver<T>(oneshot::Receiver<T>);
20
21impl<T: 'static + Send> InitReceiver<T> {
22 /// Non-blocking poll for the completed backend.
23 pub fn try_recv(&mut self) -> Result<T, oneshot::TryRecvError> {
24 self.0.try_recv()
25 }
26
27 /// Block the current thread until the completed backend arrives (or the
28 /// sender is dropped without sending one). Only meaningful on targets
29 /// that can actually block a thread — never call this on `wasm32`.
30 pub fn recv(self) -> Result<T, oneshot::RecvError> {
31 self.0.recv()
32 }
33}
34
35/// Create a matched [`InitSender`] / [`InitReceiver`] pair for communicating a
36/// finished backend from its init task back to the main loop.
37pub fn init_channel<T: 'static + Send>() -> (InitSender<T>, InitReceiver<T>) {
38 let (tx, rx) = oneshot::channel();
39 (InitSender(tx), InitReceiver(rx))
40}