From e23056ac2f2bc9c61e7f1ef93fb8faa3758819d2 Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Mon, 14 Jan 2019 17:00:04 -0800 Subject: [PATCH] Change API to message metadata inline and add visualization --- server/src/rbx_session.rs | 4 ++-- server/src/visualize.rs | 29 +++++++++++++++++++++-------- server/src/web.rs | 39 +++++++++++++++++++++++++++++++-------- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/server/src/rbx_session.rs b/server/src/rbx_session.rs index 13342379..071ced15 100644 --- a/server/src/rbx_session.rs +++ b/server/src/rbx_session.rs @@ -155,8 +155,8 @@ impl RbxSession { &self.tree } - pub fn get_instance_metadata_map(&self) -> &HashMap { - &self.instance_metadata_map + pub fn get_instance_metadata(&self, id: RbxId) -> Option<&InstanceProjectNodeMetadata> { + self.instance_metadata_map.get(&id) } pub fn debug_get_path_map(&self) -> &PathMap { diff --git a/server/src/visualize.rs b/server/src/visualize.rs index 74696eda..0a39212e 100644 --- a/server/src/visualize.rs +++ b/server/src/visualize.rs @@ -5,10 +5,11 @@ use std::{ process::{Command, Stdio}, }; -use rbx_tree::{RbxTree, RbxId}; +use rbx_tree::RbxId; use crate::{ imfs::{Imfs, ImfsItem}, + rbx_session::RbxSession, }; static GRAPHVIZ_HEADER: &str = r#" @@ -41,13 +42,13 @@ pub fn graphviz_to_svg(source: &str) -> String { String::from_utf8(output.stdout).expect("Failed to parse stdout as UTF-8") } -pub struct VisualizeRbxTree<'a>(pub &'a RbxTree); +pub struct VisualizeRbxSession<'a>(pub &'a RbxSession); -impl<'a> fmt::Display for VisualizeRbxTree<'a> { +impl<'a> fmt::Display for VisualizeRbxSession<'a> { fn fmt(&self, output: &mut fmt::Formatter) -> fmt::Result { writeln!(output, "{}", GRAPHVIZ_HEADER)?; - visualize_rbx_node(self.0, self.0.get_root_id(), output)?; + visualize_rbx_node(self.0, self.0.get_tree().get_root_id(), output)?; writeln!(output, "}}")?; @@ -55,14 +56,26 @@ impl<'a> fmt::Display for VisualizeRbxTree<'a> { } } -fn visualize_rbx_node(tree: &RbxTree, id: RbxId, output: &mut fmt::Formatter) -> fmt::Result { - let node = tree.get_instance(id).unwrap(); +fn visualize_rbx_node(session: &RbxSession, id: RbxId, output: &mut fmt::Formatter) -> fmt::Result { + let node = session.get_tree().get_instance(id).unwrap(); - writeln!(output, " \"{}\" [label=\"{} ({})|{}\"]", id, node.name, node.class_name, id)?; + let mut node_label = format!("{}|{}|{}", node.name, node.class_name, id); + + if let Some(metadata) = session.get_instance_metadata(id) { + node_label.push('|'); + node_label.push_str(&serde_json::to_string(metadata).unwrap()); + } + + node_label = node_label + .replace("\"", """) + .replace("{", "\\{") + .replace("}", "\\}"); + + writeln!(output, " \"{}\" [label=\"{}\"]", id, node_label)?; for &child_id in node.get_children_ids() { writeln!(output, " \"{}\" -> \"{}\"", id, child_id)?; - visualize_rbx_node(tree, child_id, output)?; + visualize_rbx_node(session, child_id, output)?; } Ok(()) diff --git a/server/src/web.rs b/server/src/web.rs index 5be2cef5..e02ae511 100644 --- a/server/src/web.rs +++ b/server/src/web.rs @@ -17,9 +17,23 @@ use crate::{ session_id::SessionId, project::InstanceProjectNodeMetadata, rbx_snapshot::InstanceChanges, - visualize::{VisualizeRbxTree, VisualizeImfs, graphviz_to_svg}, + visualize::{VisualizeRbxSession, VisualizeImfs, graphviz_to_svg}, }; +/// Used to attach metadata specific to Rojo to instances, which come from the +/// rbx_tree crate. +/// +/// Both fields are wrapped in Cow in order to make owned-vs-borrowed simpler +/// for tests. +#[derive(Debug, Serialize, Deserialize)] +pub struct InstanceWithMetadata<'a> { + #[serde(flatten)] + pub instance: Cow<'a, RootedRbxInstance>, + + #[serde(rename = "Metadata")] + pub metadata: Option>, +} + #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ServerInfoResponse<'a> { @@ -28,7 +42,6 @@ pub struct ServerInfoResponse<'a> { pub protocol_version: u64, pub expected_place_ids: Option>, pub root_instance_id: RbxId, - pub instance_metadata_map: Cow<'a, HashMap>, } #[derive(Debug, Serialize, Deserialize)] @@ -36,7 +49,7 @@ pub struct ServerInfoResponse<'a> { pub struct ReadResponse<'a> { pub session_id: SessionId, pub message_cursor: u32, - pub instances: HashMap>, + pub instances: HashMap>, } #[derive(Debug, Serialize, Deserialize)] @@ -81,7 +94,6 @@ impl Server { session_id: self.session.session_id, expected_place_ids: self.session.project.serve_place_ids.clone(), root_instance_id: tree.get_root_id(), - instance_metadata_map: Cow::Borrowed(rbx_session.get_instance_metadata_map()), }) }, @@ -148,10 +160,22 @@ impl Server { for &requested_id in &requested_ids { if let Some(instance) = tree.get_instance(requested_id) { - instances.insert(instance.get_id(), Cow::Borrowed(instance)); + let metadata = rbx_session.get_instance_metadata(requested_id) + .map(Cow::Borrowed); + + instances.insert(instance.get_id(), InstanceWithMetadata { + instance: Cow::Borrowed(instance), + metadata, + }); for descendant in tree.descendants(requested_id) { - instances.insert(descendant.get_id(), Cow::Borrowed(descendant)); + let descendant_meta = rbx_session.get_instance_metadata(descendant.get_id()) + .map(Cow::Borrowed); + + instances.insert(descendant.get_id(), InstanceWithMetadata { + instance: Cow::Borrowed(descendant), + metadata: descendant_meta, + }); } } } @@ -165,9 +189,8 @@ impl Server { (GET) (/visualize/rbx) => { let rbx_session = self.session.rbx_session.lock().unwrap(); - let tree = rbx_session.get_tree(); - let dot_source = format!("{}", VisualizeRbxTree(tree)); + let dot_source = format!("{}", VisualizeRbxSession(&rbx_session)); Response::svg(graphviz_to_svg(&dot_source)) },