bevy_render/
gpu_component_array_buffer.rs1use crate::{
2 render_resource::{GpuArrayBuffer, GpuArrayBufferable},
3 renderer::{RenderDevice, RenderQueue},
4 Render, RenderApp, RenderSet,
5};
6use bevy_app::{App, Plugin};
7use bevy_ecs::{
8 prelude::{Component, Entity},
9 schedule::IntoSystemConfigs,
10 system::{Commands, Query, Res, ResMut},
11};
12use core::marker::PhantomData;
13
14pub struct GpuComponentArrayBufferPlugin<C: Component + GpuArrayBufferable>(PhantomData<C>);
17
18impl<C: Component + GpuArrayBufferable> Plugin for GpuComponentArrayBufferPlugin<C> {
19 fn build(&self, app: &mut App) {
20 if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
21 render_app.add_systems(
22 Render,
23 prepare_gpu_component_array_buffers::<C>.in_set(RenderSet::PrepareResources),
24 );
25 }
26 }
27
28 fn finish(&self, app: &mut App) {
29 if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
30 render_app.insert_resource(GpuArrayBuffer::<C>::new(
31 render_app.world().resource::<RenderDevice>(),
32 ));
33 }
34 }
35}
36
37impl<C: Component + GpuArrayBufferable> Default for GpuComponentArrayBufferPlugin<C> {
38 fn default() -> Self {
39 Self(PhantomData::<C>)
40 }
41}
42
43fn prepare_gpu_component_array_buffers<C: Component + GpuArrayBufferable>(
44 mut commands: Commands,
45 render_device: Res<RenderDevice>,
46 render_queue: Res<RenderQueue>,
47 mut gpu_array_buffer: ResMut<GpuArrayBuffer<C>>,
48 components: Query<(Entity, &C)>,
49) {
50 gpu_array_buffer.clear();
51
52 let entities = components
53 .iter()
54 .map(|(entity, component)| (entity, gpu_array_buffer.push(component.clone())))
55 .collect::<Vec<_>>();
56 commands.insert_or_spawn_batch(entities);
57
58 gpu_array_buffer.write_buffer(&render_device, &render_queue);
59}