lotus_shared/
time.rs

1#[cfg(feature = "bevy")]
2use bevy::{
3    prelude::{ReflectResource, Resource},
4    reflect::Reflect,
5};
6
7#[cfg_attr(feature = "bevy", derive(Resource, Reflect, Debug, Clone, Copy))]
8#[cfg_attr(feature = "bevy", reflect(Resource))]
9pub struct GameTime {
10    #[cfg(feature = "engine")]
11    speed_multiplier: f32,
12    time_unix_micros: i64,
13}
14
15impl GameTime {
16    pub fn time_unix_micros(&self) -> i64 {
17        self.time_unix_micros
18    }
19}
20
21#[cfg(feature = "engine")]
22mod _engine {
23    use time::PrimitiveDateTime;
24
25    use super::*;
26
27    const MICROS_IN_DAY: i64 = 86_400_000_000;
28
29    impl GameTime {
30        pub fn increase(&mut self, seconds: f32) {
31            self.time_unix_micros += (seconds * 1_000_000.0 * self.speed_multiplier).round() as i64;
32        }
33
34        pub fn days_since_vernal_equinox_24(&self) -> f64 {
35            let diff = self.time_unix_micros - 1_710_975_600_000_000;
36            diff as f64 / 86_400_000_000.0
37        }
38
39        pub fn set_time(&mut self, time: PrimitiveDateTime) {
40            self.time_unix_micros = (time.assume_utc().unix_timestamp_nanos() / 1_000) as i64;
41        }
42
43        pub fn speed_multiplier(&self) -> f32 {
44            self.speed_multiplier
45        }
46
47        pub fn set_speed_multiplier(&mut self, speed_multiplier: f32) {
48            self.speed_multiplier = speed_multiplier;
49        }
50
51        /// Returns the time of day normalized to 0-1
52        pub fn day_time(&self) -> f32 {
53            (self.time_unix_micros % MICROS_IN_DAY) as f32 / MICROS_IN_DAY as f32
54        }
55
56        /// Returns the day of the week, 0 = Monday
57        pub fn day_of_week(&self) -> u8 {
58            ((self.time_unix_micros / MICROS_IN_DAY + 3) % 7) as u8
59        }
60    }
61}
62
63#[cfg(feature = "time")]
64mod _time {
65    use time::{Date, Duration, PrimitiveDateTime, Time};
66
67    use super::*;
68
69    impl GameTime {
70        pub fn primitive_date_time(&self) -> PrimitiveDateTime {
71            PrimitiveDateTime::new(
72                Date::from_calendar_date(1970, time::Month::January, 1).unwrap(),
73                Time::from_hms(0, 0, 0).unwrap(),
74            ) + Duration::new(
75                self.time_unix_micros / 1_000_000,
76                (self.time_unix_micros % 1_000_000 * 1_000) as i32,
77            )
78        }
79
80        pub fn from_unix_micros(unix_micros: i64) -> Self {
81            Self {
82                #[cfg(feature = "engine")]
83                speed_multiplier: 1.0,
84                time_unix_micros: unix_micros,
85            }
86        }
87    }
88}
89
90#[cfg(feature = "engine")]
91impl Default for GameTime {
92    fn default() -> Self {
93        Self {
94            speed_multiplier: 1.0,
95            time_unix_micros: 1_746_957_625_000_000,
96        }
97    }
98}