#[cfg(not(target_os = "none"))]
use core::cell::RefCell;
use dotzuki_engine::battle::stack::{EffectId, Event, RelayVar};
use crate::model::Op;
#[derive(Debug, Clone, PartialEq)]
pub struct TraceEvent {
pub effect: EffectId,
pub event: Event,
pub op: Op,
pub before: RelayVar,
pub after: RelayVar,
}
#[derive(Debug, Default, Clone)]
pub struct TraceSink {
pub events: Vec<TraceEvent>,
}
#[cfg(not(target_os = "none"))]
thread_local! {
static SINK: RefCell<Option<TraceSink>> = const { RefCell::new(None) };
}
#[cfg(target_os = "none")]
static mut SINK: Option<TraceSink> = None;
#[cfg_attr(target_os = "none", allow(unsafe_code, static_mut_refs))]
pub fn enable_trace() {
#[cfg(not(target_os = "none"))]
SINK.with(|s| *s.borrow_mut() = Some(TraceSink::default()));
#[cfg(target_os = "none")]
unsafe {
SINK = Some(TraceSink::default())
}
}
#[cfg_attr(target_os = "none", allow(unsafe_code, static_mut_refs))]
pub fn take_trace() -> Option<TraceSink> {
#[cfg(not(target_os = "none"))]
{
SINK.with(|s| s.borrow_mut().take())
}
#[cfg(target_os = "none")]
{
unsafe { SINK.take() }
}
}
#[cfg_attr(target_os = "none", allow(unsafe_code, static_mut_refs))]
pub(crate) fn record(effect: EffectId, event: Event, op: &Op, before: RelayVar, after: RelayVar) {
#[cfg(not(target_os = "none"))]
SINK.with(|s| {
if let Some(sink) = s.borrow_mut().as_mut() {
sink.events.push(TraceEvent {
effect,
event,
op: op.clone(),
before,
after,
});
}
});
#[cfg(target_os = "none")]
unsafe {
if let Some(sink) = SINK.as_mut() {
sink.events.push(TraceEvent {
effect,
event,
op: op.clone(),
before,
after,
});
}
}
}