goud_engine/assets/handle/load_state.rs
1//! Combined handle and load state type for convenient asset status checking.
2
3use crate::assets::{Asset, AssetState};
4
5use super::typed::AssetHandle;
6
7// =============================================================================
8// HandleLoadState
9// =============================================================================
10
11/// Combined handle and load state for convenient asset status checking.
12///
13/// This type wraps an asset handle together with its current loading state,
14/// allowing users to check both validity and load progress in one place.
15///
16/// # Example
17///
18/// ```
19/// use goud_engine::assets::{Asset, AssetHandle, AssetState, HandleLoadState};
20///
21/// struct Texture;
22/// impl Asset for Texture {}
23///
24/// // Simulate an asset that's loading
25/// let handle: AssetHandle<Texture> = AssetHandle::new(0, 1);
26/// let state = HandleLoadState::new(handle, AssetState::Loading { progress: 0.5 });
27///
28/// assert!(state.is_loading());
29/// assert_eq!(state.progress(), Some(0.5));
30///
31/// // When loaded
32/// let state = HandleLoadState::new(handle, AssetState::Loaded);
33/// assert!(state.is_ready());
34/// ```
35#[derive(Debug, Clone, PartialEq)]
36pub struct HandleLoadState<A: Asset> {
37 /// The asset handle.
38 handle: AssetHandle<A>,
39
40 /// Current loading state.
41 state: AssetState,
42}
43
44impl<A: Asset> HandleLoadState<A> {
45 /// Creates a new handle load state.
46 #[inline]
47 pub fn new(handle: AssetHandle<A>, state: AssetState) -> Self {
48 Self { handle, state }
49 }
50
51 /// Creates a handle load state for an invalid handle.
52 #[inline]
53 pub fn invalid() -> Self {
54 Self {
55 handle: AssetHandle::INVALID,
56 state: AssetState::NotLoaded,
57 }
58 }
59
60 /// Returns a reference to the handle.
61 #[inline]
62 pub fn handle(&self) -> &AssetHandle<A> {
63 &self.handle
64 }
65
66 /// Returns a reference to the asset state.
67 #[inline]
68 pub fn state(&self) -> &AssetState {
69 &self.state
70 }
71
72 /// Returns `true` if the handle is valid (not INVALID sentinel).
73 #[inline]
74 pub fn is_valid(&self) -> bool {
75 self.handle.is_valid()
76 }
77
78 /// Returns `true` if the asset is fully loaded and ready for use.
79 #[inline]
80 pub fn is_ready(&self) -> bool {
81 self.handle.is_valid() && self.state.is_ready()
82 }
83
84 /// Returns `true` if the asset is currently loading.
85 #[inline]
86 pub fn is_loading(&self) -> bool {
87 self.state.is_loading()
88 }
89
90 /// Returns `true` if the asset failed to load.
91 #[inline]
92 pub fn is_failed(&self) -> bool {
93 self.state.is_failed()
94 }
95
96 /// Returns the loading progress if currently loading.
97 #[inline]
98 pub fn progress(&self) -> Option<f32> {
99 self.state.progress()
100 }
101
102 /// Returns the error message if loading failed.
103 #[inline]
104 pub fn error(&self) -> Option<&str> {
105 self.state.error()
106 }
107
108 /// Consumes self and returns the inner handle.
109 #[inline]
110 pub fn into_handle(self) -> AssetHandle<A> {
111 self.handle
112 }
113
114 /// Updates the state.
115 #[inline]
116 pub fn set_state(&mut self, state: AssetState) {
117 self.state = state;
118 }
119}
120
121impl<A: Asset> Default for HandleLoadState<A> {
122 #[inline]
123 fn default() -> Self {
124 Self::invalid()
125 }
126}