use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use scopeguard::defer;
use super::version::Version;
use crate::debug_correlation_id::DebugCorrelationId;
use crate::prelude::diagnostics::debug;
use crate::prelude::diagnostics::trace;
use crate::prelude::diagnostics::trace_span;
use crate::string::XString;
pub mod reactive_closure_builder;
struct ReactiveClosure<F> {
name: DebugCorrelationId<XString>,
reactive_closure: F,
last_version: AtomicUsize,
}
impl<F: Fn()> ReactiveClosure<F> {
fn call(&self, version: Version) {
let version = version.number();
let last_version = self.last_version.swap(version, SeqCst);
let _span = trace_span!("Call", closure = %self.name).entered();
if last_version < version {
defer!(trace!("End"));
trace!(last_version, version, "Start");
(self.reactive_closure)();
} else {
debug!(last_version, version, "Skip");
}
}
}
impl<F> Drop for ReactiveClosure<F> {
fn drop(&mut self) {
trace!(closure = %self.name, "ReactiveClosure dropped");
}
}