bevy/crates/bevy_diagnostic/src/frame_count_diagnostics_plugin.rs
Zachary Harrold 21786632c3
Remove bevy_core (#16897)
# Objective

- Fixes #16892

## Solution

- Removed `TypeRegistryPlugin` (`Name` is now automatically registered
with a default `App`)
- Moved `TaskPoolPlugin` to `bevy_app`
- Moved `FrameCountPlugin` to `bevy_diagnostic`
- Deleted now-empty `bevy_core`

## Testing

- CI

## Migration Guide

- `TypeRegistryPlugin` no longer exists. If you can't use a default
`App` but still need `Name` registered, do so manually with
`app.register_type::<Name>()`.
- References to `TaskPoolPlugin` and associated types will need to
import it from `bevy_app` instead of `bevy_core`
- References to `FrameCountPlugin` and associated types will need to
import it from `bevy_diagnostic` instead of `bevy_core`

## Notes

This strategy was agreed upon by Cart and several other members in
[Discord](https://discord.com/channels/691052431525675048/692572690833473578/1319137218312278077).
2024-12-19 18:36:51 +00:00

102 lines
2.8 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use bevy_app::prelude::*;
use bevy_ecs::prelude::*;
#[cfg(feature = "serialize")]
use serde::{
de::{Error, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
};
/// Maintains a count of frames rendered since the start of the application.
///
/// [`FrameCount`] is incremented during [`Last`], providing predictable
/// behavior: it will be 0 during the first update, 1 during the next, and so forth.
///
/// # Overflows
///
/// [`FrameCount`] will wrap to 0 after exceeding [`u32::MAX`]. Within reasonable
/// assumptions, one may exploit wrapping arithmetic to determine the number of frames
/// that have elapsed between two observations see [`u32::wrapping_sub()`].
#[derive(Debug, Default, Resource, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct FrameCount(pub u32);
/// Adds frame counting functionality to Apps.
#[derive(Default)]
pub struct FrameCountPlugin;
impl Plugin for FrameCountPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<FrameCount>();
app.add_systems(Last, update_frame_count);
}
}
/// A system used to increment [`FrameCount`] with wrapping addition.
///
/// See [`FrameCount`] for more details.
pub fn update_frame_count(mut frame_count: ResMut<FrameCount>) {
frame_count.0 = frame_count.0.wrapping_add(1);
}
#[cfg(feature = "serialize")]
// Manually implementing serialize/deserialize allows us to use a more compact representation as simple integers
impl Serialize for FrameCount {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_u32(self.0)
}
}
#[cfg(feature = "serialize")]
impl<'de> Deserialize<'de> for FrameCount {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_u32(FrameVisitor)
}
}
#[cfg(feature = "serialize")]
struct FrameVisitor;
#[cfg(feature = "serialize")]
impl<'de> Visitor<'de> for FrameVisitor {
type Value = FrameCount;
fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
formatter.write_str(core::any::type_name::<FrameCount>())
}
fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
where
E: Error,
{
Ok(FrameCount(v))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn frame_counter_update() {
let mut app = App::new();
app.add_plugins(FrameCountPlugin);
app.update();
let frame_count = app.world().resource::<FrameCount>();
assert_eq!(1, frame_count.0);
}
}
#[cfg(all(test, feature = "serialize"))]
mod serde_tests {
use super::*;
use serde_test::{assert_tokens, Token};
#[test]
fn test_serde_frame_count() {
let frame_count = FrameCount(100);
assert_tokens(&frame_count, &[Token::U32(100)]);
}
}