weiss_core/env/
debug_events.rs1use crate::replay::ReplayEvent;
2
3use super::GameEnv;
4
5pub(crate) struct EventRing {
7 capacity: usize,
8 events: Vec<ReplayEvent>,
9 next: usize,
10 full: bool,
11}
12
13impl EventRing {
14 pub(crate) fn new(capacity: usize) -> Self {
16 let mut events = Vec::with_capacity(capacity);
17 events.reserve(capacity);
18 Self {
19 capacity,
20 events,
21 next: 0,
22 full: false,
23 }
24 }
25
26 pub(crate) fn clear(&mut self) {
28 self.events.clear();
29 self.next = 0;
30 self.full = false;
31 }
32
33 pub(crate) fn push(&mut self, event: ReplayEvent) {
35 if self.capacity == 0 {
36 return;
37 }
38 if self.events.len() < self.capacity {
39 self.events.push(event);
40 if self.events.len() == self.capacity {
41 self.full = true;
42 self.next = 0;
43 }
44 } else {
45 self.events[self.next] = event;
46 self.next = (self.next + 1) % self.capacity;
47 }
48 }
49
50 pub(crate) fn len(&self) -> usize {
52 if self.capacity == 0 {
53 0
54 } else if self.full {
55 self.capacity
56 } else {
57 self.events.len()
58 }
59 }
60
61 pub(crate) fn snapshot_codes<F: Fn(&ReplayEvent) -> u32>(
65 &self,
66 out: &mut [u32],
67 code_fn: F,
68 ) -> usize {
69 let len = self.len();
70 if len == 0 {
71 for slot in out.iter_mut() {
72 *slot = 0;
73 }
74 return 0;
75 }
76 let cap = self.capacity;
77 for (i, slot) in out.iter_mut().enumerate() {
78 if i >= len {
79 *slot = 0;
80 continue;
81 }
82 let idx = if self.full { (self.next + i) % cap } else { i };
83 *slot = code_fn(&self.events[idx]);
84 }
85 len
86 }
87
88 pub(crate) fn snapshot_events(&self) -> Vec<ReplayEvent> {
90 let len = self.len();
91 if len == 0 {
92 return Vec::new();
93 }
94 let cap = self.capacity;
95 let mut out = Vec::with_capacity(len);
96 for i in 0..len {
97 let idx = if self.full { (self.next + i) % cap } else { i };
98 out.push(self.events[idx].clone());
99 }
100 out
101 }
102}
103
104pub(crate) fn event_code(event: &ReplayEvent) -> u32 {
106 use crate::events::Event;
107 match event {
108 Event::Draw { .. } => 1,
109 Event::Damage { .. } => 2,
110 Event::DamageCancel { .. } => 3,
111 Event::DamageIntent { .. } => 4,
112 Event::DamageModifierApplied { .. } => 5,
113 Event::DamageModified { .. } => 6,
114 Event::DamageCommitted { .. } => 7,
115 Event::ReversalCommitted { .. } => 8,
116 Event::Reveal { .. } => 9,
117 Event::TriggerQueued { .. } => 10,
118 Event::TriggerGrouped { .. } => 11,
119 Event::TriggerResolved { .. } => 12,
120 Event::TriggerCanceled { .. } => 13,
121 Event::TimingWindowEntered { .. } => 14,
122 Event::PriorityGranted { .. } => 15,
123 Event::PriorityPassed { .. } => 16,
124 Event::StackGroupPresented { .. } => 17,
125 Event::StackOrderChosen { .. } => 18,
126 Event::StackPushed { .. } => 19,
127 Event::StackResolved { .. } => 20,
128 Event::AutoResolveCapExceeded { .. } => 21,
129 Event::WindowAdvanced { .. } => 22,
130 Event::ChoicePresented { .. } => 23,
131 Event::ChoicePageChanged { .. } => 24,
132 Event::ChoiceMade { .. } => 25,
133 Event::ChoiceAutopicked { .. } => 26,
134 Event::ChoiceSkipped { .. } => 27,
135 Event::ZoneMove { .. } => 28,
136 Event::ControlChanged { .. } => 29,
137 Event::ModifierAdded { .. } => 30,
138 Event::ModifierRemoved { .. } => 31,
139 Event::Concede { .. } => 32,
140 Event::Play { .. } => 33,
141 Event::PlayEvent { .. } => 34,
142 Event::PlayClimax { .. } => 35,
143 Event::Trigger { .. } => 36,
144 Event::Attack { .. } => 37,
145 Event::AttackType { .. } => 38,
146 Event::Counter { .. } => 39,
147 Event::Clock { .. } => 40,
148 Event::Shuffle { .. } => 41,
149 Event::Refresh { .. } => 42,
150 Event::RefreshPenalty { .. } => 43,
151 Event::LevelUpChoice { .. } => 44,
152 Event::Encore { .. } => 45,
153 Event::Stand { .. } => 46,
154 Event::EndTurn { .. } => 47,
155 Event::Terminal { .. } => 48,
156 }
157}
158
159impl GameEnv {
160 pub fn debug_event_ring_codes(&self, viewer: u8, out: &mut [u32]) -> u16 {
162 let Some(rings) = self.debug_event_ring.as_ref() else {
163 for slot in out.iter_mut() {
164 *slot = 0;
165 }
166 return 0;
167 };
168 let ring = &rings[viewer as usize % 2];
169 let count = ring.snapshot_codes(out, event_code);
170 count as u16
171 }
172
173 pub fn debug_event_ring_snapshot(&self, viewer: u8) -> Vec<ReplayEvent> {
175 let Some(rings) = self.debug_event_ring.as_ref() else {
176 return Vec::new();
177 };
178 rings[viewer as usize % 2].snapshot_events()
179 }
180}