Use real Rojo metadata for live sync

This commit is contained in:
Lucien Greathouse
2019-09-10 15:59:36 -07:00
parent e6ba6203bb
commit fc01eecdcb
3 changed files with 50 additions and 28 deletions

View File

@@ -1,6 +1,6 @@
use std::{collections::HashMap, path::PathBuf}; 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; 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) { fn insert_metadata(&mut self, id: RbxId, metadata: InstanceMetadata) {
if let Some(source_path) = &metadata.source_path { if let Some(source_path) = &metadata.source_path {
self.path_to_ids.insert(source_path.clone(), id); 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<Self::Item> {
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`. /// RojoTree's equivalent of `RbxInstanceProperties`.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct InstancePropertiesWithMeta { pub struct InstancePropertiesWithMeta {
@@ -182,28 +212,28 @@ pub struct InstanceWithMeta<'a> {
metadata: &'a InstanceMetadata, metadata: &'a InstanceMetadata,
} }
impl InstanceWithMeta<'_> { impl<'a> InstanceWithMeta<'a> {
pub fn id(&self) -> RbxId { pub fn id(&self) -> RbxId {
self.instance.get_id() self.instance.get_id()
} }
pub fn name(&self) -> &str { pub fn name(&self) -> &'a str {
&self.instance.name &self.instance.name
} }
pub fn class_name(&self) -> &str { pub fn class_name(&self) -> &'a str {
&self.instance.class_name &self.instance.class_name
} }
pub fn properties(&self) -> &HashMap<String, RbxValue> { pub fn properties(&self) -> &'a HashMap<String, RbxValue> {
&self.instance.properties &self.instance.properties
} }
pub fn children(&self) -> &[RbxId] { pub fn children(&self) -> &'a [RbxId] {
self.instance.get_children_ids() self.instance.get_children_ids()
} }
pub fn metadata(&self) -> &InstanceMetadata { pub fn metadata(&self) -> &'a InstanceMetadata {
&self.metadata &self.metadata
} }
} }

View File

@@ -111,16 +111,15 @@ impl ApiService {
let message_cursor = message_queue.cursor(); let message_cursor = message_queue.cursor();
let tree = self.serve_session.tree(); let tree = self.serve_session.tree();
let inner_tree = tree.inner();
let mut instances = HashMap::new(); let mut instances = HashMap::new();
for id in requested_ids { for id in requested_ids {
if let Some(instance) = inner_tree.get_instance(id) { if let Some(instance) = tree.get_instance(id) {
instances.insert(id, Instance::from_rbx_instance(instance)); instances.insert(id, Instance::from_rojo_instance(instance));
for descendant in inner_tree.descendants(id) { for descendant in tree.descendants(id) {
instances.insert(descendant.get_id(), Instance::from_rbx_instance(descendant)); instances.insert(descendant.id(), Instance::from_rojo_instance(descendant));
} }
} }
} }

View File

@@ -8,7 +8,7 @@ use std::{
use rbx_dom_weak::{RbxId, RbxInstance, RbxValue}; use rbx_dom_weak::{RbxId, RbxInstance, RbxValue};
use serde::{Deserialize, Serialize}; 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. /// Server version to report over the API, not exposed outside this crate.
pub(crate) const SERVER_VERSION: &str = env!("CARGO_PKG_VERSION"); pub(crate) const SERVER_VERSION: &str = env!("CARGO_PKG_VERSION");
@@ -37,22 +37,15 @@ pub struct Instance<'a> {
} }
impl<'a> Instance<'a> { impl<'a> Instance<'a> {
pub fn from_rbx_instance(source: &RbxInstance) -> Instance<'_> { pub fn from_rojo_instance<'b>(source: InstanceWithMeta<'b>) -> Instance<'b> {
// TODO: This is a hack!
let metadata = if source.class_name == "DataModel" {
Some(InstanceMetadata {
ignore_unknown_instances: true,
})
} else {
None
};
Instance { Instance {
name: Cow::Borrowed(&source.name), name: Cow::Borrowed(source.name()),
class_name: Cow::Borrowed(&source.class_name), class_name: Cow::Borrowed(source.class_name()),
properties: Cow::Borrowed(&source.properties), properties: Cow::Borrowed(source.properties()),
children: Cow::Borrowed(source.get_children_ids()), children: Cow::Borrowed(source.children()),
metadata, metadata: Some(InstanceMetadata {
ignore_unknown_instances: source.metadata().ignore_unknown_instances,
}),
} }
} }
} }