use std::sync::Arc;
use std::{fmt, time::Duration};
use crate::Result;
use super::{Device, RetirementTicket, TimestampPair};
#[derive(Clone)]
#[must_use]
pub struct Event {
device: Arc<Device>,
epoch: u64,
retirement: RetirementTicket,
timing: Option<TimestampPair>,
}
impl Event {
pub(crate) fn same_as(&self, other: &Self) -> bool {
self.epoch == other.epoch && self.device.same_as(&other.device)
}
pub(crate) fn follows_or_equals(&self, other: &Self) -> bool {
self.epoch >= other.epoch && self.device.same_as(&other.device)
}
pub(super) const fn new(
device: Arc<Device>,
epoch: u64,
retirement: RetirementTicket,
timing: Option<TimestampPair>,
) -> Self {
Self {
device,
epoch,
retirement,
timing,
}
}
pub(super) const fn epoch(&self) -> u64 {
self.epoch
}
pub(in crate::runtime) fn comes_from(&self, device: &Arc<Device>) -> bool {
self.device.same_as(device)
}
pub(in crate::runtime) fn retain_until_complete<T>(&self, value: T)
where
T: Send + 'static,
{
self.retirement.retain_until_complete(value);
}
pub fn is_complete(&self) -> Result<bool> {
self.retirement.check_failure()?;
let complete = self.device.is_complete(self.epoch)?;
self.retirement.check_failure()?;
Ok(complete)
}
pub fn wait(&self) -> Result<()> {
self.retirement.wait()
}
pub fn try_device_duration(&self) -> Result<Option<Duration>> {
let Some(timing) = &self.timing else {
return Err(crate::Error::failed_precondition(
"event was not produced by a timed submission",
));
};
if !self.is_complete()? {
return Ok(None);
}
Ok(Some(timing.duration()?))
}
pub fn device_duration(&self) -> Result<Duration> {
let Some(timing) = &self.timing else {
return Err(crate::Error::failed_precondition(
"event was not produced by a timed submission",
));
};
self.wait()?;
timing.duration()
}
}
impl fmt::Debug for Event {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("Event")
.field("epoch", &self.epoch)
.finish_non_exhaustive()
}
}