use crate::error::Result;
pub struct Ticket {
inner: Option<TicketInner>,
}
enum TicketInner {
#[cfg(feature = "vulkan")]
Vulkan(crate::backend::vulkan::VulkanTicket),
#[cfg(feature = "cuda")]
Cuda(crate::backend::cuda::CudaTicket),
}
impl Ticket {
#[cfg(feature = "vulkan")]
pub(crate) const fn new_vulkan(ticket: crate::backend::vulkan::VulkanTicket) -> Self {
Self {
inner: Some(TicketInner::Vulkan(ticket)),
}
}
#[cfg(feature = "cuda")]
pub(crate) const fn new_cuda(ticket: crate::backend::cuda::CudaTicket) -> Self {
Self {
inner: Some(TicketInner::Cuda(ticket)),
}
}
pub fn wait(mut self) -> Result<()> {
self.wait_inner()
}
pub fn is_ready(&self) -> Result<bool> {
match self.inner.as_ref().expect("ticket already consumed") {
#[cfg(feature = "vulkan")]
TicketInner::Vulkan(t) => t.is_ready(),
#[cfg(feature = "cuda")]
TicketInner::Cuda(t) => Ok(t.is_ready()),
}
}
fn wait_inner(&mut self) -> Result<()> {
if let Some(inner) = self.inner.take() {
match inner {
#[cfg(feature = "vulkan")]
TicketInner::Vulkan(t) => t.wait()?,
#[cfg(feature = "cuda")]
TicketInner::Cuda(t) => t.wait()?,
}
}
Ok(())
}
}
impl Drop for Ticket {
fn drop(&mut self) {
let _ = self.wait_inner();
}
}
impl std::fmt::Debug for Ticket {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Ticket")
.field("pending", &self.inner.is_some())
.finish_non_exhaustive()
}
}