feat(resource): enum instead of trait, parse fn

This commit is contained in:
Nova
2022-09-26 01:33:21 -04:00
parent a80ddf501d
commit beca805a54
3 changed files with 42 additions and 69 deletions

View File

@@ -1,37 +1,43 @@
use anyhow::bail;
use std::path::PathBuf;
pub type ResourceID = Box<dyn ResourceIDTrait + Send + Sync>;
pub trait ResourceIDTrait: Send + Sync {
fn get_file(&self, prefixes: &[PathBuf]) -> Option<PathBuf>;
pub enum ResourceID {
File(PathBuf),
Namespaced { namespace: String, path: PathBuf },
}
impl ResourceID {
pub fn get_file(&self, prefixes: &[PathBuf]) -> Option<PathBuf> {
match self {
ResourceID::File(file) => (file.is_absolute() && file.exists()).then_some(file.clone()),
ResourceID::Namespaced { namespace, path } => {
for prefix in prefixes {
let mut test_path = prefix.clone();
test_path.push(namespace.clone());
test_path.push(path.clone());
impl ResourceIDTrait for PathBuf {
fn get_file(&self, _prefixes: &[PathBuf]) -> Option<PathBuf> {
if self.is_absolute() && self.as_path().exists() {
Some(self.clone())
} else {
None
}
}
}
pub struct NamespacedResourceID {
pub namespace: String,
pub path: PathBuf,
}
impl ResourceIDTrait for NamespacedResourceID {
fn get_file(&self, prefixes: &[PathBuf]) -> Option<PathBuf> {
for prefix in prefixes {
let mut path = prefix.clone();
path.push(self.namespace.clone());
path.push(self.path.clone());
if path.as_path().exists() {
return Some(path);
if test_path.as_path().exists() {
return Some(test_path);
}
}
None
}
}
None
}
}
pub fn parse_resource_id(reader: flexbuffers::Reader<&[u8]>) -> anyhow::Result<ResourceID> {
let string = reader.get_str()?;
Ok(if string.starts_with('/') {
let path = PathBuf::from(string);
path.metadata()?;
ResourceID::File(path)
} else if let Some((namespace, path)) = string.split_once(':') {
ResourceID::Namespaced {
namespace: namespace.to_string(),
path: PathBuf::from(path),
}
} else {
bail!("Invalid format for string");
})
}

View File

@@ -9,8 +9,7 @@ use stereokit::{lifecycle::DrawContext, texture::Texture, StereoKit};
pub fn create_interface(client: &Arc<Client>) {
let node = Node::create(client, "", "drawable", false);
node.add_local_signal("createModelFromFile", model::create_from_file);
node.add_local_signal("createModelFromResource", model::create_from_resource);
node.add_local_signal("createModel", model::create);
node.add_local_signal("setSkyFile", set_sky_file_flex);
node.add_to_scenegraph();
}

View File

@@ -1,12 +1,12 @@
use super::Node;
use crate::core::client::Client;
use crate::core::destroy_queue;
use crate::core::registry::Registry;
use crate::core::resource::{NamespacedResourceID, ResourceID};
use crate::core::resource::{parse_resource_id, ResourceID};
use crate::nodes::spatial::{get_spatial_parent_flex, Spatial};
use anyhow::{anyhow, bail, ensure, Result};
use flexbuffers::FlexBufferType;
use glam::Mat4;
use lazy_static::lazy_static;
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
use prisma::{Rgb, Rgba};
@@ -24,9 +24,6 @@ use stereokit::texture::Texture;
use stereokit::StereoKit;
static MODEL_REGISTRY: Registry<Model> = Registry::new();
lazy_static! {
static ref MODELS_TO_DROP: Mutex<Vec<SendWrapper<SKModel>>> = Default::default();
}
pub enum MaterialParameter {
Texture(PathBuf),
@@ -156,7 +153,7 @@ impl Model {
impl Drop for Model {
fn drop(&mut self) {
if let Some(model) = self.sk_model.take() {
MODELS_TO_DROP.lock().push(model);
destroy_queue::add(model);
}
MODEL_REGISTRY.remove(self);
}
@@ -168,7 +165,7 @@ pub fn draw_all(sk: &StereoKit, draw_ctx: &DrawContext) {
}
}
pub fn create_from_file(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
pub fn create(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?;
let node = Node::create(
&calling_client,
@@ -177,7 +174,7 @@ pub fn create_from_file(_node: &Node, calling_client: Arc<Client>, data: &[u8])
true,
);
let parent = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?;
let path = PathBuf::from(flex_vec.idx(2).get_str()?);
let resource_id = parse_resource_id(flex_vec.idx(2))?;
let transform = Mat4::from_scale_rotation_translation(
flex_to_vec3!(flex_vec.idx(5))
.ok_or_else(|| anyhow!("Scale not found"))?
@@ -191,35 +188,6 @@ pub fn create_from_file(_node: &Node, calling_client: Arc<Client>, data: &[u8])
);
let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?;
Model::add_to(&node, Box::new(path))?;
Ok(())
}
pub fn create_from_resource(_node: &Node, calling_client: Arc<Client>, data: &[u8]) -> Result<()> {
let flex_vec = flexbuffers::Reader::get_root(data)?.get_vector()?;
let node = Node::create(
&calling_client,
"/drawable/model",
flex_vec.idx(0).get_str()?,
true,
);
let parent = get_spatial_parent_flex(&calling_client, flex_vec.idx(1).get_str()?)?;
let resource_id = NamespacedResourceID {
namespace: flex_vec.idx(2).get_str()?.to_string(),
path: PathBuf::from(flex_vec.idx(3).get_str()?),
};
let transform = Mat4::from_scale_rotation_translation(
flex_to_vec3!(flex_vec.idx(6))
.ok_or_else(|| anyhow!("Scale not found"))?
.into(),
flex_to_quat!(flex_vec.idx(5))
.ok_or_else(|| anyhow!("Rotation not found"))?
.into(),
flex_to_vec3!(flex_vec.idx(4))
.ok_or_else(|| anyhow!("Position not found"))?
.into(),
);
let node = node.add_to_scenegraph();
Spatial::add_to(&node, Some(parent), transform)?;
Model::add_to(&node, Box::new(resource_id))?;
Model::add_to(&node, resource_id)?;
Ok(())
}