pebble/assets/
dependent_asset_plugin.rs1use crate::{
2 app::SystemStage,
3 assets::storage::{Assets, GPUAssets},
4 plugin::Plugin,
5 system::{Res, ResMut},
6};
7
8macro_rules! impl_dependent_asset {
9 ($plugin:ident, $trait_name:ident, $sync_fn:ident, $($dep_ty:ident : $dep_var:ident),+) => {
10 pub trait $trait_name<B, $($dep_ty),+>: 'static + Send + Sync + Sized
11 where $($dep_ty: 'static + Send + Sync),+
12 {
13 type Source: 'static + Send + Sync;
14 fn upload(source: &Self::Source, backend: &B, $($dep_var: &$dep_ty),+) -> Self;
15 }
16 pub struct $plugin<B, T, $($dep_ty),+>(std::marker::PhantomData<(B, T, $($dep_ty),+)>);
17 impl<B, T, $($dep_ty),+> $plugin<B, T, $($dep_ty),+> {
18 pub fn new() -> Self { Self(std::marker::PhantomData) }
19 }
20 impl<B, T, $($dep_ty),+> Plugin for $plugin<B, T, $($dep_ty),+>
21 where
22 B: 'static + Send + Sync,
23 $($dep_ty: 'static + Send + Sync,)+
24 T: $trait_name<B, $($dep_ty),+>,
25 {
26 fn build(&self, app: &mut crate::app::App) {
27 app.try_insert_resource(Assets::<T::Source>::new());
28 app.try_insert_resource(GPUAssets::<T>::new());
29 app.add_system(SystemStage::AssetSyncDeps, $sync_fn::<B, T, $($dep_ty),+>);
30 }
31 }
32 #[allow(clippy::too_many_arguments)]
33 fn $sync_fn<B, T, $($dep_ty),+>(
34 mut cpu: ResMut<Assets<T::Source>>,
35 mut gpu: ResMut<GPUAssets<T>>,
36 backend: Option<Res<B>>,
37 $($dep_var: Option<Res<$dep_ty>>),+
38 ) where
39 B: 'static + Send + Sync,
40 $($dep_ty: 'static + Send + Sync,)+
41 T: $trait_name<B, $($dep_ty),+>,
42 {
43 let Some(backend) = backend else { return };
44 $(let Some($dep_var) = $dep_var else { return };)+
45 for handle in cpu.take_dirty() {
46 if let Some(source) = cpu.get(handle) {
47 gpu.insert(handle, T::upload(source, &backend, $(&$dep_var),+));
48 } else {
49 tracing::warn!("Dirty asset handle removed before GPU sync");
50 }
51 }
52 }
53 };
54}
55
56impl_dependent_asset!(
57 DependentAssetPlugin1, DependentUpload1, sync_dependent1,
58 Dep1: dep1
59);
60impl_dependent_asset!(
61 DependentAssetPlugin2, DependentUpload2, sync_dependent2,
62 Dep1: dep1, Dep2: dep2
63);
64impl_dependent_asset!(
65 DependentAssetPlugin3, DependentUpload3, sync_dependent3,
66 Dep1: dep1, Dep2: dep2, Dep3: dep3
67);
68impl_dependent_asset!(
69 DependentAssetPlugin4, DependentUpload4, sync_dependent4,
70 Dep1: dep1, Dep2: dep2, Dep3: dep3, Dep4: dep4
71);