use crate::{ render_resource::{GpuArrayBuffer, GpuArrayBufferable}, renderer::{RenderDevice, RenderQueue}, Render, RenderApp, RenderSet, }; use bevy_app::{App, Plugin}; use bevy_ecs::{ prelude::{Component, Entity}, schedule::IntoSystemConfigs, system::{Commands, Query, Res, ResMut}, }; use std::marker::PhantomData; /// This plugin prepares the components of the corresponding type for the GPU /// by storing them in a [`GpuArrayBuffer`]. pub struct GpuComponentArrayBufferPlugin(PhantomData); impl Plugin for GpuComponentArrayBufferPlugin { fn build(&self, app: &mut App) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { render_app.add_systems( Render, prepare_gpu_component_array_buffers::.in_set(RenderSet::Prepare), ); } } fn finish(&self, app: &mut App) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { render_app.insert_resource(GpuArrayBuffer::::new( render_app.world.resource::(), )); } } } impl Default for GpuComponentArrayBufferPlugin { fn default() -> Self { Self(PhantomData::) } } fn prepare_gpu_component_array_buffers( mut commands: Commands, render_device: Res, render_queue: Res, mut gpu_array_buffer: ResMut>, components: Query<(Entity, &C)>, ) { gpu_array_buffer.clear(); let entities = components .iter() .map(|(entity, component)| (entity, gpu_array_buffer.push(component.clone()))) .collect::>(); commands.insert_or_spawn_batch(entities); gpu_array_buffer.write_buffer(&render_device, &render_queue); }