resource: impl Reflect for a bunch of types, add some utility methods to handles

This commit is contained in:
SeanOMik 2024-04-27 00:28:49 -04:00
parent f0d36e7b56
commit 15807a3dc1
Signed by: SeanOMik
GPG Key ID: FEC9E2FC15235964
5 changed files with 50 additions and 18 deletions

View File

@ -31,7 +31,7 @@ impl From<gltf::material::PbrMetallicRoughness<'_>> for PbrRoughness {
} }
} }
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default, Reflect)]
pub struct PbrGlossiness { pub struct PbrGlossiness {
/// The rgba diffuse color of the material /// The rgba diffuse color of the material
pub diffuse_color: glam::Vec4, pub diffuse_color: glam::Vec4,
@ -95,7 +95,7 @@ impl From<gltf::material::AlphaMode> for AlphaMode {
} }
} }
#[derive(Clone)] #[derive(Clone, Reflect)]
pub struct Specular { pub struct Specular {
/// The strength of the specular reflection, default of 1.0 /// The strength of the specular reflection, default of 1.0
pub factor: f32, pub factor: f32,
@ -131,7 +131,7 @@ impl Specular {
} }
} }
#[derive(Clone, Default)] #[derive(Clone, Default, Reflect)]
pub struct Material { pub struct Material {
pub shader_uuid: Option<u64>, pub shader_uuid: Option<u64>,
pub name: Option<String>, pub name: Option<String>,

View File

@ -48,7 +48,7 @@ impl From<Vec<u32>> for MeshIndices {
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq, Reflect)]
pub enum VertexAttributeData { pub enum VertexAttributeData {
Vec2(Vec<glam::Vec2>), Vec2(Vec<glam::Vec2>),
Vec3(Vec<glam::Vec3>), Vec3(Vec<glam::Vec3>),
@ -87,7 +87,7 @@ pub enum MeshVertexAttribute {
Other(String), Other(String),
} }
#[derive(Clone, Default, lyra_ecs::Component)] #[derive(Clone, Default, lyra_ecs::Component, Reflect)]
pub struct Mesh { pub struct Mesh {
pub attributes: HashMap<MeshVertexAttribute, VertexAttributeData>, pub attributes: HashMap<MeshVertexAttribute, VertexAttributeData>,
pub indices: Option<MeshIndices>, pub indices: Option<MeshIndices>,

View File

@ -2,6 +2,7 @@ pub mod loader;
pub use loader::*; pub use loader::*;
pub mod material; pub mod material;
use lyra_reflect::Reflect;
use lyra_scene::SceneGraph; use lyra_scene::SceneGraph;
use crate::ResourceData; use crate::ResourceData;
pub use material::*; pub use material::*;
@ -14,8 +15,10 @@ pub use scene::*;
use crate::ResHandle; use crate::ResHandle;
use crate::lyra_engine;
/// A loaded Gltf file /// A loaded Gltf file
#[derive(Clone, Default)] #[derive(Clone, Default, Reflect)]
pub struct Gltf { pub struct Gltf {
pub scenes: Vec<ResHandle<SceneGraph>>, pub scenes: Vec<ResHandle<SceneGraph>>,
pub materials: Vec<ResHandle<Material>>, pub materials: Vec<ResHandle<Material>>,
@ -48,6 +51,4 @@ impl ResourceData for Gltf {
fn as_any_mut(&mut self) -> &mut dyn std::any::Any { fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self self
} }
} }

View File

@ -1,6 +1,7 @@
use std::{any::{Any, TypeId}, marker::PhantomData, ops::{Deref, DerefMut}, sync::{Arc, Condvar, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}}; use std::{any::{Any, TypeId}, marker::PhantomData, ops::{Deref, DerefMut}, sync::{Arc, Condvar, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}};
use lyra_ecs::Component; use lyra_ecs::Component;
use lyra_reflect::Reflect;
use crate::{loader::LoaderError, lyra_engine, DependencyState}; use crate::{loader::LoaderError, lyra_engine, DependencyState};
use uuid::Uuid; use uuid::Uuid;
@ -90,16 +91,16 @@ pub struct UntypedResource {
pub(crate) version: usize, pub(crate) version: usize,
pub(crate) state: ResourceState, pub(crate) state: ResourceState,
uuid: Uuid, uuid: Uuid,
path: Option<String>, pub(crate) path: Option<String>,
pub(crate) is_watched: bool, pub(crate) is_watched: bool,
/// can be used to wait for the resource to load. /// can be used to wait for the resource to load.
pub(crate) condvar: Arc<(Mutex<bool>, Condvar)>, pub(crate) condvar: Arc<(Mutex<bool>, Condvar)>,
} }
#[derive(Clone, Component)] #[derive(Clone, Component, Reflect)]
pub struct UntypedResHandle{ pub struct UntypedResHandle{
#[reflect(skip)]
pub(crate) res: Arc<RwLock<UntypedResource>>, pub(crate) res: Arc<RwLock<UntypedResource>>,
#[allow(dead_code)]
tyid: TypeId, tyid: TypeId,
} }
@ -131,6 +132,15 @@ impl UntypedResHandle {
matches!(d.state, ResourceState::Ready(_)) matches!(d.state, ResourceState::Ready(_))
} }
pub fn get_error(&self) -> Option<Arc<LoaderError>> {
let d = self.read();
match &d.state {
ResourceState::Error(e) => Some(e.clone()),
_ => None,
}
}
/// Returns the uuid of the resource. /// Returns the uuid of the resource.
pub fn uuid(&self) -> Uuid { pub fn uuid(&self) -> Uuid {
let d = self.read(); let d = self.read();
@ -199,11 +209,28 @@ impl UntypedResHandle {
DependencyState::from_res_recurse(self) DependencyState::from_res_recurse(self)
} }
pub fn as_typed<T: ResourceData>(&self) -> ResHandle<T> { /// Retrieve a typed handle to the resource.
ResHandle { ///
handle: self.clone(), /// Returns `None` if the types do not match
_marker: PhantomData::<T>, pub fn as_typed<T: ResourceData>(&self) -> Option<ResHandle<T>> {
} self.clone().into_typed()
}
/// Convert `self` into a typed handle.
///
/// Returns `None` if the types do not match
pub fn into_typed<T: ResourceData>(self) -> Option<ResHandle<T>> {
if self.tyid == TypeId::of::<T>() {
Some(ResHandle {
handle: self,
_marker: PhantomData::<T>,
})
} else { None }
}
/// Retrieve the type id of the resource in the handle.
pub fn resource_type_id(&self) -> TypeId {
self.tyid
} }
} }
@ -213,7 +240,7 @@ impl UntypedResHandle {
/// This struct has an inner [`RwLock`] to the resource data, so most methods may be blocking. /// This struct has an inner [`RwLock`] to the resource data, so most methods may be blocking.
/// However, the only times it will be blocking is if another thread is reloading the resource /// However, the only times it will be blocking is if another thread is reloading the resource
/// and has a write lock on the data. This means that most of the time, it is not blocking. /// and has a write lock on the data. This means that most of the time, it is not blocking.
#[derive(Component)] #[derive(Component, Reflect)]
pub struct ResHandle<T: ResourceData> { pub struct ResHandle<T: ResourceData> {
pub(crate) handle: UntypedResHandle, pub(crate) handle: UntypedResHandle,
_marker: PhantomData<T>, _marker: PhantomData<T>,
@ -331,6 +358,10 @@ impl<T: ResourceData> ResourceStorage for ResHandle<T> {
let mut d = self.handle.write(); let mut d = self.handle.write();
d.state = new; d.state = new;
} }
fn clone_untyped(&self) -> UntypedResHandle {
self.handle.clone()
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -75,7 +75,7 @@ impl From<DynamicImage> for Image {
} }
} }
#[derive(Clone)] #[derive(Clone, Reflect)]
pub struct Texture { pub struct Texture {
pub image: ResHandle<Image>, pub image: ResHandle<Image>,
pub sampler: Option<TextureSampler>, pub sampler: Option<TextureSampler>,