1#[cfg(feature = "bevy_reflect")]
2use bevy_reflect::Reflect;
3use core::time::Duration;
4use log::debug;
56use crate::{real::Real, time::Time};
78/// The virtual game clock representing game time.
9///
10/// A specialization of the [`Time`] structure. **For method documentation, see
11/// [`Time<Virtual>#impl-Time<Virtual>`].**
12///
13/// Normally used as `Time<Virtual>`. It is automatically inserted as a resource
14/// by [`TimePlugin`](crate::TimePlugin) and updated based on
15/// [`Time<Real>`](Real). The virtual clock is automatically set as the default
16/// generic [`Time`] resource for the update.
17///
18/// The virtual clock differs from real time clock in that it can be paused, sped up
19/// and slowed down. It also limits how much it can advance in a single update
20/// in order to prevent unexpected behavior in cases where updates do not happen
21/// at regular intervals (e.g. coming back after the program was suspended a long time).
22///
23/// The virtual clock can be paused by calling [`pause()`](Time::pause),
24/// unpaused by calling [`unpause()`](Time::unpause), or toggled by calling
25/// [`toggle()`](Time::toggle). When the game clock is
26/// paused [`delta()`](Time::delta) will be zero on each update, and
27/// [`elapsed()`](Time::elapsed) will not grow.
28/// [`effective_speed()`](Time::effective_speed) will return `0.0`. Calling
29/// [`pause()`](Time::pause) will not affect value the [`delta()`](Time::delta)
30/// value for the update currently being processed.
31///
32/// The speed of the virtual clock can be changed by calling
33/// [`set_relative_speed()`](Time::set_relative_speed). A value of `2.0` means
34/// that virtual clock should advance twice as fast as real time, meaning that
35/// [`delta()`](Time::delta) values will be double of what
36/// [`Time<Real>::delta()`](Time::delta) reports and
37/// [`elapsed()`](Time::elapsed) will go twice as fast as
38/// [`Time<Real>::elapsed()`](Time::elapsed). Calling
39/// [`set_relative_speed()`](Time::set_relative_speed) will not affect the
40/// [`delta()`](Time::delta) value for the update currently being processed.
41///
42/// The maximum amount of delta time that can be added by a single update can be
43/// set by [`set_max_delta()`](Time::set_max_delta). This value serves a dual
44/// purpose in the virtual clock.
45///
46/// If the game temporarily freezes due to any reason, such as disk access, a
47/// blocking system call, or operating system level suspend, reporting the full
48/// elapsed delta time is likely to cause bugs in game logic. Usually if a
49/// laptop is suspended for an hour, it doesn't make sense to try to simulate
50/// the game logic for the elapsed hour when resuming. Instead it is better to
51/// lose the extra time and pretend a shorter duration of time passed. Setting
52/// [`max_delta()`](Time::max_delta) to a relatively short time means that the
53/// impact on game logic will be minimal.
54///
55/// If the game lags for some reason, meaning that it will take a longer time to
56/// compute a frame than the real time that passes during the computation, then
57/// we would fall behind in processing virtual time. If this situation persists,
58/// and computing a frame takes longer depending on how much virtual time has
59/// passed, the game would enter a "death spiral" where computing each frame
60/// takes longer and longer and the game will appear to freeze. By limiting the
61/// maximum time that can be added at once, we also limit the amount of virtual
62/// time the game needs to compute for each frame. This means that the game will
63/// run slow, and it will run slower than real time, but it will not freeze and
64/// it will recover as soon as computation becomes fast again.
65///
66/// You should set [`max_delta()`](Time::max_delta) to a value that is
67/// approximately the minimum FPS your game should have even if heavily lagged
68/// for a moment. The actual FPS when lagged will be somewhat lower than this,
69/// depending on how much more time it takes to compute a frame compared to real
70/// time. You should also consider how stable your FPS is, as the limit will
71/// also dictate how big of an FPS drop you can accept without losing time and
72/// falling behind real time.
73#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Virtual {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f, "Virtual",
"max_delta", &self.max_delta, "paused", &self.paused,
"relative_speed", &self.relative_speed, "effective_speed",
&&self.effective_speed)
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for Virtual { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Virtual {
#[inline]
fn clone(&self) -> Virtual {
let _: ::core::clone::AssertParamIsClone<Duration>;
let _: ::core::clone::AssertParamIsClone<bool>;
let _: ::core::clone::AssertParamIsClone<f64>;
*self
}
}Clone)]
74#[cfg_attr(feature = "bevy_reflect", derive(const _: () =
{
impl bevy_reflect::GetTypeRegistration for Virtual where {
fn get_type_registration() -> bevy_reflect::TypeRegistration {
let mut registration =
bevy_reflect::TypeRegistration::of::<Self>();
registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
registration
}
#[inline(never)]
fn register_type_dependencies(registry:
&mut bevy_reflect::TypeRegistry) {
<Duration as
bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
<bool as
bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
<f64 as
bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
}
}
impl bevy_reflect::Typed for Virtual where {
#[inline]
fn type_info() -> &'static bevy_reflect::TypeInfo {
static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
bevy_reflect::utility::NonGenericTypeInfoCell::new();
CELL.get_or_set(||
{
bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Duration>("max_delta"),
bevy_reflect::NamedField::new::<bool>("paused"),
bevy_reflect::NamedField::new::<f64>("relative_speed"),
bevy_reflect::NamedField::new::<f64>("effective_speed")]))
})
}
}
#[allow(deprecated, reason =
"derives on a deprecated type shouldn't be considered a usage")]
impl bevy_reflect::TypePath for Virtual where {
fn type_path() -> &'static str { "bevy_time::virt::Virtual" }
fn short_type_path() -> &'static str { "Virtual" }
fn type_ident() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("Virtual")
}
fn crate_name() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_time::virt".split(':').next().unwrap())
}
fn module_path() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_time::virt")
}
}
impl bevy_reflect::Reflect for Virtual where {
#[inline]
fn into_any(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
self
}
#[inline]
fn as_any(&self) -> &dyn ::core::any::Any { self }
#[inline]
fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
#[inline]
fn into_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
#[inline]
fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
self
}
#[inline]
fn set(&mut self,
value:
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
->
::core::result::Result<(),
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
*self = <dyn bevy_reflect::Reflect>::take(value)?;
::core::result::Result::Ok(())
}
}
impl bevy_reflect::structs::Struct for Virtual where {
fn field(&self, name: &str)
-> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
match name {
"max_delta" =>
::core::option::Option::Some(&self.max_delta),
"paused" => ::core::option::Option::Some(&self.paused),
"relative_speed" =>
::core::option::Option::Some(&self.relative_speed),
"effective_speed" =>
::core::option::Option::Some(&self.effective_speed),
_ => ::core::option::Option::None,
}
}
fn field_mut(&mut self, name: &str)
->
::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
match name {
"max_delta" =>
::core::option::Option::Some(&mut self.max_delta),
"paused" => ::core::option::Option::Some(&mut self.paused),
"relative_speed" =>
::core::option::Option::Some(&mut self.relative_speed),
"effective_speed" =>
::core::option::Option::Some(&mut self.effective_speed),
_ => ::core::option::Option::None,
}
}
fn field_at(&self, index: usize)
-> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
match index {
0usize => ::core::option::Option::Some(&self.max_delta),
1usize => ::core::option::Option::Some(&self.paused),
2usize =>
::core::option::Option::Some(&self.relative_speed),
3usize =>
::core::option::Option::Some(&self.effective_speed),
_ => ::core::option::Option::None,
}
}
fn field_at_mut(&mut self, index: usize)
->
::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
match index {
0usize => ::core::option::Option::Some(&mut self.max_delta),
1usize => ::core::option::Option::Some(&mut self.paused),
2usize =>
::core::option::Option::Some(&mut self.relative_speed),
3usize =>
::core::option::Option::Some(&mut self.effective_speed),
_ => ::core::option::Option::None,
}
}
fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
match index {
0usize => ::core::option::Option::Some("max_delta"),
1usize => ::core::option::Option::Some("paused"),
2usize => ::core::option::Option::Some("relative_speed"),
3usize => ::core::option::Option::Some("effective_speed"),
_ => ::core::option::Option::None,
}
}
fn index_of_name(&self, name: &str)
-> ::core::option::Option<usize> {
match name {
"max_delta" => ::core::option::Option::Some(0usize),
"paused" => ::core::option::Option::Some(1usize),
"relative_speed" => ::core::option::Option::Some(2usize),
"effective_speed" => ::core::option::Option::Some(3usize),
_ => ::core::option::Option::None,
}
}
fn field_len(&self) -> usize { 4usize }
fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
bevy_reflect::structs::FieldIter::new(self)
}
fn to_dynamic_struct(&self)
-> bevy_reflect::structs::DynamicStruct {
let mut dynamic: bevy_reflect::structs::DynamicStruct =
::core::default::Default::default();
dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
dynamic.insert_boxed("max_delta",
bevy_reflect::PartialReflect::to_dynamic(&self.max_delta));
dynamic.insert_boxed("paused",
bevy_reflect::PartialReflect::to_dynamic(&self.paused));
dynamic.insert_boxed("relative_speed",
bevy_reflect::PartialReflect::to_dynamic(&self.relative_speed));
dynamic.insert_boxed("effective_speed",
bevy_reflect::PartialReflect::to_dynamic(&self.effective_speed));
dynamic
}
}
impl bevy_reflect::PartialReflect for Virtual where {
#[inline]
fn get_represented_type_info(&self)
-> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
::core::option::Option::Some(<Self as
bevy_reflect::Typed>::type_info())
}
#[inline]
fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
-> ::core::result::Result<(), bevy_reflect::ApplyError> {
if let bevy_reflect::ReflectRef::Struct(struct_value) =
bevy_reflect::PartialReflect::reflect_ref(value) {
for (name, value) in
bevy_reflect::structs::Struct::iter_fields(struct_value) {
if let ::core::option::Option::Some(v) =
bevy_reflect::structs::Struct::field_mut(self, name) {
bevy_reflect::PartialReflect::try_apply(v, value)?;
}
}
} else {
return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
to_kind: bevy_reflect::ReflectKind::Struct,
});
}
::core::result::Result::Ok(())
}
#[inline]
fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
bevy_reflect::ReflectKind::Struct
}
#[inline]
fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
bevy_reflect::ReflectRef::Struct(self)
}
#[inline]
fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
bevy_reflect::ReflectMut::Struct(self)
}
#[inline]
fn reflect_owned(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
-> bevy_reflect::ReflectOwned {
bevy_reflect::ReflectOwned::Struct(self)
}
#[inline]
fn try_into_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
::core::result::Result::Ok(self)
}
#[inline]
fn try_as_reflect(&self)
-> ::core::option::Option<&dyn bevy_reflect::Reflect> {
::core::option::Option::Some(self)
}
#[inline]
fn try_as_reflect_mut(&mut self)
-> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
::core::option::Option::Some(self)
}
#[inline]
fn into_partial_reflect(self:
bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
->
bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
self
}
#[inline]
fn as_partial_reflect(&self)
-> &dyn bevy_reflect::PartialReflect {
self
}
#[inline]
fn as_partial_reflect_mut(&mut self)
-> &mut dyn bevy_reflect::PartialReflect {
self
}
fn reflect_partial_eq(&self,
value: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<bool> {
(bevy_reflect::structs::struct_partial_eq)(self, value)
}
fn reflect_partial_cmp(&self,
value: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<::core::cmp::Ordering> {
(bevy_reflect::structs::struct_partial_cmp)(self, value)
}
#[inline]
fn reflect_clone(&self)
->
::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
bevy_reflect::ReflectCloneError> {
::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
}
}
impl bevy_reflect::FromReflect for Virtual where {
fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
-> ::core::option::Option<Self> {
if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
bevy_reflect::PartialReflect::reflect_ref(reflect) {
let __this =
Self {
max_delta: <Duration as
bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
"max_delta")?)?,
paused: <bool as
bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
"paused")?)?,
relative_speed: <f64 as
bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
"relative_speed")?)?,
effective_speed: <f64 as
bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
"effective_speed")?)?,
};
::core::option::Option::Some(__this)
} else { ::core::option::Option::None }
}
}
};Reflect), reflect(Clone))]
75pub struct Virtual {
76 max_delta: Duration,
77 paused: bool,
78 relative_speed: f64,
79 effective_speed: f64,
80}
8182impl Time<Virtual> {
83/// The default amount of time that can added in a single update.
84 ///
85 /// Equal to 250 milliseconds.
86const DEFAULT_MAX_DELTA: Duration = Duration::from_millis(250);
8788/// Create new virtual clock with given maximum delta step [`Duration`]
89 ///
90 /// # Panics
91 ///
92 /// Panics if `max_delta` is zero.
93pub fn from_max_delta(max_delta: Duration) -> Self {
94let mut ret = Self::default();
95ret.set_max_delta(max_delta);
96ret97 }
9899/// Returns the maximum amount of time that can be added to this clock by a
100 /// single update, as [`Duration`].
101 ///
102 /// This is the maximum value [`Self::delta()`] will return and also to
103 /// maximum time [`Self::elapsed()`] will be increased by in a single
104 /// update.
105 ///
106 /// This ensures that even if no updates happen for an extended amount of time,
107 /// the clock will not have a sudden, huge advance all at once. This also indirectly
108 /// limits the maximum number of fixed update steps that can run in a single update.
109 ///
110 /// The default value is 250 milliseconds.
111#[inline]
112pub fn max_delta(&self) -> Duration {
113self.context().max_delta
114 }
115116/// Sets the maximum amount of time that can be added to this clock by a
117 /// single update, as [`Duration`].
118 ///
119 /// This is the maximum value [`Self::delta()`] will return and also to
120 /// maximum time [`Self::elapsed()`] will be increased by in a single
121 /// update.
122 ///
123 /// This is used to ensure that even if the game freezes for a few seconds,
124 /// or is suspended for hours or even days, the virtual clock doesn't
125 /// suddenly jump forward for that full amount, which would likely cause
126 /// gameplay bugs or having to suddenly simulate all the intervening time.
127 ///
128 /// If no updates happen for an extended amount of time, this limit prevents
129 /// having a sudden, huge advance all at once. This also indirectly limits
130 /// the maximum number of fixed update steps that can run in a single
131 /// update.
132 ///
133 /// The default value is 250 milliseconds. If you want to disable this
134 /// feature, set the value to [`Duration::MAX`].
135 ///
136 /// # Panics
137 ///
138 /// Panics if `max_delta` is zero.
139#[inline]
140pub fn set_max_delta(&mut self, max_delta: Duration) {
141match (&(max_delta), &(Duration::ZERO)) {
(left_val, right_val) => {
if *left_val == *right_val {
let kind = ::core::panicking::AssertKind::Ne;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::Some(format_args!("tried to set max delta to zero")));
}
}
};assert_ne!(max_delta, Duration::ZERO, "tried to set max delta to zero");
142self.context_mut().max_delta = max_delta;
143 }
144145/// Returns the speed the clock advances relative to your system clock, as [`f32`].
146 /// This is known as "time scaling" or "time dilation" in other engines.
147#[inline]
148pub fn relative_speed(&self) -> f32 {
149self.relative_speed_f64() as f32150 }
151152/// Returns the speed the clock advances relative to your system clock, as [`f64`].
153 /// This is known as "time scaling" or "time dilation" in other engines.
154#[inline]
155pub fn relative_speed_f64(&self) -> f64 {
156self.context().relative_speed
157 }
158159/// Returns the speed the clock advanced relative to your system clock in
160 /// this update, as [`f32`].
161 ///
162 /// Returns `0.0` if the game was paused or what the `relative_speed` value
163 /// was at the start of this update.
164#[inline]
165pub fn effective_speed(&self) -> f32 {
166self.context().effective_speed as f32167 }
168169/// Returns the speed the clock advanced relative to your system clock in
170 /// this update, as [`f64`].
171 ///
172 /// Returns `0.0` if the game was paused or what the `relative_speed` value
173 /// was at the start of this update.
174#[inline]
175pub fn effective_speed_f64(&self) -> f64 {
176self.context().effective_speed
177 }
178179/// Sets the speed the clock advances relative to your system clock, given as an [`f32`].
180 ///
181 /// For example, setting this to `2.0` will make the clock advance twice as fast as your system
182 /// clock.
183 ///
184 /// # Panics
185 ///
186 /// Panics if `ratio` is negative or not finite.
187#[inline]
188pub fn set_relative_speed(&mut self, ratio: f32) {
189self.set_relative_speed_f64(ratioas f64);
190 }
191192/// Sets the speed the clock advances relative to your system clock, given as an [`f64`].
193 ///
194 /// For example, setting this to `2.0` will make the clock advance twice as fast as your system
195 /// clock.
196 ///
197 /// # Panics
198 ///
199 /// Panics if `ratio` is negative or not finite.
200#[inline]
201pub fn set_relative_speed_f64(&mut self, ratio: f64) {
202if !ratio.is_finite() {
{
::core::panicking::panic_fmt(format_args!("tried to go infinitely fast"));
}
};assert!(ratio.is_finite(), "tried to go infinitely fast");
203if !(ratio >= 0.0) {
{
::core::panicking::panic_fmt(format_args!("tried to go back in time"));
}
};assert!(ratio >= 0.0, "tried to go back in time");
204self.context_mut().relative_speed = ratio;
205 }
206207/// Stops the clock if it is running, otherwise resumes the clock.
208#[inline]
209pub fn toggle(&mut self) {
210self.context_mut().paused ^= true;
211 }
212213/// Stops the clock, preventing it from advancing until resumed.
214#[inline]
215pub fn pause(&mut self) {
216self.context_mut().paused = true;
217 }
218219/// Resumes the clock.
220#[inline]
221pub fn unpause(&mut self) {
222self.context_mut().paused = false;
223 }
224225/// Returns `true` if the clock is currently paused.
226#[inline]
227pub fn is_paused(&self) -> bool {
228self.context().paused
229 }
230231/// Returns `true` if the clock was paused at the start of this update.
232#[inline]
233pub fn was_paused(&self) -> bool {
234self.context().effective_speed == 0.0
235}
236237/// Updates the elapsed duration of `self` by `raw_delta`, up to the `max_delta`.
238fn advance_with_raw_delta(&mut self, raw_delta: Duration) {
239let max_delta = self.context().max_delta;
240let clamped_delta = if raw_delta > max_delta {
241{
{
let lvl = ::log::Level::Debug;
if lvl <= ::log::STATIC_MAX_LEVEL && lvl <= ::log::max_level() {
::log::__private_api::log({ ::log::__private_api::GlobalLogger },
format_args!("delta time larger than maximum delta, clamping delta to {0:?} and skipping {1:?}",
max_delta, raw_delta - max_delta), lvl,
&("bevy_time::virt", "bevy_time::virt",
::log::__private_api::loc()), ());
}
}
};debug!(
242"delta time larger than maximum delta, clamping delta to {:?} and skipping {:?}",
243 max_delta,
244 raw_delta - max_delta
245 );
246max_delta247 } else {
248raw_delta249 };
250let effective_speed = if self.context().paused {
2510.0
252} else {
253self.context().relative_speed
254 };
255let delta = if effective_speed != 1.0 {
256clamped_delta.mul_f64(effective_speed)
257 } else {
258// avoid rounding when at normal speed
259clamped_delta260 };
261self.context_mut().effective_speed = effective_speed;
262self.advance_by(delta);
263 }
264}
265266impl Defaultfor Virtual {
267fn default() -> Self {
268Self {
269 max_delta: Time::<Virtual>::DEFAULT_MAX_DELTA,
270 paused: false,
271 relative_speed: 1.0,
272 effective_speed: 1.0,
273 }
274 }
275}
276277/// Advances [`Time<Virtual>`] and [`Time`] based on the elapsed [`Time<Real>`].
278///
279/// The virtual time will be advanced up to the provided [`Time::max_delta`].
280pub fn update_virtual_time(current: &mut Time, virt: &mut Time<Virtual>, real: &Time<Real>) {
281let raw_delta = real.delta();
282virt.advance_with_raw_delta(raw_delta);
283*current = virt.as_generic();
284}
285286#[cfg(test)]
287mod test {
288use super::*;
289290#[test]
291fn test_default() {
292let time = Time::<Virtual>::default();
293294assert!(!time.is_paused()); // false
295assert_eq!(time.relative_speed(), 1.0);
296assert_eq!(time.max_delta(), Time::<Virtual>::DEFAULT_MAX_DELTA);
297assert_eq!(time.delta(), Duration::ZERO);
298assert_eq!(time.elapsed(), Duration::ZERO);
299 }
300301#[test]
302fn test_advance() {
303let mut time = Time::<Virtual>::default();
304305 time.advance_with_raw_delta(Duration::from_millis(125));
306307assert_eq!(time.delta(), Duration::from_millis(125));
308assert_eq!(time.elapsed(), Duration::from_millis(125));
309310 time.advance_with_raw_delta(Duration::from_millis(125));
311312assert_eq!(time.delta(), Duration::from_millis(125));
313assert_eq!(time.elapsed(), Duration::from_millis(250));
314315 time.advance_with_raw_delta(Duration::from_millis(125));
316317assert_eq!(time.delta(), Duration::from_millis(125));
318assert_eq!(time.elapsed(), Duration::from_millis(375));
319320 time.advance_with_raw_delta(Duration::from_millis(125));
321322assert_eq!(time.delta(), Duration::from_millis(125));
323assert_eq!(time.elapsed(), Duration::from_millis(500));
324 }
325326#[test]
327fn test_relative_speed() {
328let mut time = Time::<Virtual>::default();
329330 time.advance_with_raw_delta(Duration::from_millis(250));
331332assert_eq!(time.relative_speed(), 1.0);
333assert_eq!(time.effective_speed(), 1.0);
334assert_eq!(time.delta(), Duration::from_millis(250));
335assert_eq!(time.elapsed(), Duration::from_millis(250));
336337 time.set_relative_speed_f64(2.0);
338339assert_eq!(time.relative_speed(), 2.0);
340assert_eq!(time.effective_speed(), 1.0);
341342 time.advance_with_raw_delta(Duration::from_millis(250));
343344assert_eq!(time.relative_speed(), 2.0);
345assert_eq!(time.effective_speed(), 2.0);
346assert_eq!(time.delta(), Duration::from_millis(500));
347assert_eq!(time.elapsed(), Duration::from_millis(750));
348349 time.set_relative_speed_f64(0.5);
350351assert_eq!(time.relative_speed(), 0.5);
352assert_eq!(time.effective_speed(), 2.0);
353354 time.advance_with_raw_delta(Duration::from_millis(250));
355356assert_eq!(time.relative_speed(), 0.5);
357assert_eq!(time.effective_speed(), 0.5);
358assert_eq!(time.delta(), Duration::from_millis(125));
359assert_eq!(time.elapsed(), Duration::from_millis(875));
360 }
361362#[test]
363fn test_pause() {
364let mut time = Time::<Virtual>::default();
365366 time.advance_with_raw_delta(Duration::from_millis(250));
367368assert!(!time.is_paused()); // false
369assert!(!time.was_paused()); // false
370assert_eq!(time.relative_speed(), 1.0);
371assert_eq!(time.effective_speed(), 1.0);
372assert_eq!(time.delta(), Duration::from_millis(250));
373assert_eq!(time.elapsed(), Duration::from_millis(250));
374375 time.pause();
376377assert!(time.is_paused()); // true
378assert!(!time.was_paused()); // false
379assert_eq!(time.relative_speed(), 1.0);
380assert_eq!(time.effective_speed(), 1.0);
381382 time.advance_with_raw_delta(Duration::from_millis(250));
383384assert!(time.is_paused()); // true
385assert!(time.was_paused()); // true
386assert_eq!(time.relative_speed(), 1.0);
387assert_eq!(time.effective_speed(), 0.0);
388assert_eq!(time.delta(), Duration::ZERO);
389assert_eq!(time.elapsed(), Duration::from_millis(250));
390391 time.unpause();
392393assert!(!time.is_paused()); // false
394assert!(time.was_paused()); // true
395assert_eq!(time.relative_speed(), 1.0);
396assert_eq!(time.effective_speed(), 0.0);
397398 time.advance_with_raw_delta(Duration::from_millis(250));
399400assert!(!time.is_paused()); // false
401assert!(!time.was_paused()); // false
402assert_eq!(time.relative_speed(), 1.0);
403assert_eq!(time.effective_speed(), 1.0);
404assert_eq!(time.delta(), Duration::from_millis(250));
405assert_eq!(time.elapsed(), Duration::from_millis(500));
406 }
407408#[test]
409fn test_max_delta() {
410let mut time = Time::<Virtual>::default();
411 time.set_max_delta(Duration::from_millis(500));
412413 time.advance_with_raw_delta(Duration::from_millis(250));
414415assert_eq!(time.delta(), Duration::from_millis(250));
416assert_eq!(time.elapsed(), Duration::from_millis(250));
417418 time.advance_with_raw_delta(Duration::from_millis(500));
419420assert_eq!(time.delta(), Duration::from_millis(500));
421assert_eq!(time.elapsed(), Duration::from_millis(750));
422423 time.advance_with_raw_delta(Duration::from_millis(750));
424425assert_eq!(time.delta(), Duration::from_millis(500));
426assert_eq!(time.elapsed(), Duration::from_millis(1250));
427428 time.set_max_delta(Duration::from_secs(1));
429430assert_eq!(time.max_delta(), Duration::from_secs(1));
431432 time.advance_with_raw_delta(Duration::from_millis(750));
433434assert_eq!(time.delta(), Duration::from_millis(750));
435assert_eq!(time.elapsed(), Duration::from_millis(2000));
436437 time.advance_with_raw_delta(Duration::from_millis(1250));
438439assert_eq!(time.delta(), Duration::from_millis(1000));
440assert_eq!(time.elapsed(), Duration::from_millis(3000));
441 }
442}