#![warn(missing_docs)] //! This crate provides core functionality for Bevy Engine. mod name; #[cfg(feature = "serialize")] mod serde; mod task_pool_options; use bevy_ecs::system::{ResMut, Resource}; pub use bytemuck::{bytes_of, cast_slice, Pod, Zeroable}; pub use name::*; pub use task_pool_options::*; pub mod prelude { //! The Bevy Core Prelude. #[doc(hidden)] pub use crate::{ FrameCountPlugin, Name, TaskPoolOptions, TaskPoolPlugin, TypeRegistrationPlugin, }; } use bevy_app::prelude::*; use bevy_ecs::entity::Entity; use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; use bevy_utils::{Duration, HashSet, Instant}; use std::borrow::Cow; use std::ffi::OsString; use std::ops::Range; use std::path::PathBuf; #[cfg(not(target_arch = "wasm32"))] use bevy_ecs::schedule::IntoSystemDescriptor; #[cfg(not(target_arch = "wasm32"))] use bevy_tasks::tick_global_task_pools_on_main_thread; /// Registration of default types to the `TypeRegistry` reesource. #[derive(Default)] pub struct TypeRegistrationPlugin; impl Plugin for TypeRegistrationPlugin { fn build(&self, app: &mut App) { app.register_type::().register_type::(); register_rust_types(app); register_math_types(app); } } fn register_rust_types(app: &mut App) { app.register_type::>() .register_type_data::, ReflectSerialize>() .register_type_data::, ReflectDeserialize>() .register_type::() .register_type::() .register_type::() .register_type::>() .register_type::>() .register_type::>() .register_type::() .register_type::(); } fn register_math_types(app: &mut App) { app.register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::(); } /// Setup of default task pools: `AsyncComputeTaskPool`, `ComputeTaskPool`, `IoTaskPool`. #[derive(Default)] pub struct TaskPoolPlugin { /// Options for the [`TaskPool`](bevy_tasks::TaskPool) created at application start. pub task_pool_options: TaskPoolOptions, } impl Plugin for TaskPoolPlugin { fn build(&self, app: &mut App) { // Setup the default bevy task pools self.task_pool_options.create_default_pools(); #[cfg(not(target_arch = "wasm32"))] app.add_system_to_stage( bevy_app::CoreStage::Last, tick_global_task_pools_on_main_thread.at_end(), ); } } /// Keeps a count of rendered frames since the start of the app /// /// Wraps to 0 when it reaches the maximum u32 value #[derive(Default, Resource, Clone, Copy)] 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::(); app.add_system(update_frame_count); } } fn update_frame_count(mut frame_count: ResMut) { frame_count.0 = frame_count.0.wrapping_add(1); } #[cfg(test)] mod tests { use super::*; use bevy_tasks::prelude::{AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool}; #[test] fn runs_spawn_local_tasks() { let mut app = App::new(); app.add_plugin(TaskPoolPlugin::default()); app.add_plugin(TypeRegistrationPlugin::default()); let (async_tx, async_rx) = crossbeam_channel::unbounded(); AsyncComputeTaskPool::get() .spawn_local(async move { async_tx.send(()).unwrap(); }) .detach(); let (compute_tx, compute_rx) = crossbeam_channel::unbounded(); ComputeTaskPool::get() .spawn_local(async move { compute_tx.send(()).unwrap(); }) .detach(); let (io_tx, io_rx) = crossbeam_channel::unbounded(); IoTaskPool::get() .spawn_local(async move { io_tx.send(()).unwrap(); }) .detach(); app.run(); async_rx.try_recv().unwrap(); compute_rx.try_recv().unwrap(); io_rx.try_recv().unwrap(); } #[test] fn frame_counter_update() { let mut app = App::new(); app.add_plugin(TaskPoolPlugin::default()); app.add_plugin(TypeRegistrationPlugin::default()); app.add_plugin(FrameCountPlugin::default()); app.update(); let frame_count = app.world.resource::(); assert_eq!(1, frame_count.0); } }