pebble/assets/
asset_plugin.rs1use crate::{
2 app::SystemStage,
3 assets::{
4 storage::{Assets, GPUAssets},
5 upload::DeviceUpload,
6 },
7 plugin::Plugin,
8 rendering::backend::Backend,
9 system::{Res, ResMut},
10};
11
12pub struct DeviceAssetPlugin<B: Backend, T: DeviceUpload<B>> {
13 _marker: std::marker::PhantomData<(B, T)>,
14}
15
16impl<B: Backend, T: DeviceUpload<B>> DeviceAssetPlugin<B, T> {
17 pub fn new() -> Self {
18 Self {
19 _marker: std::marker::PhantomData,
20 }
21 }
22}
23
24impl<B, T> Plugin for DeviceAssetPlugin<B, T>
25where
26 B: Backend,
27 T: DeviceUpload<B>,
28{
29 fn build(&self, app: &mut crate::prelude::App) {
30 app.try_insert_resource(Assets::<T::Source>::new());
31 app.try_insert_resource(GPUAssets::<T>::new());
32 app.add_system(SystemStage::AssetSync, sync_device_assets::<B, T>);
33 }
34}
35
36fn sync_device_assets<B, T>(
37 mut cpu: ResMut<Assets<T::Source>>,
38 mut gpu: ResMut<GPUAssets<T>>,
39 backend: Option<Res<B>>,
40) where
41 B: Backend,
42 T: DeviceUpload<B>,
43{
44 let Some(device) = backend else { return };
45 for handle in cpu.take_dirty() {
46 if let Some(source) = cpu.get(handle) {
47 gpu.insert(handle, T::upload(source, &device));
48 } else {
49 tracing::warn!("Dirty asset handle removed before GPU sync");
50 }
51 }
52}