From e9ab47bcf7183c2d456ececc281cbf53352e0425 Mon Sep 17 00:00:00 2001 From: Hurricane996 Date: Sun, 5 Jun 2022 17:34:24 -0500 Subject: [PATCH 1/4] Added rainbow color support --- src/layout/general_settings.rs | 54 +++++++++++++++++++++++++++------- src/layout/parser/mod.rs | 7 ++++- src/settings/semantic_color.rs | 4 +-- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/layout/general_settings.rs b/src/layout/general_settings.rs index e35dffdd..7855da97 100644 --- a/src/layout/general_settings.rs +++ b/src/layout/general_settings.rs @@ -1,3 +1,5 @@ +use std::time::SystemTime; + use super::LayoutDirection; use crate::{ platform::prelude::*, @@ -5,6 +7,8 @@ use crate::{ }; use serde::{Deserialize, Serialize}; + + /// The general settings of the layout that apply to all components. #[derive(Clone, Serialize, Deserialize)] #[serde(default)] @@ -24,6 +28,8 @@ pub struct GeneralSettings { pub background: Gradient, /// The color to use for when the runner achieved a best segment. pub best_segment_color: Color, + /// Should we render best segment splits as a rainbow? + pub rainbow_for_best_segments: bool, /// The color to use for when the runner is ahead of the comparison and is /// gaining even more time. pub ahead_gaining_time_color: Color, @@ -59,6 +65,7 @@ impl Default for GeneralSettings { text_font: None, background: Gradient::Plain(Color::hsla(0.0, 0.0, 0.06, 1.0)), best_segment_color: Color::hsla(50.0, 1.0, 0.5, 1.0), + rainbow_for_best_segments: false, ahead_gaining_time_color: Color::hsla(136.0, 1.0, 0.4, 1.0), ahead_losing_time_color: Color::hsla(136.0, 0.55, 0.6, 1.0), behind_gaining_time_color: Color::hsla(0.0, 0.55, 0.6, 1.0), @@ -84,6 +91,7 @@ impl GeneralSettings { Field::new("Custom Text Font".into(), self.text_font.clone().into()), Field::new("Background".into(), self.background.into()), Field::new("Best Segment".into(), self.best_segment_color.into()), + Field::new("Use Rainbow Best Segment Color".into(), self.rainbow_for_best_segments.into()), Field::new( "Ahead (Gaining Time)".into(), self.ahead_gaining_time_color.into(), @@ -124,17 +132,43 @@ impl GeneralSettings { 3 => self.text_font = value.into(), 4 => self.background = value.into(), 5 => self.best_segment_color = value.into(), - 6 => self.ahead_gaining_time_color = value.into(), - 7 => self.ahead_losing_time_color = value.into(), - 8 => self.behind_gaining_time_color = value.into(), - 9 => self.behind_losing_time_color = value.into(), - 10 => self.not_running_color = value.into(), - 11 => self.personal_best_color = value.into(), - 12 => self.paused_color = value.into(), - 13 => self.thin_separators_color = value.into(), - 14 => self.separators_color = value.into(), - 15 => self.text_color = value.into(), + 6 => self.rainbow_for_best_segments = value.into(), + 7 => self.ahead_gaining_time_color = value.into(), + 8 => self.ahead_losing_time_color = value.into(), + 9 => self.behind_gaining_time_color = value.into(), + 10 => self.behind_losing_time_color = value.into(), + 11 => self.not_running_color = value.into(), + 12 => self.personal_best_color = value.into(), + 13 => self.paused_color = value.into(), + 14 => self.thin_separators_color = value.into(), + 15 => self.separators_color = value.into(), + 16 => self.text_color = value.into(), _ => panic!("Unsupported Setting Index"), } } + + fn _rainbow() -> Option { + let time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).ok()?.as_millis(); + + + let hue = (time/100) % 36 * 10; + + Some(Color::hsva(hue as f32, 1., 0., 1.)) + } + + + /// Gets the best segment color. If `rainbow_for_best_segments` is false, + /// this just returns the `best_segment_color` field. otherwise, it returns + /// a color that cycles based on the current system times + pub fn get_best_segment_color(&self) -> Color { + if self.rainbow_for_best_segments { + match Self::_rainbow() { + Some(c) => c, + None => self.best_segment_color + } + } + else { + self.best_segment_color + } + } } diff --git a/src/layout/parser/mod.rs b/src/layout/parser/mod.rs index c349c833..4dee23b7 100644 --- a/src/layout/parser/mod.rs +++ b/src/layout/parser/mod.rs @@ -691,7 +691,12 @@ fn parse_general_settings( color(reader, tag.into_buf(), |color| { settings.personal_best_color = color; }) - } else if tag.name() == b"AheadGainingTimeColor" { + } else if tag.name() == b"UseRainbowColor" { + parse_bool(reader, tag.into_buf(), |rainbow| { + settings.rainbow_for_best_segments = rainbow; + }) + } + else if tag.name() == b"AheadGainingTimeColor" { color(reader, tag.into_buf(), |color| { settings.ahead_gaining_time_color = color; }) diff --git a/src/settings/semantic_color.rs b/src/settings/semantic_color.rs index 982212bc..106e8b3c 100644 --- a/src/settings/semantic_color.rs +++ b/src/settings/semantic_color.rs @@ -48,14 +48,14 @@ impl SemanticColor { /// The General Settings store actual Color values for each of the different /// events. Using this method, you can use these to convert a Semantic Color /// to an actual Color. - pub const fn visualize(self, settings: &layout::GeneralSettings) -> Color { + pub fn visualize(self, settings: &layout::GeneralSettings) -> Color { match self { SemanticColor::Default => settings.text_color, SemanticColor::AheadGainingTime => settings.ahead_gaining_time_color, SemanticColor::AheadLosingTime => settings.ahead_losing_time_color, SemanticColor::BehindLosingTime => settings.behind_losing_time_color, SemanticColor::BehindGainingTime => settings.behind_gaining_time_color, - SemanticColor::BestSegment => settings.best_segment_color, + SemanticColor::BestSegment => settings.get_best_segment_color(), SemanticColor::NotRunning => settings.not_running_color, SemanticColor::Paused => settings.paused_color, SemanticColor::PersonalBest => settings.personal_best_color, From 53cce41174b27956ff87ad5d1b4a85363dc6f471 Mon Sep 17 00:00:00 2001 From: Hurricane996 Date: Sun, 5 Jun 2022 19:28:35 -0500 Subject: [PATCH 2/4] fix no-std --- src/layout/general_settings.rs | 7 ++----- src/timing/mod.rs | 13 +++++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/layout/general_settings.rs b/src/layout/general_settings.rs index 7855da97..6f372a13 100644 --- a/src/layout/general_settings.rs +++ b/src/layout/general_settings.rs @@ -1,9 +1,8 @@ -use std::time::SystemTime; - use super::LayoutDirection; use crate::{ platform::prelude::*, settings::{Color, Field, Font, Gradient, SettingsDescription, Value}, + timing::visual_cycle_timer }; use serde::{Deserialize, Serialize}; @@ -148,10 +147,8 @@ impl GeneralSettings { } fn _rainbow() -> Option { - let time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).ok()?.as_millis(); - - let hue = (time/100) % 36 * 10; + let hue = (visual_cycle_timer() / 100.) % 36. * 10.; Some(Color::hsva(hue as f32, 1., 0., 1.)) } diff --git a/src/timing/mod.rs b/src/timing/mod.rs index 2bc23713..56554063 100644 --- a/src/timing/mod.rs +++ b/src/timing/mod.rs @@ -19,3 +19,16 @@ pub use self::timer::SharedTimer; pub use self::timer::{CreationError as TimerCreationError, Snapshot, Timer}; pub use self::timer_phase::TimerPhase; pub use self::timing_method::TimingMethod; + + +/// A function used for visual elements that change over time, without any +/// specific connection to an actual timer. This function returns an f64 +/// which approximately changes by 1 every millisecond. No guarantees are +/// made about the initial value of this, so you'll almost definitely want to +/// modulo this. Currently this is used to animate the rainbows on gold segments. +pub fn visual_cycle_timer() -> f64 { + use crate::platform::DateTime; + + let since_epoch = DateTime::now_utc() - DateTime::UNIX_EPOCH; + since_epoch.as_seconds_f64() * 1000. +} From 239e67fb8bc873ae0024566835f0ad7fba48723b Mon Sep 17 00:00:00 2001 From: Hurricane996 Date: Sun, 5 Jun 2022 19:32:05 -0500 Subject: [PATCH 3/4] removed unnecessary function that was previously used for error handling --- src/layout/general_settings.rs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/layout/general_settings.rs b/src/layout/general_settings.rs index 6f372a13..a31a5a1f 100644 --- a/src/layout/general_settings.rs +++ b/src/layout/general_settings.rs @@ -145,24 +145,16 @@ impl GeneralSettings { _ => panic!("Unsupported Setting Index"), } } - - fn _rainbow() -> Option { - - let hue = (visual_cycle_timer() / 100.) % 36. * 10.; - - Some(Color::hsva(hue as f32, 1., 0., 1.)) - } - /// Gets the best segment color. If `rainbow_for_best_segments` is false, /// this just returns the `best_segment_color` field. otherwise, it returns /// a color that cycles based on the current system times pub fn get_best_segment_color(&self) -> Color { if self.rainbow_for_best_segments { - match Self::_rainbow() { - Some(c) => c, - None => self.best_segment_color - } + Color::hsva( + ((visual_cycle_timer() / 100.) % 36. * 10.) as f32, + 1.0, 1.0, 1.0 + ) } else { self.best_segment_color From 869efb495f1287ad69f27ab894422dccc12c84a3 Mon Sep 17 00:00:00 2001 From: Hurricane996 Date: Mon, 6 Jun 2022 17:29:17 -0500 Subject: [PATCH 4/4] Hopefully fixed the no-std issues by using lazy static --- Cargo.toml | 1 + src/timing/mod.rs | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b7b6f734..846434ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -87,6 +87,7 @@ tokio = { version = "1.17.0", default-features = false, features = [ "time", ], optional = true } log = { version = "0.4.14", default-features = false, optional = true } +lazy_static = "1.4.0" [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies] # WebAssembly in the Web diff --git a/src/timing/mod.rs b/src/timing/mod.rs index 56554063..a6efdd95 100644 --- a/src/timing/mod.rs +++ b/src/timing/mod.rs @@ -27,8 +27,11 @@ pub use self::timing_method::TimingMethod; /// made about the initial value of this, so you'll almost definitely want to /// modulo this. Currently this is used to animate the rainbows on gold segments. pub fn visual_cycle_timer() -> f64 { - use crate::platform::DateTime; + use lazy_static::lazy_static; - let since_epoch = DateTime::now_utc() - DateTime::UNIX_EPOCH; - since_epoch.as_seconds_f64() * 1000. -} + lazy_static! { + static ref TIME: TimeStamp = TimeStamp::now(); + } + + (TimeStamp::now() - *TIME).total_milliseconds() +} \ No newline at end of file