diff --git a/src/snapshot/tree.rs b/src/snapshot/tree.rs index 374def45..27aa3f45 100644 --- a/src/snapshot/tree.rs +++ b/src/snapshot/tree.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, path::PathBuf}; -use rbx_dom_weak::{RbxId, RbxInstance, RbxInstanceProperties, RbxTree, RbxValue}; +use rbx_dom_weak::{Descendants, RbxId, RbxInstance, RbxInstanceProperties, RbxTree, RbxValue}; use crate::multimap::MultiMap; @@ -128,6 +128,17 @@ impl RojoTree { } } + pub fn descendants(&self, id: RbxId) -> RojoDescendants<'_> { + RojoDescendants { + inner: self.inner.descendants(id), + tree: self, + } + } + + fn get_metadata(&self, id: RbxId) -> Option<&InstanceMetadata> { + self.metadata_map.get(&id) + } + fn insert_metadata(&mut self, id: RbxId, metadata: InstanceMetadata) { if let Some(source_path) = &metadata.source_path { self.path_to_ids.insert(source_path.clone(), id); @@ -155,6 +166,25 @@ impl RojoTree { } } +pub struct RojoDescendants<'a> { + inner: Descendants<'a>, + tree: &'a RojoTree, +} + +impl<'a> Iterator for RojoDescendants<'a> { + type Item = InstanceWithMeta<'a>; + + fn next(&mut self) -> Option { + let instance = self.inner.next()?; + let metadata = self + .tree + .get_metadata(instance.get_id()) + .expect("Metadata did not exist for instance"); + + Some(InstanceWithMeta { instance, metadata }) + } +} + /// RojoTree's equivalent of `RbxInstanceProperties`. #[derive(Debug, Clone)] pub struct InstancePropertiesWithMeta { @@ -182,28 +212,28 @@ pub struct InstanceWithMeta<'a> { metadata: &'a InstanceMetadata, } -impl InstanceWithMeta<'_> { +impl<'a> InstanceWithMeta<'a> { pub fn id(&self) -> RbxId { self.instance.get_id() } - pub fn name(&self) -> &str { + pub fn name(&self) -> &'a str { &self.instance.name } - pub fn class_name(&self) -> &str { + pub fn class_name(&self) -> &'a str { &self.instance.class_name } - pub fn properties(&self) -> &HashMap { + pub fn properties(&self) -> &'a HashMap { &self.instance.properties } - pub fn children(&self) -> &[RbxId] { + pub fn children(&self) -> &'a [RbxId] { self.instance.get_children_ids() } - pub fn metadata(&self) -> &InstanceMetadata { + pub fn metadata(&self) -> &'a InstanceMetadata { &self.metadata } } diff --git a/src/web/api.rs b/src/web/api.rs index 2d7e9a37..885c941b 100644 --- a/src/web/api.rs +++ b/src/web/api.rs @@ -111,16 +111,15 @@ impl ApiService { let message_cursor = message_queue.cursor(); let tree = self.serve_session.tree(); - let inner_tree = tree.inner(); let mut instances = HashMap::new(); for id in requested_ids { - if let Some(instance) = inner_tree.get_instance(id) { - instances.insert(id, Instance::from_rbx_instance(instance)); + if let Some(instance) = tree.get_instance(id) { + instances.insert(id, Instance::from_rojo_instance(instance)); - for descendant in inner_tree.descendants(id) { - instances.insert(descendant.get_id(), Instance::from_rbx_instance(descendant)); + for descendant in tree.descendants(id) { + instances.insert(descendant.id(), Instance::from_rojo_instance(descendant)); } } } diff --git a/src/web/interface.rs b/src/web/interface.rs index 1bc6c117..18f62104 100644 --- a/src/web/interface.rs +++ b/src/web/interface.rs @@ -8,7 +8,7 @@ use std::{ use rbx_dom_weak::{RbxId, RbxInstance, RbxValue}; use serde::{Deserialize, Serialize}; -use crate::session_id::SessionId; +use crate::{session_id::SessionId, snapshot::InstanceWithMeta}; /// Server version to report over the API, not exposed outside this crate. pub(crate) const SERVER_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -37,22 +37,15 @@ pub struct Instance<'a> { } impl<'a> Instance<'a> { - pub fn from_rbx_instance(source: &RbxInstance) -> Instance<'_> { - // TODO: This is a hack! - let metadata = if source.class_name == "DataModel" { - Some(InstanceMetadata { - ignore_unknown_instances: true, - }) - } else { - None - }; - + pub fn from_rojo_instance<'b>(source: InstanceWithMeta<'b>) -> Instance<'b> { Instance { - name: Cow::Borrowed(&source.name), - class_name: Cow::Borrowed(&source.class_name), - properties: Cow::Borrowed(&source.properties), - children: Cow::Borrowed(source.get_children_ids()), - metadata, + name: Cow::Borrowed(source.name()), + class_name: Cow::Borrowed(source.class_name()), + properties: Cow::Borrowed(source.properties()), + children: Cow::Borrowed(source.children()), + metadata: Some(InstanceMetadata { + ignore_unknown_instances: source.metadata().ignore_unknown_instances, + }), } } }