pebble/assets/dependent_asset_plugin.rs
1use crate::{resources::Resources, system::Res};
2
3pub trait Dependencies<'a>: Sized {
4 fn try_gather(world: &'a hecs::World, resources: &'a Resources) -> Option<Self>;
5}
6
7impl<'a> Dependencies<'a> for () {
8 fn try_gather(_world: &'a hecs::World, _resources: &'a Resources) -> Option<Self> {
9 Some(())
10 }
11}
12
13impl<'a, A: 'static + Send + Sync> Dependencies<'a> for Res<'a, A> {
14 fn try_gather(world: &'a hecs::World, resources: &'a Resources) -> Option<Self> {
15 if !resources.has_resource::<A>(world) {
16 return None;
17 }
18
19 Some(Res {
20 data: resources.get_resource(world),
21 })
22 }
23}
24
25impl<'a, A, B> Dependencies<'a> for (Res<'a, A>, Res<'a, B>)
26where
27 A: 'static + Send + Sync,
28 B: 'static + Send + Sync,
29{
30 fn try_gather(world: &'a hecs::World, resources: &'a Resources) -> Option<Self> {
31 if !resources.has_resource::<A>(world) || !resources.has_resource::<B>(world) {
32 return None;
33 }
34
35 Some((
36 Res {
37 data: resources.get_resource(world),
38 },
39 Res {
40 data: resources.get_resource(world),
41 },
42 ))
43 }
44}
45
46// macro_rules! impl_dependent_asset {
47// ($plugin:ident, $trait_name:ident, $sync_fn:ident, $($dep_ty:ident : $dep_var:ident),+) => {
48// pub trait $trait_name<B, $($dep_ty),+>: 'static + Send + Sync + Sized
49// where $($dep_ty: 'static + Send + Sync),+
50// {
51// type Source: 'static + Send + Sync;
52// fn upload(source: &Self::Source, backend: &B, $($dep_var: &$dep_ty),+) -> Self;
53// }
54// pub struct $plugin<B, T, $($dep_ty),+>(std::marker::PhantomData<(B, T, $($dep_ty),+)>);
55// impl<B, T, $($dep_ty),+> $plugin<B, T, $($dep_ty),+> {
56// pub fn new() -> Self { Self(std::marker::PhantomData) }
57// }
58// impl<B, T, $($dep_ty),+> Plugin for $plugin<B, T, $($dep_ty),+>
59// where
60// B: 'static + Send + Sync,
61// $($dep_ty: 'static + Send + Sync,)+
62// T: $trait_name<B, $($dep_ty),+>,
63// {
64// fn build(&self, app: &mut crate::app::App) {
65// app.try_insert_resource(Assets::<T::Source>::new());
66// app.try_insert_resource(GPUAssets::<T>::new());
67// app.add_system(SystemStage::AssetSyncDeps, $sync_fn::<B, T, $($dep_ty),+>);
68// }
69// }
70// #[allow(clippy::too_many_arguments)]
71// fn $sync_fn<B, T, $($dep_ty),+>(
72// mut cpu: ResMut<Assets<T::Source>>,
73// mut gpu: ResMut<GPUAssets<T>>,
74// backend: Option<Res<B>>,
75// $($dep_var: Option<Res<$dep_ty>>),+
76// ) where
77// B: 'static + Send + Sync,
78// $($dep_ty: 'static + Send + Sync,)+
79// T: $trait_name<B, $($dep_ty),+>,
80// {
81// let Some(backend) = backend else { return };
82// $(let Some($dep_var) = $dep_var else { return };)+
83// for handle in cpu.take_dirty() {
84// if let Some(source) = cpu.get(handle) {
85// gpu.insert(handle, T::upload(source, &backend, $(&$dep_var),+));
86// } else {
87// tracing::warn!("Dirty asset handle removed before GPU sync");
88// }
89// }
90// }
91// };
92// }
93//
94// impl_dependent_asset!(
95// DependentAssetPlugin1, DependentUpload1, sync_dependent1,
96// Dep1: dep1
97// );
98// impl_dependent_asset!(
99// DependentAssetPlugin2, DependentUpload2, sync_dependent2,
100// Dep1: dep1, Dep2: dep2
101// );
102// impl_dependent_asset!(
103// DependentAssetPlugin3, DependentUpload3, sync_dependent3,
104// Dep1: dep1, Dep2: dep2, Dep3: dep3
105// );
106// impl_dependent_asset!(
107// DependentAssetPlugin4, DependentUpload4, sync_dependent4,
108// Dep1: dep1, Dep2: dep2, Dep3: dep3, Dep4: dep4
109// );