livesplit_core/component/
current_pace.rs1use super::key_value;
7use crate::{
8 analysis::current_pace,
9 comparison,
10 platform::prelude::*,
11 settings::{Color, Field, Gradient, SettingsDescription, Value},
12 timing::{
13 formatter::{Accuracy, Regular, TimeFormatter},
14 Snapshot,
15 },
16 TimerPhase,
17};
18use alloc::borrow::Cow;
19use core::fmt::Write;
20use serde::{Deserialize, Serialize};
21
22#[derive(Default, Clone)]
26pub struct Component {
27 settings: Settings,
28}
29
30#[derive(Clone, Serialize, Deserialize)]
32#[serde(default)]
33pub struct Settings {
34 pub background: Gradient,
36 pub comparison_override: Option<String>,
39 pub display_two_rows: bool,
42 pub label_color: Option<Color>,
45 pub value_color: Option<Color>,
48 pub accuracy: Accuracy,
50}
51
52impl Default for Settings {
53 fn default() -> Self {
54 Self {
55 background: key_value::DEFAULT_GRADIENT,
56 comparison_override: None,
57 display_two_rows: false,
58 label_color: None,
59 value_color: None,
60 accuracy: Accuracy::Seconds,
61 }
62 }
63}
64
65impl Component {
66 pub fn new() -> Self {
68 Default::default()
69 }
70
71 pub const fn with_settings(settings: Settings) -> Self {
73 Self { settings }
74 }
75
76 pub const fn settings(&self) -> &Settings {
78 &self.settings
79 }
80
81 pub fn settings_mut(&mut self) -> &mut Settings {
83 &mut self.settings
84 }
85
86 pub fn name(&self) -> Cow<'static, str> {
88 self.text(self.settings.comparison_override.as_deref())
89 }
90
91 fn text(&self, comparison: Option<&str>) -> Cow<'static, str> {
92 if let Some(comparison) = comparison {
93 match comparison {
94 comparison::personal_best::NAME => "Current Pace".into(),
95 comparison::best_segments::NAME => "Best Possible Time".into(),
96 comparison::worst_segments::NAME => "Worst Possible Time".into(),
97 comparison::average_segments::NAME => "Predicted Time".into(),
98 comparison => format!("Current Pace ({})", comparison::shorten(comparison)).into(),
99 }
100 } else {
101 "Current Pace".into()
102 }
103 }
104
105 pub fn update_state(&self, state: &mut key_value::State, timer: &Snapshot<'_>) {
107 let comparison = comparison::resolve(&self.settings.comparison_override, timer);
108 let comparison = comparison::or_current(comparison, timer);
109 let key = self.text(Some(comparison));
110
111 let (current_pace, updates_frequently) =
112 if timer.current_phase() == TimerPhase::NotRunning && key.starts_with("Current Pace") {
113 (None, false)
114 } else {
115 current_pace::calculate(timer, comparison)
116 };
117
118 state.background = self.settings.background;
119 state.key_color = self.settings.label_color;
120 state.value_color = self.settings.value_color;
121 state.semantic_color = Default::default();
122
123 state.key.clear();
124 state.key.push_str(&key); state.value.clear();
127 let _ = write!(
128 state.value,
129 "{}",
130 Regular::with_accuracy(self.settings.accuracy).format(current_pace)
131 );
132
133 state.key_abbreviations.clear();
134 match &*key {
136 "Best Possible Time" => {
137 state.key_abbreviations.push("Best Poss. Time".into());
138 state.key_abbreviations.push("Best Time".into());
139 state.key_abbreviations.push("BPT".into());
140 }
141 "Worst Possible Time" => {
142 state.key_abbreviations.push("Worst Poss. Time".into());
143 state.key_abbreviations.push("Worst Time".into());
144 }
145 "Predicted Time" => {
146 state.key_abbreviations.push("Pred. Time".into());
147 }
148 "Current Pace" => {
149 state.key_abbreviations.push("Cur. Pace".into());
150 state.key_abbreviations.push("Pace".into());
151 }
152 _ => {
153 state.key_abbreviations.push("Current Pace".into());
154 state.key_abbreviations.push("Cur. Pace".into());
155 state.key_abbreviations.push("Pace".into());
156 }
157 }
158
159 state.display_two_rows = self.settings.display_two_rows;
160 state.updates_frequently = updates_frequently;
161 }
162
163 pub fn state(&self, timer: &Snapshot<'_>) -> key_value::State {
165 let mut state = Default::default();
166 self.update_state(&mut state, timer);
167 state
168 }
169
170 pub fn settings_description(&self) -> SettingsDescription {
173 SettingsDescription::with_fields(vec![
174 Field::new("Background".into(), self.settings.background.into()),
175 Field::new(
176 "Comparison".into(),
177 self.settings.comparison_override.clone().into(),
178 ),
179 Field::new(
180 "Display 2 Rows".into(),
181 self.settings.display_two_rows.into(),
182 ),
183 Field::new("Label Color".into(), self.settings.label_color.into()),
184 Field::new("Value Color".into(), self.settings.value_color.into()),
185 Field::new("Accuracy".into(), self.settings.accuracy.into()),
186 ])
187 }
188
189 pub fn set_value(&mut self, index: usize, value: Value) {
197 match index {
198 0 => self.settings.background = value.into(),
199 1 => self.settings.comparison_override = value.into(),
200 2 => self.settings.display_two_rows = value.into(),
201 3 => self.settings.label_color = value.into(),
202 4 => self.settings.value_color = value.into(),
203 5 => self.settings.accuracy = value.into(),
204 _ => panic!("Unsupported Setting Index"),
205 }
206 }
207}