use super::{Item, ItemSpecialization, ItemType}; use crate::{ core::{ client::{Client, INTERNAL_CLIENT}, registry::Registry, }, nodes::{ items::TypeInfo, spatial::{find_spatial_parent, parse_transform, Spatial}, Node, }, }; use anyhow::{anyhow, Result}; use lazy_static::lazy_static; use serde::Deserialize; use stardust_xr::{ schemas::flex::{deserialize, serialize}, values::Transform, }; use std::sync::Arc; lazy_static! { pub(super) static ref ITEM_TYPE_INFO_ENVIRONMENT: TypeInfo = TypeInfo { type_name: "environment", aliased_local_signals: vec!["apply_sky_tex", "apply_sky_light"], aliased_local_methods: vec![], aliased_remote_signals: vec![], ui: Default::default(), items: Registry::new(), acceptors: Registry::new(), }; } pub struct EnvironmentItem { path: String, } impl EnvironmentItem { pub fn add_to(node: &Arc, path: String) { Item::add_to( node, &ITEM_TYPE_INFO_ENVIRONMENT, ItemType::Environment(EnvironmentItem { path }), ); node.add_local_method("get_path", EnvironmentItem::get_path_flex); } fn get_path_flex(node: &Node, _calling_client: Arc, _data: &[u8]) -> Result> { let ItemType::Environment(environment_item) = &node.item.get().unwrap().specialization else { return Err(anyhow!("Wrong item type?")) }; Ok(flexbuffers::singleton(environment_item.path.as_str())) } } impl ItemSpecialization for EnvironmentItem { fn serialize_start_data(&self, id: &str) -> Vec { serialize((id, self.path.as_str())).unwrap() } } pub(super) fn create_environment_item_flex( _node: &Node, calling_client: Arc, data: &[u8], ) -> Result<()> { #[derive(Deserialize)] struct CreateEnvironmentItemInfo<'a> { name: &'a str, parent_path: &'a str, transform: Transform, item_data: String, } let info: CreateEnvironmentItemInfo = deserialize(data)?; let parent_name = format!("/item/{}/item", ITEM_TYPE_INFO_ENVIRONMENT.type_name); let space = find_spatial_parent(&calling_client, info.parent_path)?; let transform = parse_transform(info.transform, true, true, false)?; let node = Node::create(&INTERNAL_CLIENT, &parent_name, info.name, false).add_to_scenegraph(); Spatial::add_to(&node, None, transform * space.global_transform(), false)?; EnvironmentItem::add_to(&node, info.item_data); node.item .get() .unwrap() .make_alias_named(&calling_client, &parent_name, info.name); Ok(()) }