Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_asset/src/event.rs
6598 views
1
use crate::{Asset, AssetId, AssetLoadError, AssetPath, UntypedAssetId};
2
use bevy_ecs::event::BufferedEvent;
3
use bevy_reflect::Reflect;
4
use core::fmt::Debug;
5
6
/// A [`BufferedEvent`] emitted when a specific [`Asset`] fails to load.
7
///
8
/// For an untyped equivalent, see [`UntypedAssetLoadFailedEvent`].
9
#[derive(BufferedEvent, Clone, Debug)]
10
pub struct AssetLoadFailedEvent<A: Asset> {
11
/// The stable identifier of the asset that failed to load.
12
pub id: AssetId<A>,
13
/// The asset path that was attempted.
14
pub path: AssetPath<'static>,
15
/// Why the asset failed to load.
16
pub error: AssetLoadError,
17
}
18
19
impl<A: Asset> AssetLoadFailedEvent<A> {
20
/// Converts this to an "untyped" / "generic-less" asset error event that stores the type information.
21
pub fn untyped(&self) -> UntypedAssetLoadFailedEvent {
22
self.into()
23
}
24
}
25
26
/// An untyped version of [`AssetLoadFailedEvent`].
27
#[derive(BufferedEvent, Clone, Debug)]
28
pub struct UntypedAssetLoadFailedEvent {
29
/// The stable identifier of the asset that failed to load.
30
pub id: UntypedAssetId,
31
/// The asset path that was attempted.
32
pub path: AssetPath<'static>,
33
/// Why the asset failed to load.
34
pub error: AssetLoadError,
35
}
36
37
impl<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
/// [`BufferedEvent`]s that occur for a specific loaded [`Asset`], such as "value changed" events and "dependency" events.
48
#[expect(missing_docs, reason = "Documenting the id fields is unhelpful.")]
49
#[derive(BufferedEvent, Reflect)]
50
pub enum AssetEvent<A: Asset> {
51
/// Emitted whenever an [`Asset`] is added.
52
Added { id: AssetId<A> },
53
/// Emitted whenever an [`Asset`] value is modified.
54
Modified { id: AssetId<A> },
55
/// Emitted whenever an [`Asset`] is removed.
56
Removed { id: AssetId<A> },
57
/// Emitted when the last [`Handle::Strong`](`super::Handle::Strong`) of an [`Asset`] is dropped.
58
Unused { id: AssetId<A> },
59
/// Emitted whenever an [`Asset`] has been fully loaded (including its dependencies and all "recursive dependencies").
60
LoadedWithDependencies { id: AssetId<A> },
61
}
62
63
impl<A: Asset> AssetEvent<A> {
64
/// Returns `true` if this event is [`AssetEvent::LoadedWithDependencies`] and matches the given `id`.
65
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
/// Returns `true` if this event is [`AssetEvent::Added`] and matches the given `id`.
70
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
/// Returns `true` if this event is [`AssetEvent::Modified`] and matches the given `id`.
75
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
/// Returns `true` if this event is [`AssetEvent::Removed`] and matches the given `id`.
80
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
/// Returns `true` if this event is [`AssetEvent::Unused`] and matches the given `id`.
85
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
90
impl<A: Asset> Clone for AssetEvent<A> {
91
fn clone(&self) -> Self {
92
*self
93
}
94
}
95
96
impl<A: Asset> Copy for AssetEvent<A> {}
97
98
impl<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
113
impl<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
129
impl<A: Asset> Eq for AssetEvent<A> {}
130
131