cbtop/bricks/panels/load/
mod.rs1mod render;
7mod types;
8
9pub use types::{ComputeBackend, LoadStats, WorkloadType};
10
11use crate::brick::{Brick, BrickAssertion, BrickBudget, BrickScore, BrickVerification};
12use presentar_terminal::Theme;
13use std::any::Any;
14
15pub struct LoadControlPanelBrick {
17 pub backend: ComputeBackend,
19 pub workload: WorkloadType,
21 pub intensity: f64,
23 pub problem_size: usize,
25 pub is_running: bool,
27 pub stats: LoadStats,
29 pub error: Option<String>,
31 pub selected_item: usize,
33 pub theme: Theme,
35 pub brick_score: Option<BrickScore>,
37 pub gflops: f64,
39}
40
41impl LoadControlPanelBrick {
42 pub fn new() -> Self {
44 Self {
45 backend: ComputeBackend::default(),
46 workload: WorkloadType::default(),
47 intensity: 50.0,
48 problem_size: 1024,
49 is_running: false,
50 stats: LoadStats::default(),
51 error: None,
52 selected_item: 0,
53 theme: Theme::tokyo_night(),
54 brick_score: None,
55 gflops: 0.0,
56 }
57 }
58
59 pub fn next_backend(&mut self) {
61 let idx = ComputeBackend::ALL
62 .iter()
63 .position(|&b| b == self.backend)
64 .unwrap_or(0);
65 self.backend = ComputeBackend::ALL[(idx + 1) % ComputeBackend::ALL.len()];
66 }
67
68 pub fn prev_backend(&mut self) {
70 let idx = ComputeBackend::ALL
71 .iter()
72 .position(|&b| b == self.backend)
73 .unwrap_or(0);
74 self.backend =
75 ComputeBackend::ALL[(idx + ComputeBackend::ALL.len() - 1) % ComputeBackend::ALL.len()];
76 }
77
78 pub fn next_workload(&mut self) {
80 let idx = WorkloadType::ALL
81 .iter()
82 .position(|&w| w == self.workload)
83 .unwrap_or(0);
84 self.workload = WorkloadType::ALL[(idx + 1) % WorkloadType::ALL.len()];
85 }
86
87 pub fn prev_workload(&mut self) {
89 let idx = WorkloadType::ALL
90 .iter()
91 .position(|&w| w == self.workload)
92 .unwrap_or(0);
93 self.workload =
94 WorkloadType::ALL[(idx + WorkloadType::ALL.len() - 1) % WorkloadType::ALL.len()];
95 }
96
97 pub fn increase_intensity(&mut self) {
99 self.intensity = (self.intensity + 5.0).min(100.0);
100 }
101
102 pub fn decrease_intensity(&mut self) {
104 self.intensity = (self.intensity - 5.0).max(0.0);
105 }
106
107 pub fn increase_size(&mut self) {
109 self.problem_size = (self.problem_size * 2).min(65536);
110 }
111
112 pub fn decrease_size(&mut self) {
114 self.problem_size = (self.problem_size / 2).max(64);
115 }
116
117 pub fn toggle_running(&mut self) {
119 self.is_running = !self.is_running;
120 if self.is_running {
121 self.stats = LoadStats::default();
122 self.error = None;
123 }
124 }
125
126 pub fn update_stats(&mut self, stats: LoadStats) {
128 self.stats = stats;
129 }
130
131 pub fn update_score(&mut self, score: BrickScore, gflops: f64) {
133 self.brick_score = Some(score);
134 self.gflops = gflops;
135 }
136
137 pub fn set_error(&mut self, error: String) {
139 self.error = Some(error);
140 self.is_running = false;
141 }
142
143 pub fn next_item(&mut self) {
145 self.selected_item = (self.selected_item + 1) % 5;
146 }
147
148 pub fn prev_item(&mut self) {
150 self.selected_item = (self.selected_item + 4) % 5;
151 }
152
153 pub fn handle_left(&mut self) {
155 match self.selected_item {
156 0 => self.prev_backend(),
157 1 => self.prev_workload(),
158 2 => self.decrease_intensity(),
159 3 => self.decrease_size(),
160 4 => {} _ => {}
162 }
163 }
164
165 pub fn handle_right(&mut self) {
167 match self.selected_item {
168 0 => self.next_backend(),
169 1 => self.next_workload(),
170 2 => self.increase_intensity(),
171 3 => self.increase_size(),
172 4 => {} _ => {}
174 }
175 }
176
177 pub fn handle_enter(&mut self) {
179 if self.selected_item == 4 {
180 self.toggle_running();
181 }
182 }
183}
184
185impl Default for LoadControlPanelBrick {
186 fn default() -> Self {
187 Self::new()
188 }
189}
190
191impl Brick for LoadControlPanelBrick {
192 fn brick_name(&self) -> &'static str {
193 "load_control_panel"
194 }
195
196 fn assertions(&self) -> Vec<BrickAssertion> {
197 vec![
198 BrickAssertion::MinWidth(50),
199 BrickAssertion::MinHeight(20),
200 BrickAssertion::max_latency_ms(8),
201 ]
202 }
203
204 fn budget(&self) -> BrickBudget {
205 BrickBudget::FRAME_60FPS
206 }
207
208 fn verify(&self) -> BrickVerification {
209 let mut v = BrickVerification::new();
210 for assertion in self.assertions() {
211 v.check(&assertion);
212 }
213 v
214 }
215
216 fn as_any(&self) -> &dyn Any {
217 self
218 }
219}
220
221#[cfg(test)]
222mod tests;