Skip to main content

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}