wowlab_engine_domain/rotation/buffer/dense/
dump.rs1use std::fmt::Write as _;
2
3use wowlab_types::sim::AuraOn;
4
5use super::DenseBuffer;
6
7const PET_AURA_SORT_RANK: u8 = 2;
8
9impl DenseBuffer {
10 pub fn dump(&self) -> String {
12 let mut out = String::with_capacity(1024);
14
15 out.push_str("[player]\n");
16 self.player().dump_fields(&mut out);
17 out.push_str("[combat]\n");
18 self.combat().dump_fields(&mut out);
19
20 dump_keyed(
21 &mut out,
22 "[cooldowns]\n",
23 sorted_by_key(
24 self.layout
25 .offsets
26 .slots
27 .cooldowns
28 .keys()
29 .copied()
30 .collect(),
31 |key| key.0,
32 ),
33 |out, &key| {
34 if let Some(handle) = self.layout.cooldown_handle(key) {
35 let value = self.cooldown_at(handle);
36 let _ = writeln!(out, " spell={}", key.0);
37
38 value.dump_fields(out);
39 }
40 },
41 );
42 dump_keyed(
43 &mut out,
44 "[auras]\n",
45 sorted_by_key(
46 self.layout.offsets.slots.auras.keys().copied().collect(),
47 |key| {
48 let on = match key.on() {
49 AuraOn::Player => 0,
50 AuraOn::Target => 1,
51 AuraOn::Pet => PET_AURA_SORT_RANK,
52 };
53
54 (key.aura(), key.source(), key.affected(), on)
55 },
56 ),
57 |out, &key| {
58 if let Some(handle) = self.layout.aura_handle(key) {
59 let value = self.aura_at(handle);
60 let _ = writeln!(
61 out,
62 " aura={} source={:?} affected={:?} on={:?}",
63 key.aura().0,
64 key.source(),
65 key.affected(),
66 key.on()
67 );
68
69 value.dump_fields(out);
70 }
71 },
72 );
73 dump_keyed(
74 &mut out,
75 "[spells]\n",
76 sorted_by_key(
77 self.layout.offsets.slots.spells.keys().copied().collect(),
78 |key| key.0,
79 ),
80 |out, &key| {
81 if let Some(handle) = self.layout.spell_handle(key) {
82 let value = self.spell_at(handle);
83 let _ = writeln!(out, " spell={}", key.0);
84
85 value.dump_fields(out);
86 }
87 },
88 );
89 dump_keyed(
90 &mut out,
91 "[talents]\n",
92 sorted_by_key(
93 self.layout.offsets.slots.talents.keys().cloned().collect(),
94 Clone::clone,
95 ),
96 |out, key| {
97 if let Some(handle) = self.layout.talent_handle(key) {
98 let value = self.talent_at(handle);
99 let _ = writeln!(out, " talent={key}");
100
101 value.dump_fields(out);
102 }
103 },
104 );
105 dump_keyed(
106 &mut out,
107 "[resources]\n",
108 sorted_by_key(
109 self.layout
110 .offsets
111 .slots
112 .resources
113 .keys()
114 .copied()
115 .collect(),
116 |key| u8::from(*key),
117 ),
118 |out, &key| {
119 if let Some(handle) = self.layout.resource_handle(key) {
120 let value = self.resource_at(handle);
121 let _ = writeln!(out, " {key}");
122
123 value.dump_fields(out);
124 }
125 },
126 );
127 dump_keyed(
128 &mut out,
129 "[units]\n",
130 sorted_by_key(
131 self.layout.offsets.slots.units.keys().cloned().collect(),
132 Clone::clone,
133 ),
134 |out, key| {
135 if let Some(handle) = self.layout.unit_handle(key) {
136 let value = self.unit_at(handle);
137 let _ = writeln!(out, " role={key}");
138
139 value.dump_fields(out);
140 }
141 },
142 );
143 dump_keyed(
144 &mut out,
145 "[standalone]\n",
146 sorted_by_key(
147 self.layout
148 .offsets
149 .standalone
150 .iter()
151 .map(|(&id, &offset)| (id.get(), offset.as_usize()))
152 .collect(),
153 |&(descriptor_id, _)| descriptor_id,
154 ),
155 |out, &(descriptor_id, offset)| {
156 let _ = writeln!(out, " descriptor_id={descriptor_id:<6} offset={offset}");
157 },
158 );
159
160 out
161 }
162}
163
164fn dump_keyed<K>(out: &mut String, section: &str, keys: Vec<K>, emit: impl Fn(&mut String, &K)) {
165 if keys.is_empty() {
166 return;
167 }
168
169 out.push_str(section);
170
171 for key in keys {
172 emit(out, &key);
173 }
174}
175
176fn sorted_by_key<K, S>(mut values: Vec<K>, key: impl Fn(&K) -> S) -> Vec<K>
177where
178 S: Ord,
179{
180 values.sort_by_key(key);
181
182 values
183}