use std::sync::{
atomic::{AtomicU64, Ordering},
Arc,
};
#[derive(Default, Clone)]
pub struct ProcFramesNotif {
inner: Arc<ProcNotifInner>,
}
#[derive(Default)]
struct ProcNotifInner {
frames_processed: AtomicU64,
old_frames: AtomicU64,
}
impl ProcFramesNotif {
#[inline]
pub(crate) fn add_frames(&self, frames: u64) {
self.inner
.frames_processed
.fetch_add(frames, Ordering::Relaxed);
}
#[inline]
pub fn peek(&self) -> bool {
self.inner.old_frames.load(Ordering::Relaxed)
< self.inner.frames_processed.load(Ordering::Relaxed)
}
#[inline]
pub fn clear(&self) {
self.inner.frames_processed.store(0, Ordering::Relaxed);
self.inner.old_frames.store(0, Ordering::Relaxed);
}
#[inline]
pub fn take_delta(&self) -> u64 {
let cur = self.inner.frames_processed.load(Ordering::Relaxed);
let delta = cur.saturating_sub(self.inner.old_frames.load(Ordering::Relaxed));
self.inner.old_frames.store(cur, Ordering::Relaxed);
delta
}
#[inline]
pub fn take_with<F: FnOnce(u64)>(&self, f: F) {
let delta = self.take_delta();
if delta != 0 {
f(delta);
}
}
}