use std::future::Future;
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::task::{Context, Poll, Waker};
#[derive(Clone)]
pub struct DevicePoller;
impl DevicePoller {
pub fn start(_device: Arc<wgpu::Device>) -> Self {
Self
}
pub fn request_poll(&self) {}
pub fn poll_complete(&self) {}
}
struct MapAsyncState {
result: Mutex<Option<Result<(), wgpu::BufferAsyncError>>>,
waker: Mutex<Option<Waker>>,
}
impl MapAsyncState {
fn new() -> Self {
Self {
result: Mutex::new(None),
waker: Mutex::new(None),
}
}
fn set_result(&self, result: Result<(), wgpu::BufferAsyncError>) {
*self.result.lock().expect("map_async state result lock") = Some(result);
if let Some(waker) = self
.waker
.lock()
.expect("map_async state waker lock")
.take()
{
waker.wake();
}
}
fn poll(&self, cx: &mut Context<'_>) -> Poll<Result<(), wgpu::BufferAsyncError>> {
let mut result = self.result.lock().expect("map_async state result lock");
if let Some(res) = result.take() {
return Poll::Ready(res);
}
*self.waker.lock().expect("map_async state waker lock") = Some(cx.waker().clone());
Poll::Pending
}
}
pub struct BufferMapAsyncFuture {
state: Arc<MapAsyncState>,
}
impl BufferMapAsyncFuture {
pub fn new(_poller: &DevicePoller, buffer: &wgpu::Buffer) -> Self {
let state = Arc::new(MapAsyncState::new());
let state_clone = state.clone();
buffer
.slice(..)
.map_async(wgpu::MapMode::Read, move |result| {
state_clone.set_result(result);
});
Self { state }
}
}
impl Future for BufferMapAsyncFuture {
type Output = Result<(), wgpu::BufferAsyncError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
self.state.poll(cx)
}
}
pub async fn request_adapter_async(
instance: &wgpu::Instance,
options: &wgpu::RequestAdapterOptions<'_, '_>,
) -> Result<wgpu::Adapter, wgpu::RequestAdapterError> {
instance.request_adapter(options).await
}
pub async fn request_device_async(
adapter: &wgpu::Adapter,
descriptor: &wgpu::DeviceDescriptor<'_>,
) -> Result<(wgpu::Device, wgpu::Queue), wgpu::RequestDeviceError> {
adapter.request_device(descriptor).await
}