lyra-engine/lyra-resource/src/dep_state.rs

109 lines
3.7 KiB
Rust

use std::sync::Arc;
use crate::{loader::LoaderError, ResourceState, UntypedResHandle};
#[derive(Clone)]
pub enum DependencyState {
Loading,
Error {
/// The resource that had the error.
handle: UntypedResHandle,
/// The error that the resource ran into when loading.
error: Arc<LoaderError>,
},
Ready,
}
impl DependencyState {
/// Creates a DependencyState from a resource by retrieving its state. Does not include
/// the states of the dependencies.
pub fn shallow_from_res(handle: &UntypedResHandle) -> DependencyState {
let res = handle.read();
match &res.state {
ResourceState::Loading => DependencyState::Loading,
ResourceState::Error(er) => DependencyState::Error {
handle: handle.clone(),
error: er.clone(),
},
ResourceState::Ready(_) => DependencyState::Ready,
}
}
/// Retrieve the state of the handle and its dependencies, does not recursively retrieve.
pub fn from_res(handle: &UntypedResHandle) -> DependencyState {
let res = handle.read();
match &res.state {
ResourceState::Loading => DependencyState::Loading,
ResourceState::Error(er) => DependencyState::Error {
handle: handle.clone(),
error: er.clone(),
},
ResourceState::Ready(res) => {
let mut lowest_state = DependencyState::Ready;
for dep in res.dependencies() {
let state = DependencyState::shallow_from_res(&dep);
// try to find the "lowest" dependency. Meaning the state of a dependency
// that would stop the parent from being ready.
if state.is_loading() {
lowest_state = state;
break;
} else if state.is_error() {
lowest_state = state;
break;
}
// anything else would be loaded, so no need to update `lowest_state`
}
lowest_state
},
}
}
/// Retrieve the state of the handle and its dependencies, does not recursively retrieve.
pub fn from_res_recurse(handle: &UntypedResHandle) -> DependencyState {
let res = handle.read();
match &res.state {
ResourceState::Loading => DependencyState::Loading,
ResourceState::Error(er) => DependencyState::Error {
handle: handle.clone(),
error: er.clone(),
},
ResourceState::Ready(res) => {
let mut lowest_state = DependencyState::Ready;
for dep in res.dependencies() {
let state = DependencyState::from_res_recurse(&dep);
// try to find the "lowest" dependency. Meaning the state of a dependency
// that would stop the parent from being ready.
if state.is_loading() {
lowest_state = state;
break;
} else if state.is_error() {
lowest_state = state;
break;
}
// anything else would be loaded, so no need to update `lowest_state`
}
lowest_state
},
}
}
pub fn is_ready(&self) -> bool {
matches!(self, DependencyState::Ready)
}
pub fn is_error(&self) -> bool {
matches!(self, DependencyState::Error { handle: _, error: _ })
}
pub fn is_loading(&self) -> bool {
matches!(self, DependencyState::Loading)
}
}