Add change detection to `Manifest`

main
copygirl 3 weeks ago
parent a436180ae4
commit be253e8cb7
  1. 44
      common/src/assets/manifest.rs

@ -76,6 +76,11 @@ pub struct Manifest<'w, T: ManifestEntry> {
} }
impl<T: ManifestEntry> Manifest<'_, T> { impl<T: ManifestEntry> Manifest<'_, T> {
/// System condition which returns `true` if this manifest was added or changed.
pub fn changed(res: Option<Res<ManifestResource<T>>>) -> bool {
resource_exists_and_changed(res)
}
/// Looks up an [`Asset`] of type `T` from its associated manifest. /// Looks up an [`Asset`] of type `T` from its associated manifest.
/// ///
/// Returns `None` if an asset with the given identifier is missing from /// Returns `None` if an asset with the given identifier is missing from
@ -90,6 +95,31 @@ impl<T: ManifestEntry> Manifest<'_, T> {
let entry = self.entry_assets.get(entry_handle).unwrap(); let entry = self.entry_assets.get(entry_handle).unwrap();
Some(entry) Some(entry)
} }
pub fn iter(&self) -> impl Iterator<Item = &T> {
let Some(manifest_handle) = self.resource.as_deref().map(|res| &res.handle) else {
return ManifestIter(None);
};
// // SAFETY: Manifest loads this as a dependency, so it should exist.
let manifest = self.manifest_assets.get(manifest_handle).unwrap();
let values = manifest.map.values();
// // SAFETY: Entry loads this as a dependency, so they should exist.
let iter = values.map(|h| self.entry_assets.get(h).unwrap());
ManifestIter(Some(iter))
}
}
struct ManifestIter<I>(Option<I>);
impl<'a, T, I> Iterator for ManifestIter<I>
where
T: ManifestEntry,
I: Iterator<Item = &'a T>,
{
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.0.as_mut().and_then(|i| i.next())
}
} }
pub trait InitManifest { pub trait InitManifest {
@ -105,5 +135,19 @@ impl InitManifest for App {
// Insert a `Resource` that holds a handle to the `ManifestAsset` once it's loaded. // Insert a `Resource` that holds a handle to the `ManifestAsset` once it's loaded.
let handle = self.world_mut().load_asset(path); let handle = self.world_mut().load_asset(path);
self.load_resource_with(ManifestResource::<T> { handle }); self.load_resource_with(ManifestResource::<T> { handle });
self.add_systems(PostUpdate, trigger_change_on_loaded::<T>);
}
}
fn trigger_change_on_loaded<T: ManifestEntry>(
mut events: MessageReader<AssetEvent<ManifestAsset<T>>>,
mut resource: Option<ResMut<ManifestResource<T>>>,
) {
for event in events.read() {
if let AssetEvent::LoadedWithDependencies { id: _ } = event {
// Trigger change detection on the `ManifestResource`.
resource.as_deref_mut();
}
} }
} }

Loading…
Cancel
Save