Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Add TimeUpdateStrategy resource for manual Time updating #6159

Closed
wants to merge 12 commits into from

Conversation

ShinySapphic
Copy link
Contributor

@ShinySapphic ShinySapphic commented Oct 4, 2022

Objective

Solution

  • Create TimeUpdateStrategy config resource
  • Allow users to specify a manual Instant/Duration or leave as default (automatic)
  • Get resource in bevy_time::time_systemand update time with desired value

Changelog

  • Add TimeUpdateStrategy resource
  • Update bevy_time::time_system to use optional manual values

@alice-i-cecile alice-i-cecile added C-Usability A simple quality-of-life change that makes Bevy easier to use C-Testing A change that impacts how we test Bevy or how users test their apps A-App Bevy apps and plugins A-Time Involves time keeping and reporting labels Oct 4, 2022
@alice-i-cecile alice-i-cecile self-requested a review October 4, 2022 02:29
///
/// See [`update_with_interval`](self::TimeUpdater::update_with_instant) for more details.
#[derive(Resource)]
struct DesiredTime(Instant);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this isn't pub?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. I just assumed since it was going to be inserted from the method that it didn't need to be accessed externally. Now that I think about it, there's probably some use cases where you might want to access it externally so I'll go ahead and make it public.

Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a doc test on update_with_instant would be nice, but I'm okay if we merge this as is.

Copy link
Contributor

@maniwani maniwani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it OK that the TimeReceiver channel interaction has precedence over the manual time setting?

If the answer is yes, then this all seems fine to me.

@ShinySapphic
Copy link
Contributor Author

Is it OK that the TimeReceiver channel interaction has precedence over the manual time setting?

If the answer is yes, then this all seems fine to me.

I think so. I wasn't 100% sure how important TimeReceiver was. I even thought about combining it with DesiredTime since they almost do the same thing, but I wasn't too sure.

@alice-i-cecile
Copy link
Member

Is it OK that the TimeReceiver channel interaction has precedence over the manual time setting?

Ping @hymm; do you have opinions on this?

@hymm
Copy link
Contributor

hymm commented Oct 7, 2022

I even thought about combining it with DesiredTime since they almost do the same thing, but I wasn't too sure.

Overall it feels weird to only update time once instead of taking over the machinery completely. Are there use cases for only updating the time once and then going back to using the Instant::now()? Seems like something that would be problematic with frames reporting zero time for multiple frames or an extra long frame time once.

I feel like a better approach would be to somehow not use the time_system and just do everything (including updating the Res) in the app.update_with_instant function.

@alice-i-cecile
Copy link
Member

Are there use cases for only updating the time once and then going back to using the Instant::now()? Seems like something that would be problematic with frames reporting zero time for multiple frames or an extra long frame time once.

When reproducing tricky bugs, you may want to immediately "fast forward" time to the recorded problem state, and then play through as normal. I don't think it's common though.

I feel like a better approach would be to somehow not use the time_system and just do everything (including updating the Res) in the app.update_with_instant function.

Agreed, this feels like the more coherent strategy overall.

@ShinySapphic
Copy link
Contributor Author

I feel like a better approach would be to somehow not use the time_system and just do everything (including updating the Res) in the app.update_with_instant function.

I agree as well. I would've preferred to not do it the way I did but I didn't think it was possible. Given the information in the issue, time should only be changed after time_system but before everything else otherwise the desired time isn't going to be accurate. The only other thing I can think of is having an option to prevent the system from running.

@alice-i-cecile
Copy link
Member

Can we have a config resource that controls whether time is updated? This resource could even supply the "next time", and then get reset after that Instant is consumed.

@ShinySapphic
Copy link
Contributor Author

Can we have a config resource that controls whether time is updated? This resource could even supply the "next time", and then get reset after that Instant is consumed.

Something like this?

pub struct TimeConfig {
    pub should_update: bool,
    pub next_time: Instant,
}

If so, would it be best to set next_time to Instant::now() or should it be wrapped in an Option? It might also be better if next_time holds a Duration instead assuming users are constantly adding that to Instant::now() to get the next time.

@alice-i-cecile
Copy link
Member

Yep, that's the basic strategy I had in mind :) should_update probably needs a clearer name, but I think this is a good path forward.

would it be best to set next_time to Instant::now() or should it be wrapped in an Option?

I think just setting the next_time field directly should work fine.

It might also be better if next_time holds a Duration instead assuming users are constantly adding that to Instant::now() to get the next time

In my use case, the pattern is actually to set the exact time that was previously observed :) However when testing, you'll often want to increment it by a Duration. Maybe a

#[derive(Resource, Default)
pub enum TimeUpdateStrategy {
   #[default]
   Automatic,
   ManualInstant(Instant),
   ManualDuration(Duration),
}

@ShinySapphic
Copy link
Contributor Author

If it's going to be a config resource, is there still a reason to have the update_with_instant method? It seems kind of redundant if you're just going to insert the desired instant/duration and then manually change the values anyways. I suppose it would be pretty annoying to constantly do:

if let Some(TimeUpdateStrategy::ManualInstant(mut instant)) = app.world.get_resource::<TimeUpdateStrategy>() {
    instant = prev_instant;
    app.update();
}

// or
app.insert_resource(TimeUpdateStrategy::ManualInstant(prev_instant));
app.update();

Maybe TimeUpdateStrategy should only have Automatic & Manual with no instant/duration values provided. Manual implies it's up to the user to grab the time resource and call time.update_with_instant(desired_time). app.update_with_instant could still be used to set a specific time and have update() called. If the UpdateStrategy isn't set to Manual, calling that method could either not do anything or would set the strategy to manual for a single frame.

@alice-i-cecile
Copy link
Member

If it's going to be a config resource, is there still a reason to have the update_with_instant method? It seems kind of redundant if you're just going to insert the desired instant/duration and then manually change the values anyways

I think we can cut it; the insert_resource strategy is very clear and idiomatic. Then we can point to the TimeUpdateStrategy resource (with three variants) from the App::update docs.

time.update();
}
}
TimeUpdateStrategy::ManualInstant(instant) => time.update_with_instant(*instant),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably want to try_recv on the channel in the manual cases too and discard the value. The time channel only can have 2 times in it and will panic if the channel gets full.

warn!("time_system did not receive the time from the render world! Calculations depending on the time may be incorrect.");
Instant::now()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this matters, but this is a change in behavior from before. This is updating the time with Instant::now(), while the old code was skipping updating the time if nothing was received. I'm not sure if either way is more right or wrong as skipping an update could be just as bad as assuming Instant::now() depending on what caused the time not to be sent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure either but it's probably not expected behavior. I think it might be safer to skip updating like before because at least then future delta time values will remain some what accurate. Then again I don't really know. Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can keep the current behavior for now. With the way bevy is sending the time from render right now this shouldn't ever be hit. Issues would only arise when people are doing custom stuff. In those cases, I'm not sure what the better behavior would be. We can just punt that into the future when we have more concrete evidence of what is better. It'll be easy to change things to skip the update if this is found to be problematic.

@alice-i-cecile
Copy link
Member

Can you update the PR description and title to reflect the new changes?

@maniwani maniwani self-requested a review October 14, 2022 14:36
@ShinySapphic ShinySapphic changed the title Add update_with_instant method to App Add TimeUpdateStrategy resource for manual Time updating Oct 14, 2022
@alice-i-cecile alice-i-cecile added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Oct 18, 2022
Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description is still outdated and the comments should be resolved. Do fix that for us if you notice to make writing patch notes easier? I won't block on it though.

bors r+

bors bot pushed a commit that referenced this pull request Oct 24, 2022
# Objective

- Addresses #6146 by allowing manual `Time` updating

## Solution
- Create `TimeUpdateStrategy` config resource
- Allow users to specify a manual `Instant/Duration` or leave as default (automatic)
- Get resource in `bevy_time::time_system`and update time with desired value
---

## Changelog

- Add `TimeUpdateStrategy` resource
- Update `bevy_time::time_system` to use optional manual values

Co-authored-by: BuildTools <unconfigured@null.spigotmc.org>
Co-authored-by: Lucidus115 <92978847+Lucidus115@users.noreply.github.com>
@bors
Copy link
Contributor

bors bot commented Oct 24, 2022

Build failed (retrying...):

bors bot pushed a commit that referenced this pull request Oct 24, 2022
# Objective

- Addresses #6146 by allowing manual `Time` updating

## Solution
- Create `TimeUpdateStrategy` config resource
- Allow users to specify a manual `Instant/Duration` or leave as default (automatic)
- Get resource in `bevy_time::time_system`and update time with desired value
---

## Changelog

- Add `TimeUpdateStrategy` resource
- Update `bevy_time::time_system` to use optional manual values

Co-authored-by: BuildTools <unconfigured@null.spigotmc.org>
Co-authored-by: Lucidus115 <92978847+Lucidus115@users.noreply.github.com>
@bors bors bot changed the title Add TimeUpdateStrategy resource for manual Time updating [Merged by Bors] - Add TimeUpdateStrategy resource for manual Time updating Oct 24, 2022
@bors bors bot closed this Oct 24, 2022
@mockersf mockersf added the hacktoberfest-accepted A PR that was accepted for Hacktoberfest, an annual open source event label Oct 24, 2022
bors bot pushed a commit that referenced this pull request Oct 24, 2022
# Objective

- Fixes #6355 

## Solution

- Add the removed local bool from #6159
@hymm
Copy link
Contributor

hymm commented Oct 24, 2022

Might be worth adding the breaking change label to this PR as it changes the behavior of time.delta on startup.

Before it would be [0, 0, correct] and this PR changes it to be [0, "approximately the time between the time_system and present_frame", correct].

@hymm hymm added the C-Breaking-Change A breaking change to Bevy's public API that needs to be noted in a migration guide label Oct 24, 2022
james7132 pushed a commit to james7132/bevy that referenced this pull request Oct 28, 2022
…ine#6159)

# Objective

- Addresses bevyengine#6146 by allowing manual `Time` updating

## Solution
- Create `TimeUpdateStrategy` config resource
- Allow users to specify a manual `Instant/Duration` or leave as default (automatic)
- Get resource in `bevy_time::time_system`and update time with desired value
---

## Changelog

- Add `TimeUpdateStrategy` resource
- Update `bevy_time::time_system` to use optional manual values

Co-authored-by: BuildTools <unconfigured@null.spigotmc.org>
Co-authored-by: Lucidus115 <92978847+Lucidus115@users.noreply.github.com>
james7132 pushed a commit to james7132/bevy that referenced this pull request Oct 28, 2022
# Objective

- Fixes bevyengine#6355 

## Solution

- Add the removed local bool from bevyengine#6159
Pietrek14 pushed a commit to Pietrek14/bevy that referenced this pull request Dec 17, 2022
…ine#6159)

# Objective

- Addresses bevyengine#6146 by allowing manual `Time` updating

## Solution
- Create `TimeUpdateStrategy` config resource
- Allow users to specify a manual `Instant/Duration` or leave as default (automatic)
- Get resource in `bevy_time::time_system`and update time with desired value
---

## Changelog

- Add `TimeUpdateStrategy` resource
- Update `bevy_time::time_system` to use optional manual values

Co-authored-by: BuildTools <unconfigured@null.spigotmc.org>
Co-authored-by: Lucidus115 <92978847+Lucidus115@users.noreply.github.com>
Pietrek14 pushed a commit to Pietrek14/bevy that referenced this pull request Dec 17, 2022
# Objective

- Fixes bevyengine#6355 

## Solution

- Add the removed local bool from bevyengine#6159
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
…ine#6159)

# Objective

- Addresses bevyengine#6146 by allowing manual `Time` updating

## Solution
- Create `TimeUpdateStrategy` config resource
- Allow users to specify a manual `Instant/Duration` or leave as default (automatic)
- Get resource in `bevy_time::time_system`and update time with desired value
---

## Changelog

- Add `TimeUpdateStrategy` resource
- Update `bevy_time::time_system` to use optional manual values

Co-authored-by: BuildTools <unconfigured@null.spigotmc.org>
Co-authored-by: Lucidus115 <92978847+Lucidus115@users.noreply.github.com>
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
# Objective

- Fixes bevyengine#6355 

## Solution

- Add the removed local bool from bevyengine#6159
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-App Bevy apps and plugins A-Time Involves time keeping and reporting C-Breaking-Change A breaking change to Bevy's public API that needs to be noted in a migration guide C-Testing A change that impacts how we test Bevy or how users test their apps C-Usability A simple quality-of-life change that makes Bevy easier to use hacktoberfest-accepted A PR that was accepted for Hacktoberfest, an annual open source event S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants