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

View File

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

View File

@ -2,6 +2,7 @@ pub mod loader;
pub use loader::*;
pub mod material;
use lyra_reflect::Reflect;
use lyra_scene::SceneGraph;
use crate::ResourceData;
pub use material::*;
@ -14,8 +15,10 @@ pub use scene::*;
use crate::ResHandle;
use crate::lyra_engine;
/// A loaded Gltf file
#[derive(Clone, Default)]
#[derive(Clone, Default, Reflect)]
pub struct Gltf {
pub scenes: Vec<ResHandle<SceneGraph>>,
pub materials: Vec<ResHandle<Material>>,
@ -48,6 +51,4 @@ impl ResourceData for Gltf {
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
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 lyra_ecs::Component;
use lyra_reflect::Reflect;
use crate::{loader::LoaderError, lyra_engine, DependencyState};
use uuid::Uuid;
@ -90,16 +91,16 @@ pub struct UntypedResource {
pub(crate) version: usize,
pub(crate) state: ResourceState,
uuid: Uuid,
path: Option<String>,
pub(crate) path: Option<String>,
pub(crate) is_watched: bool,
/// can be used to wait for the resource to load.
pub(crate) condvar: Arc<(Mutex<bool>, Condvar)>,
}
#[derive(Clone, Component)]
#[derive(Clone, Component, Reflect)]
pub struct UntypedResHandle{
#[reflect(skip)]
pub(crate) res: Arc<RwLock<UntypedResource>>,
#[allow(dead_code)]
tyid: TypeId,
}
@ -131,6 +132,15 @@ impl UntypedResHandle {
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.
pub fn uuid(&self) -> Uuid {
let d = self.read();
@ -199,11 +209,28 @@ impl UntypedResHandle {
DependencyState::from_res_recurse(self)
}
pub fn as_typed<T: ResourceData>(&self) -> ResHandle<T> {
ResHandle {
handle: self.clone(),
_marker: PhantomData::<T>,
/// Retrieve a typed handle to the resource.
///
/// Returns `None` if the types do not match
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.
/// 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.
#[derive(Component)]
#[derive(Component, Reflect)]
pub struct ResHandle<T: ResourceData> {
pub(crate) handle: UntypedResHandle,
_marker: PhantomData<T>,
@ -331,6 +358,10 @@ impl<T: ResourceData> ResourceStorage for ResHandle<T> {
let mut d = self.handle.write();
d.state = new;
}
fn clone_untyped(&self) -> UntypedResHandle {
self.handle.clone()
}
}
#[cfg(test)]

View File

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