use crate::profiler::SpanAttribution;
use super::super::PassEvent;
#[derive(Debug, Clone, Copy)]
pub struct WalkTiming<Mark> {
open: Option<WalkSpan<Mark>>,
}
#[derive(Debug, Clone, Copy)]
struct WalkSpan<Mark> {
mark: Mark,
attribution: SpanAttribution,
}
impl<Mark> Default for WalkTiming<Mark> {
fn default() -> Self {
Self::new()
}
}
impl<Mark> WalkTiming<Mark> {
#[must_use]
pub const fn new() -> Self {
Self { open: None }
}
#[inline]
pub fn discard(&mut self) {
self.open = None;
}
#[inline]
pub fn begin(&mut self, event: &PassEvent<'_>, start: impl FnOnce() -> Option<Mark>) {
if !event.is_group_entry() {
return;
}
if let Some(mark) = start() {
self.open = Some(WalkSpan {
mark,
attribution: SpanAttribution::new()
.with_stage(event.pipeline.stage)
.with_pass(
(event.pipeline.passes.get(event.group.start)).map_or("", |pass| pass.name),
),
});
}
}
#[inline]
#[must_use]
pub fn end(&mut self, event: &PassEvent<'_>) -> Option<(Mark, SpanAttribution)> {
if !event.is_group_exit() {
return None;
}
self.open.take().map(|span| (span.mark, span.attribution))
}
}