1use crate::{Asset, AssetId, AssetLoadError, AssetPath, UntypedAssetId};
2use bevy_ecs::event::Event;
3use bevy_reflect::Reflect;
4use core::fmt::Debug;
5
6#[derive(Event, Clone, Debug)]
10pub struct AssetLoadFailedEvent<A: Asset> {
11 pub id: AssetId<A>,
13 pub path: AssetPath<'static>,
15 pub error: AssetLoadError,
17}
18
19impl<A: Asset> AssetLoadFailedEvent<A> {
20 pub fn untyped(&self) -> UntypedAssetLoadFailedEvent {
22 self.into()
23 }
24}
25
26#[derive(Event, Clone, Debug)]
28pub struct UntypedAssetLoadFailedEvent {
29 pub id: UntypedAssetId,
31 pub path: AssetPath<'static>,
33 pub error: AssetLoadError,
35}
36
37impl<A: Asset> From<&AssetLoadFailedEvent<A>> for UntypedAssetLoadFailedEvent {
38 fn from(value: &AssetLoadFailedEvent<A>) -> Self {
39 UntypedAssetLoadFailedEvent {
40 id: value.id.untyped(),
41 path: value.path.clone(),
42 error: value.error.clone(),
43 }
44 }
45}
46
47#[expect(missing_docs, reason = "Documenting the id fields is unhelpful.")]
49#[derive(Event, Reflect)]
50pub enum AssetEvent<A: Asset> {
51 Added { id: AssetId<A> },
53 Modified { id: AssetId<A> },
55 Removed { id: AssetId<A> },
57 Unused { id: AssetId<A> },
59 LoadedWithDependencies { id: AssetId<A> },
61}
62
63impl<A: Asset> AssetEvent<A> {
64 pub fn is_loaded_with_dependencies(&self, asset_id: impl Into<AssetId<A>>) -> bool {
66 matches!(self, AssetEvent::LoadedWithDependencies { id } if *id == asset_id.into())
67 }
68
69 pub fn is_added(&self, asset_id: impl Into<AssetId<A>>) -> bool {
71 matches!(self, AssetEvent::Added { id } if *id == asset_id.into())
72 }
73
74 pub fn is_modified(&self, asset_id: impl Into<AssetId<A>>) -> bool {
76 matches!(self, AssetEvent::Modified { id } if *id == asset_id.into())
77 }
78
79 pub fn is_removed(&self, asset_id: impl Into<AssetId<A>>) -> bool {
81 matches!(self, AssetEvent::Removed { id } if *id == asset_id.into())
82 }
83
84 pub fn is_unused(&self, asset_id: impl Into<AssetId<A>>) -> bool {
86 matches!(self, AssetEvent::Unused { id } if *id == asset_id.into())
87 }
88}
89
90impl<A: Asset> Clone for AssetEvent<A> {
91 fn clone(&self) -> Self {
92 *self
93 }
94}
95
96impl<A: Asset> Copy for AssetEvent<A> {}
97
98impl<A: Asset> Debug for AssetEvent<A> {
99 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
100 match self {
101 Self::Added { id } => f.debug_struct("Added").field("id", id).finish(),
102 Self::Modified { id } => f.debug_struct("Modified").field("id", id).finish(),
103 Self::Removed { id } => f.debug_struct("Removed").field("id", id).finish(),
104 Self::Unused { id } => f.debug_struct("Unused").field("id", id).finish(),
105 Self::LoadedWithDependencies { id } => f
106 .debug_struct("LoadedWithDependencies")
107 .field("id", id)
108 .finish(),
109 }
110 }
111}
112
113impl<A: Asset> PartialEq for AssetEvent<A> {
114 fn eq(&self, other: &Self) -> bool {
115 match (self, other) {
116 (Self::Added { id: l_id }, Self::Added { id: r_id })
117 | (Self::Modified { id: l_id }, Self::Modified { id: r_id })
118 | (Self::Removed { id: l_id }, Self::Removed { id: r_id })
119 | (Self::Unused { id: l_id }, Self::Unused { id: r_id })
120 | (
121 Self::LoadedWithDependencies { id: l_id },
122 Self::LoadedWithDependencies { id: r_id },
123 ) => l_id == r_id,
124 _ => false,
125 }
126 }
127}
128
129impl<A: Asset> Eq for AssetEvent<A> {}