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).
This commit is contained in:
Zachary Harrold 2024-12-20 05:36:51 +11:00 committed by GitHub
parent d4b07a5114
commit 21786632c3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
39 changed files with 305 additions and 319 deletions

View File

@ -7,7 +7,7 @@
entities: {
4294967296: (
components: {
"bevy_core::name::Name": (
"bevy_ecs::name::Name": (
hash: 17588334858059901562,
name: "joe",
),

View File

@ -13,7 +13,6 @@ keywords = ["bevy"]
bevy_app = { path = "../bevy_app", version = "0.15.0-dev" }
bevy_asset = { path = "../bevy_asset", version = "0.15.0-dev" }
bevy_color = { path = "../bevy_color", version = "0.15.0-dev" }
bevy_core = { path = "../bevy_core", version = "0.15.0-dev" }
bevy_derive = { path = "../bevy_derive", version = "0.15.0-dev" }
bevy_log = { path = "../bevy_log", version = "0.15.0-dev" }
bevy_math = { path = "../bevy_math", version = "0.15.0-dev" }

View File

@ -55,11 +55,20 @@ std = [
## `critical-section` provides the building blocks for synchronization primitives
## on all platforms, including `no_std`.
critical-section = ["bevy_tasks?/critical-section", "bevy_ecs/critical-section"]
critical-section = [
"portable-atomic?/critical-section",
"bevy_tasks?/critical-section",
"bevy_ecs/critical-section",
]
## `portable-atomic` provides additional platform support for atomic types and
## operations, even on targets without native support.
portable-atomic = ["bevy_tasks?/portable-atomic", "bevy_ecs/portable-atomic"]
portable-atomic = [
"dep:portable-atomic",
"dep:portable-atomic-util",
"bevy_tasks?/portable-atomic",
"bevy_ecs/portable-atomic",
]
[dependencies]
# bevy
@ -77,6 +86,12 @@ thiserror = { version = "2", default-features = false }
variadics_please = "1.1"
tracing = { version = "0.1", default-features = false, optional = true }
log = { version = "0.4", default-features = false }
portable-atomic = { version = "1", default-features = false, features = [
"fallback",
], optional = true }
portable-atomic-util = { version = "0.2.4", features = [
"alloc",
], optional = true }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
ctrlc = { version = "3.4.4", optional = true }
@ -86,6 +101,9 @@ wasm-bindgen = { version = "0.2" }
web-sys = { version = "0.3", features = ["Window"] }
console_error_panic_hook = "0.1.6"
[dev-dependencies]
crossbeam-channel = "0.5.0"
[lints]
workspace = true

View File

@ -103,7 +103,10 @@ impl Default for App {
app.sub_apps.main.update_schedule = Some(Main.intern());
#[cfg(feature = "bevy_reflect")]
app.init_resource::<AppTypeRegistry>();
{
app.init_resource::<AppTypeRegistry>();
app.register_type::<Name>();
}
#[cfg(feature = "reflect_functions")]
app.init_resource::<AppFunctionRegistry>();

View File

@ -24,6 +24,8 @@ mod plugin;
mod plugin_group;
mod schedule_runner;
mod sub_app;
#[cfg(feature = "bevy_tasks")]
mod task_pool_plugin;
#[cfg(all(not(target_arch = "wasm32"), feature = "std"))]
mod terminal_ctrl_c_handler;
@ -34,6 +36,8 @@ pub use plugin::*;
pub use plugin_group::*;
pub use schedule_runner::*;
pub use sub_app::*;
#[cfg(feature = "bevy_tasks")]
pub use task_pool_plugin::*;
#[cfg(all(not(target_arch = "wasm32"), feature = "std"))]
pub use terminal_ctrl_c_handler::*;
@ -52,4 +56,8 @@ pub mod prelude {
sub_app::SubApp,
Plugin, PluginGroup,
};
#[cfg(feature = "bevy_tasks")]
#[doc(hidden)]
pub use crate::{NonSendMarker, TaskPoolOptions, TaskPoolPlugin};
}

View File

@ -1,8 +1,55 @@
use bevy_tasks::{AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool, TaskPoolBuilder};
use bevy_utils::tracing::trace;
#![cfg_attr(
feature = "portable-atomic",
expect(
clippy::redundant_closure,
reason = "portable_atomic_util::Arc has subtly different implicit behavior"
)
)]
use crate::{App, Last, Plugin};
use alloc::string::ToString;
use bevy_ecs::prelude::*;
use bevy_tasks::{AsyncComputeTaskPool, ComputeTaskPool, IoTaskPool, TaskPoolBuilder};
use core::{fmt::Debug, marker::PhantomData};
use log::trace;
#[cfg(feature = "portable-atomic")]
use portable_atomic_util::Arc;
#[cfg(not(feature = "portable-atomic"))]
use alloc::sync::Arc;
use core::fmt::Debug;
#[cfg(not(target_arch = "wasm32"))]
use bevy_tasks::tick_global_task_pools_on_main_thread;
/// 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_systems(Last, tick_global_task_pools);
}
}
/// A dummy type that is [`!Send`](Send), to force systems to run on the main thread.
pub struct NonSendMarker(PhantomData<*mut ()>);
/// A system used to check and advanced our task pools.
///
/// Calls [`tick_global_task_pools_on_main_thread`],
/// and uses [`NonSendMarker`] to ensure that this system runs on the main thread
#[cfg(not(target_arch = "wasm32"))]
fn tick_global_task_pools(_main_thread_marker: Option<NonSend<NonSendMarker>>) {
tick_global_task_pools_on_main_thread();
}
/// Defines a simple way to determine how many threads to use given the number of remaining cores
/// and number of total cores
@ -37,7 +84,14 @@ impl TaskPoolThreadAssignmentPolicy {
/// Determine the number of threads to use for this task pool
fn get_number_of_threads(&self, remaining_threads: usize, total_threads: usize) -> usize {
assert!(self.percent >= 0.0);
let mut desired = (total_threads as f32 * self.percent).round() as usize;
let proportion = total_threads as f32 * self.percent;
let mut desired = proportion as usize;
// Equivalent to round() for positive floats without libm requirement for
// no_std compatibility
if proportion - desired as f32 >= 0.5 {
desired += 1;
}
// Limit ourselves to the number of cores available
desired = desired.min(remaining_threads);
@ -50,7 +104,7 @@ impl TaskPoolThreadAssignmentPolicy {
}
/// Helper for configuring and creating the default task pools. For end-users who want full control,
/// set up [`TaskPoolPlugin`](super::TaskPoolPlugin)
/// set up [`TaskPoolPlugin`]
#[derive(Clone, Debug)]
pub struct TaskPoolOptions {
/// If the number of physical cores is less than `min_total_threads`, force using
@ -208,3 +262,42 @@ impl TaskPoolOptions {
}
}
}
#[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_plugins(TaskPoolPlugin::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();
}
}

View File

@ -65,7 +65,6 @@ js-sys = "0.3"
notify-debouncer-full = { version = "0.4.0", optional = true }
[dev-dependencies]
bevy_core = { path = "../bevy_core", version = "0.15.0-dev" }
bevy_log = { path = "../bevy_log", version = "0.15.0-dev" }
[lints]

View File

@ -296,8 +296,7 @@ mod tests {
use core::num::NonZero;
use crate::{AssetApp, Assets};
use bevy_app::{App, AppExit, Last, Startup, Update};
use bevy_core::TaskPoolPlugin;
use bevy_app::{App, AppExit, Last, Startup, TaskPoolPlugin, Update};
use bevy_ecs::schedule::IntoSystemConfigs;
use bevy_ecs::{
component::Component,

View File

@ -633,8 +633,7 @@ mod tests {
AssetPlugin, AssetServer, Assets,
};
use alloc::sync::Arc;
use bevy_app::{App, Update};
use bevy_core::TaskPoolPlugin;
use bevy_app::{App, TaskPoolPlugin, Update};
use bevy_ecs::{
event::EventCursor,
prelude::*,

View File

@ -1,42 +0,0 @@
[package]
name = "bevy_core"
version = "0.15.0-dev"
edition = "2021"
description = "Provides core functionality for Bevy Engine"
homepage = "https://bevyengine.org"
repository = "https://github.com/bevyengine/bevy"
license = "MIT OR Apache-2.0"
keywords = ["bevy"]
[dependencies]
# bevy
bevy_app = { path = "../bevy_app", version = "0.15.0-dev", default-features = false }
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev", default-features = false }
bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [
"bevy",
], optional = true }
bevy_tasks = { path = "../bevy_tasks", version = "0.15.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" }
# other
serde = { version = "1.0", optional = true }
[features]
default = ["bevy_reflect"]
bevy_reflect = [
"dep:bevy_reflect",
"bevy_app/bevy_reflect",
"bevy_ecs/bevy_reflect",
]
serialize = ["dep:serde"]
[dev-dependencies]
crossbeam-channel = "0.5.0"
serde_test = "1.0"
[lints]
workspace = true
[package.metadata.docs.rs]
rustdoc-args = ["-Zunstable-options", "--generate-link-to-definition"]
all-features = true

View File

@ -1,7 +0,0 @@
# Bevy Core
[![License](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](https://github.com/bevyengine/bevy#license)
[![Crates.io](https://img.shields.io/crates/v/bevy_core.svg)](https://crates.io/crates/bevy_core)
[![Downloads](https://img.shields.io/crates/d/bevy_core.svg)](https://crates.io/crates/bevy_core)
[![Docs](https://docs.rs/bevy_core/badge.svg)](https://docs.rs/bevy_core/latest/bevy_core/)
[![Discord](https://img.shields.io/discord/691052431525675048.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/bevy)

View File

@ -1,157 +0,0 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![forbid(unsafe_code)]
#![doc(
html_logo_url = "https://bevyengine.org/assets/icon.png",
html_favicon_url = "https://bevyengine.org/assets/icon.png"
)]
//! This crate provides core functionality for Bevy Engine.
extern crate alloc;
#[cfg(feature = "serialize")]
mod serde;
mod task_pool_options;
use bevy_ecs::system::Resource;
pub use task_pool_options::*;
/// The core prelude.
///
/// This includes the most common types in this crate, re-exported for your convenience.
pub mod prelude {
#[doc(hidden)]
pub use crate::{FrameCountPlugin, TaskPoolOptions, TaskPoolPlugin, TypeRegistrationPlugin};
}
use bevy_app::prelude::*;
use bevy_ecs::prelude::*;
use core::marker::PhantomData;
#[cfg(not(target_arch = "wasm32"))]
use bevy_tasks::tick_global_task_pools_on_main_thread;
/// Registration of default types to the [`TypeRegistry`](bevy_reflect::TypeRegistry) resource.
#[derive(Default)]
pub struct TypeRegistrationPlugin;
impl Plugin for TypeRegistrationPlugin {
#[cfg_attr(not(feature = "bevy_reflect"), allow(unused_variables))]
fn build(&self, app: &mut App) {
#[cfg(feature = "bevy_reflect")]
app.register_type::<Name>();
}
}
/// Setup of default task pools: [`AsyncComputeTaskPool`](bevy_tasks::AsyncComputeTaskPool),
/// [`ComputeTaskPool`](bevy_tasks::ComputeTaskPool), [`IoTaskPool`](bevy_tasks::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_systems(Last, tick_global_task_pools);
}
}
/// A dummy type that is [`!Send`](Send), to force systems to run on the main thread.
pub struct NonSendMarker(PhantomData<*mut ()>);
/// A system used to check and advanced our task pools.
///
/// Calls [`tick_global_task_pools_on_main_thread`],
/// and uses [`NonSendMarker`] to ensure that this system runs on the main thread
#[cfg(not(target_arch = "wasm32"))]
fn tick_global_task_pools(_main_thread_marker: Option<NonSend<NonSendMarker>>) {
tick_global_task_pools_on_main_thread();
}
/// 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(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_plugins((TaskPoolPlugin::default(), TypeRegistrationPlugin));
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_plugins((
TaskPoolPlugin::default(),
TypeRegistrationPlugin,
FrameCountPlugin,
));
app.update();
let frame_count = app.world().resource::<FrameCount>();
assert_eq!(1, frame_count.0);
}
}

View File

@ -1,54 +0,0 @@
use core::{
any,
fmt::{self, Formatter},
};
use serde::{
de::{Error, Visitor},
Deserialize, Deserializer, Serialize, Serializer,
};
use super::FrameCount;
// 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)
}
}
impl<'de> Deserialize<'de> for FrameCount {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_u32(FrameVisitor)
}
}
struct FrameVisitor;
impl<'de> Visitor<'de> for FrameVisitor {
type Value = FrameCount;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str(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::*;
use serde_test::{assert_tokens, Token};
#[test]
fn test_serde_frame_count() {
let frame_count = FrameCount(100);
assert_tokens(&frame_count, &[Token::U32(100)]);
}
}

View File

@ -24,9 +24,9 @@ smaa_luts = ["bevy_render/ktx2", "bevy_image/ktx2", "bevy_image/zstd"]
# bevy
bevy_app = { path = "../bevy_app", version = "0.15.0-dev" }
bevy_asset = { path = "../bevy_asset", version = "0.15.0-dev" }
bevy_core = { path = "../bevy_core", version = "0.15.0-dev" }
bevy_color = { path = "../bevy_color", version = "0.15.0-dev" }
bevy_derive = { path = "../bevy_derive", version = "0.15.0-dev" }
bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.15.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev" }
bevy_image = { path = "../bevy_image", version = "0.15.0-dev" }
bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev" }

View File

@ -8,7 +8,7 @@ use crate::{
};
use bevy_app::{App, Plugin};
use bevy_asset::{load_internal_asset, Handle};
use bevy_core::FrameCount;
use bevy_diagnostic::FrameCount;
use bevy_ecs::{
prelude::{require, Bundle, Component, Entity, ReflectComponent},
query::{QueryItem, With},

View File

@ -12,17 +12,18 @@ keywords = ["bevy"]
# Disables diagnostics that are unsupported when Bevy is dynamically linked
dynamic_linking = []
sysinfo_plugin = ["sysinfo"]
serialize = ["dep:serde"]
[dependencies]
# bevy
bevy_app = { path = "../bevy_app", version = "0.15.0-dev" }
bevy_core = { path = "../bevy_core", version = "0.15.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev" }
bevy_time = { path = "../bevy_time", version = "0.15.0-dev" }
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" }
bevy_tasks = { path = "../bevy_tasks", version = "0.15.0-dev" }
const-fnv1a-hash = "1.1.0"
serde = { version = "1.0", optional = true }
# macOS
[target.'cfg(all(target_os="macos"))'.dependencies]
@ -38,6 +39,9 @@ sysinfo = { version = "0.33.0", optional = true, default-features = false, featu
"system",
] }
[dev-dependencies]
serde_test = "1.0"
[lints]
workspace = true

View File

@ -0,0 +1,101 @@
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)]);
}
}

View File

@ -1,6 +1,5 @@
use crate::{Diagnostic, DiagnosticPath, Diagnostics, RegisterDiagnostic};
use crate::{Diagnostic, DiagnosticPath, Diagnostics, FrameCount, RegisterDiagnostic};
use bevy_app::prelude::*;
use bevy_core::FrameCount;
use bevy_ecs::prelude::*;
use bevy_time::{Real, Time};

View File

@ -14,6 +14,7 @@ extern crate alloc;
mod diagnostic;
mod entity_count_diagnostics_plugin;
mod frame_count_diagnostics_plugin;
mod frame_time_diagnostics_plugin;
mod log_diagnostics_plugin;
#[cfg(feature = "sysinfo_plugin")]
@ -22,6 +23,7 @@ mod system_information_diagnostics_plugin;
pub use diagnostic::*;
pub use entity_count_diagnostics_plugin::EntityCountDiagnosticsPlugin;
pub use frame_count_diagnostics_plugin::{update_frame_count, FrameCount, FrameCountPlugin};
pub use frame_time_diagnostics_plugin::FrameTimeDiagnosticsPlugin;
pub use log_diagnostics_plugin::LogDiagnosticsPlugin;
#[cfg(feature = "sysinfo_plugin")]

View File

@ -2,7 +2,6 @@ use alloc::{
boxed::Box,
collections::{btree_map, btree_set},
rc::Rc,
sync::Arc,
};
use core::{
@ -14,6 +13,12 @@ use core::{
use super::Entity;
#[cfg(feature = "portable-atomic")]
use portable_atomic_util::Arc;
#[cfg(not(feature = "portable-atomic"))]
use alloc::sync::Arc;
/// A trait for entity borrows.
///
/// This trait can be thought of as `Borrow<Entity>`, but yielding `Entity` directly.

View File

@ -45,7 +45,7 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
reflect(Deserialize, Serialize)
)]
pub struct Name {
hash: u64, // Won't be serialized (see: `bevy_core::serde` module)
hash: u64, // Won't be serialized
name: Cow<'static, str>,
}

View File

@ -1,15 +1,19 @@
use alloc::{boxed::Box, sync::Arc, vec::Vec};
use core::any::Any;
use std::sync::{Mutex, MutexGuard};
use alloc::{boxed::Box, vec::Vec};
use bevy_tasks::{ComputeTaskPool, Scope, TaskPool, ThreadExecutor};
use bevy_utils::{default, syncunsafecell::SyncUnsafeCell};
use core::panic::AssertUnwindSafe;
use concurrent_queue::ConcurrentQueue;
use core::{any::Any, panic::AssertUnwindSafe};
use fixedbitset::FixedBitSet;
use std::sync::{Mutex, MutexGuard};
#[cfg(feature = "trace")]
use tracing::{info_span, Span};
use concurrent_queue::ConcurrentQueue;
use fixedbitset::FixedBitSet;
#[cfg(feature = "portable-atomic")]
use portable_atomic_util::Arc;
#[cfg(not(feature = "portable-atomic"))]
use alloc::sync::Arc;
use crate::{
archetype::ArchetypeComponentId,

View File

@ -22,7 +22,6 @@ bevy_animation = { path = "../bevy_animation", version = "0.15.0-dev", optional
bevy_app = { path = "../bevy_app", version = "0.15.0-dev" }
bevy_asset = { path = "../bevy_asset", version = "0.15.0-dev" }
bevy_color = { path = "../bevy_color", version = "0.15.0-dev" }
bevy_core = { path = "../bevy_core", version = "0.15.0-dev" }
bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.15.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev" }
bevy_hierarchy = { path = "../bevy_hierarchy", version = "0.15.0-dev" }

View File

@ -2260,7 +2260,7 @@ mod test {
use std::path::Path;
use crate::{Gltf, GltfAssetLabel, GltfNode, GltfSkin};
use bevy_app::App;
use bevy_app::{App, TaskPoolPlugin};
use bevy_asset::{
io::{
memory::{Dir, MemoryAssetReader},
@ -2268,7 +2268,6 @@ mod test {
},
AssetApp, AssetPlugin, AssetServer, Assets, Handle, LoadState,
};
use bevy_core::TaskPoolPlugin;
use bevy_ecs::{system::Resource, world::World};
use bevy_log::LogPlugin;
use bevy_render::mesh::{skinning::SkinnedMeshInverseBindposes, MeshPlugin};

View File

@ -11,13 +11,12 @@ keywords = ["bevy"]
[features]
default = ["bevy_app"]
trace = []
bevy_app = ["reflect", "dep:bevy_app", "bevy_core"]
bevy_app = ["reflect", "dep:bevy_app"]
reflect = ["bevy_ecs/bevy_reflect", "bevy_reflect"]
[dependencies]
# bevy
bevy_app = { path = "../bevy_app", version = "0.15.0-dev", optional = true }
bevy_core = { path = "../bevy_core", version = "0.15.0-dev", optional = true }
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev", default-features = false }
bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [
"bevy",

View File

@ -21,7 +21,6 @@ serialize = ["serde", "smol_str/serde"]
[dependencies]
# bevy
bevy_app = { path = "../bevy_app", version = "0.15.0-dev", default-features = false }
bevy_core = { path = "../bevy_core", version = "0.15.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev", default-features = false, features = [
"serialize",
] }

View File

@ -88,7 +88,6 @@ shader_format_spirv = ["bevy_render/shader_format_spirv"]
serialize = [
"bevy_color?/serialize",
"bevy_core/serialize",
"bevy_ecs/serialize",
"bevy_input/serialize",
"bevy_math/serialize",
@ -264,7 +263,6 @@ ghost_nodes = ["bevy_ui/ghost_nodes"]
# bevy
bevy_a11y = { path = "../bevy_a11y", version = "0.15.0-dev", optional = true }
bevy_app = { path = "../bevy_app", version = "0.15.0-dev" }
bevy_core = { path = "../bevy_core", version = "0.15.0-dev" }
bevy_derive = { path = "../bevy_derive", version = "0.15.0-dev" }
bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.15.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev" }

View File

@ -5,9 +5,8 @@ plugin_group! {
pub struct DefaultPlugins {
bevy_app:::PanicHandlerPlugin,
bevy_log:::LogPlugin,
bevy_core:::TaskPoolPlugin,
bevy_core:::TypeRegistrationPlugin,
bevy_core:::FrameCountPlugin,
bevy_app:::TaskPoolPlugin,
bevy_diagnostic:::FrameCountPlugin,
bevy_time:::TimePlugin,
bevy_transform:::TransformPlugin,
bevy_hierarchy:::HierarchyPlugin,
@ -107,9 +106,8 @@ impl Plugin for IgnoreAmbiguitiesPlugin {
plugin_group! {
/// This plugin group will add the minimal plugins for a *Bevy* application:
pub struct MinimalPlugins {
bevy_core:::TaskPoolPlugin,
bevy_core:::TypeRegistrationPlugin,
bevy_core:::FrameCountPlugin,
bevy_app:::TaskPoolPlugin,
bevy_diagnostic:::FrameCountPlugin,
bevy_time:::TimePlugin,
bevy_app:::ScheduleRunnerPlugin,
#[cfg(feature = "bevy_ci_testing")]

View File

@ -24,7 +24,6 @@ pub use bevy_asset as asset;
pub use bevy_audio as audio;
#[cfg(feature = "bevy_color")]
pub use bevy_color as color;
pub use bevy_core as core;
#[cfg(feature = "bevy_core_pipeline")]
pub use bevy_core_pipeline as core_pipeline;
#[cfg(feature = "bevy_dev_tools")]

View File

@ -1,8 +1,8 @@
#[doc(hidden)]
pub use crate::{
app::prelude::*, core::prelude::*, ecs::prelude::*, hierarchy::prelude::*, input::prelude::*,
log::prelude::*, math::prelude::*, reflect::prelude::*, time::prelude::*,
transform::prelude::*, utils::prelude::*, DefaultPlugins, MinimalPlugins,
app::prelude::*, ecs::prelude::*, hierarchy::prelude::*, input::prelude::*, log::prelude::*,
math::prelude::*, reflect::prelude::*, time::prelude::*, transform::prelude::*,
utils::prelude::*, DefaultPlugins, MinimalPlugins,
};
#[doc(hidden)]

View File

@ -40,7 +40,6 @@ bevy_color = { path = "../bevy_color", version = "0.15.0-dev", features = [
"serialize",
"wgpu-types",
] }
bevy_core = { path = "../bevy_core", version = "0.15.0-dev" }
bevy_derive = { path = "../bevy_derive", version = "0.15.0-dev" }
bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.15.0-dev" }
bevy_ecs = { path = "../bevy_ecs", version = "0.15.0-dev" }

View File

@ -7,7 +7,7 @@ use crate::{
};
use bevy_app::{App, Plugin};
use bevy_asset::{load_internal_asset, Handle};
use bevy_core::FrameCount;
use bevy_diagnostic::FrameCount;
use bevy_ecs::prelude::*;
use bevy_reflect::prelude::*;
use bevy_time::Time;

View File

@ -308,7 +308,7 @@ pub fn create_surfaces(
// By accessing a NonSend resource, we tell the scheduler to put this system on the main thread,
// which is necessary for some OS's
#[cfg(any(target_os = "macos", target_os = "ios"))] _marker: Option<
NonSend<bevy_core::NonSendMarker>,
NonSend<bevy_app::NonSendMarker>,
>,
windows: Res<ExtractedWindows>,
mut window_surfaces: ResMut<WindowSurfaces>,

View File

@ -1,4 +1,3 @@
use alloc::sync::Arc;
use core::{future::Future, marker::PhantomData, mem, panic::AssertUnwindSafe};
use std::thread::{self, JoinHandle};
@ -6,6 +5,12 @@ use crate::executor::FallibleTask;
use concurrent_queue::ConcurrentQueue;
use futures_lite::FutureExt;
#[cfg(feature = "portable-atomic")]
use {alloc::boxed::Box, portable_atomic_util::Arc};
#[cfg(not(feature = "portable-atomic"))]
use alloc::sync::Arc;
use crate::{
block_on,
thread_executor::{ThreadExecutor, ThreadExecutorTicker},
@ -70,7 +75,17 @@ impl TaskPoolBuilder {
/// This is called on the thread itself and has access to all thread-local storage.
/// This will block running async tasks on the thread until the callback completes.
pub fn on_thread_spawn(mut self, f: impl Fn() + Send + Sync + 'static) -> Self {
self.on_thread_spawn = Some(Arc::new(f));
#[cfg(feature = "portable-atomic")]
let arc = {
let boxed = Box::new(f);
let boxed: Box<dyn Fn() + Send + Sync + 'static> = boxed;
Arc::from(boxed)
};
#[cfg(not(feature = "portable-atomic"))]
let arc = Arc::new(f);
self.on_thread_spawn = Some(arc);
self
}
@ -79,7 +94,17 @@ impl TaskPoolBuilder {
/// This is called on the thread itself and has access to all thread-local storage.
/// This will block thread termination until the callback completes.
pub fn on_thread_destroy(mut self, f: impl Fn() + Send + Sync + 'static) -> Self {
self.on_thread_destroy = Some(Arc::new(f));
#[cfg(feature = "portable-atomic")]
let arc = {
let boxed = Box::new(f);
let boxed: Box<dyn Fn() + Send + Sync + 'static> = boxed;
Arc::from(boxed)
};
#[cfg(not(feature = "portable-atomic"))]
let arc = Arc::new(f);
self.on_thread_destroy = Some(arc);
self
}

View File

@ -92,7 +92,7 @@ taskpool! {
(IO_TASK_POOL, IoTaskPool)
}
/// A function used by `bevy_core` to tick the global tasks pools on the main thread.
/// A function used by `bevy_app` to tick the global tasks pools on the main thread.
/// This will run a maximum of 100 local tasks per executor per call to this function.
///
/// # Warning

View File

@ -19,7 +19,7 @@
//!
//! Let's look at an example of each.
use bevy::{core::FrameCount, ecs::event::EventCursor, prelude::*};
use bevy::{diagnostic::FrameCount, ecs::event::EventCursor, prelude::*};
fn main() {
let mut app = App::new();

View File

@ -4,8 +4,7 @@
#[cfg(feature = "custom_cursor")]
use bevy::winit::cursor::CustomCursor;
use bevy::{
core::FrameCount,
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
diagnostic::{FrameCount, FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
prelude::*,
window::{CursorGrabMode, PresentMode, SystemCursorIcon, WindowLevel, WindowTheme},
winit::cursor::CursorIcon,

View File

@ -1,6 +1,6 @@
//! A test to confirm that `bevy` allows minimizing the window
//! This is run in CI to ensure that this doesn't regress again.
use bevy::{core::FrameCount, prelude::*};
use bevy::{diagnostic::FrameCount, prelude::*};
fn main() {
// TODO: Combine this with `resizing` once multiple_windows is simpler than

View File

@ -19,7 +19,6 @@ crates=(
bevy_asset/macros
bevy_asset
bevy_audio
bevy_core
bevy_diagnostic
bevy_hierarchy
bevy_transform