Path: blob/main/crates/bevy_render/src/extract_resource.rs
6595 views
use core::marker::PhantomData;12use bevy_app::{App, Plugin};3use bevy_ecs::prelude::*;4pub use bevy_render_macros::ExtractResource;5use bevy_utils::once;67use crate::{Extract, ExtractSchedule, RenderApp};89/// Describes how a resource gets extracted for rendering.10///11/// Therefore the resource is transferred from the "main world" into the "render world"12/// in the [`ExtractSchedule`] step.13pub trait ExtractResource: Resource {14type Source: Resource;1516/// Defines how the resource is transferred into the "render world".17fn extract_resource(source: &Self::Source) -> Self;18}1920/// This plugin extracts the resources into the "render world".21///22/// Therefore it sets up the[`ExtractSchedule`] step23/// for the specified [`Resource`].24pub struct ExtractResourcePlugin<R: ExtractResource>(PhantomData<R>);2526impl<R: ExtractResource> Default for ExtractResourcePlugin<R> {27fn default() -> Self {28Self(PhantomData)29}30}3132impl<R: ExtractResource> Plugin for ExtractResourcePlugin<R> {33fn build(&self, app: &mut App) {34if let Some(render_app) = app.get_sub_app_mut(RenderApp) {35render_app.add_systems(ExtractSchedule, extract_resource::<R>);36} else {37once!(tracing::error!(38"Render app did not exist when trying to add `extract_resource` for <{}>.",39core::any::type_name::<R>()40));41}42}43}4445/// This system extracts the resource of the corresponding [`Resource`] type46pub fn extract_resource<R: ExtractResource>(47mut commands: Commands,48main_resource: Extract<Option<Res<R::Source>>>,49target_resource: Option<ResMut<R>>,50) {51if let Some(main_resource) = main_resource.as_ref() {52if let Some(mut target_resource) = target_resource {53if main_resource.is_changed() {54*target_resource = R::extract_resource(main_resource);55}56} else {57#[cfg(debug_assertions)]58if !main_resource.is_added() {59once!(tracing::warn!(60"Removing resource {} from render world not expected, adding using `Commands`.61This may decrease performance",62core::any::type_name::<R>()63));64}6566commands.insert_resource(R::extract_resource(main_resource));67}68}69}707172