From 729ab25581992bd9bc29a7c49dfea9a06418c975 Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Sat, 17 Nov 2018 01:14:07 -0800 Subject: [PATCH] Expose more project stuff via the API --- server/src/project.rs | 11 +++-- server/src/rbx_session.rs | 88 ++++++++++++++++++++++++++------------- server/src/session.rs | 2 +- server/src/web.rs | 5 +++ 4 files changed, 73 insertions(+), 33 deletions(-) diff --git a/server/src/project.rs b/server/src/project.rs index 853c8547..4d761d12 100644 --- a/server/src/project.rs +++ b/server/src/project.rs @@ -137,13 +137,15 @@ impl fmt::Display for ProjectSaveError { } } -#[derive(Debug)] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(tag = "type")] pub enum ProjectNode { Instance(InstanceProjectNode), SyncPoint(SyncPointProjectNode), } -#[derive(Debug)] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct InstanceProjectNode { pub class_name: String, pub children: HashMap, @@ -151,12 +153,13 @@ pub struct InstanceProjectNode { // ignore_unknown: bool, } -#[derive(Debug)] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct SyncPointProjectNode { pub path: PathBuf, } -#[derive(Debug)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Project { pub name: String, pub tree: ProjectNode, diff --git a/server/src/rbx_session.rs b/server/src/rbx_session.rs index de3e16c1..13d0f7d2 100644 --- a/server/src/rbx_session.rs +++ b/server/src/rbx_session.rs @@ -16,6 +16,7 @@ use crate::{ pub struct RbxSession { tree: RbxTree, paths_to_ids: HashMap, + ids_to_project_paths: HashMap, message_queue: Arc, vfs: Arc>, project: Arc, @@ -23,7 +24,7 @@ pub struct RbxSession { impl RbxSession { pub fn new(project: Arc, vfs: Arc>, message_queue: Arc) -> RbxSession { - let (tree, paths_to_ids) = { + let (tree, paths_to_ids, ids_to_project_paths) = { let temp_vfs = vfs.lock().unwrap(); construct_initial_tree(&project, &temp_vfs) }; @@ -31,6 +32,7 @@ impl RbxSession { RbxSession { tree, paths_to_ids, + ids_to_project_paths, message_queue, vfs, project, @@ -56,14 +58,19 @@ impl RbxSession { pub fn get_tree(&self) -> &RbxTree { &self.tree } + + pub fn get_project_path_map(&self) -> &HashMap { + &self.ids_to_project_paths + } } fn construct_initial_tree( project: &Project, vfs: &Vfs, -) -> (RbxTree, HashMap) { - let mut paths_to_ids = HashMap::new(); - let mut tree = RbxTree::new(RbxInstance { +) -> (RbxTree, HashMap, HashMap) { + let paths_to_ids = HashMap::new(); + let ids_to_project_paths = HashMap::new(); + let tree = RbxTree::new(RbxInstance { name: "this isn't supposed to be here".to_string(), class_name: "ahhh, help me".to_string(), properties: HashMap::new(), @@ -71,59 +78,80 @@ fn construct_initial_tree( let root_id = tree.get_root_id(); - construct_initial_tree_node(&mut tree, vfs, &mut paths_to_ids, root_id, "<<>>", &project.tree); + let mut context = ConstructContext { + tree, + vfs, + paths_to_ids, + ids_to_project_paths, + }; - (tree, paths_to_ids) + construct_project_node( + &mut context, + root_id, + "<<>>".to_string(), + "<<>>", + &project.tree, + ); + + (context.tree, context.paths_to_ids, context.ids_to_project_paths) } -fn construct_initial_tree_node( - tree: &mut RbxTree, - vfs: &Vfs, - paths_to_ids: &mut HashMap, +struct ConstructContext<'a> { + tree: RbxTree, + vfs: &'a Vfs, + paths_to_ids: HashMap, + ids_to_project_paths: HashMap, +} + +fn construct_project_node( + context: &mut ConstructContext, parent_instance_id: RbxId, + instance_path: String, instance_name: &str, project_node: &ProjectNode, ) { match project_node { ProjectNode::Instance(node) => { - construct_instance_node(tree, vfs, paths_to_ids, parent_instance_id, instance_name, node); + let id = construct_instance_node(context, parent_instance_id, &instance_path, instance_name, node); + context.ids_to_project_paths.insert(id, instance_path.to_string()); }, ProjectNode::SyncPoint(node) => { - construct_sync_point_node(tree, vfs, paths_to_ids, parent_instance_id, instance_name, &node.path); + let id = construct_sync_point_node(context, parent_instance_id, instance_name, &node.path); + context.ids_to_project_paths.insert(id, instance_path.to_string()); }, } } fn construct_instance_node( - tree: &mut RbxTree, - vfs: &Vfs, - paths_to_ids: &mut HashMap, + context: &mut ConstructContext, parent_instance_id: RbxId, + instance_path: &str, instance_name: &str, project_node: &InstanceProjectNode, -) { +) -> RbxId { let instance = RbxInstance { class_name: project_node.class_name.clone(), name: instance_name.to_string(), properties: HashMap::new(), }; - let id = tree.insert_instance(instance, parent_instance_id); + let id = context.tree.insert_instance(instance, parent_instance_id); for (child_name, child_project_node) in &project_node.children { - construct_initial_tree_node(tree, vfs, paths_to_ids, id, child_name, child_project_node); + let child_path = format!("{}/{}", instance_path, child_name); + construct_project_node(context, id, child_path, child_name, child_project_node); } + + id } fn construct_sync_point_node( - tree: &mut RbxTree, - vfs: &Vfs, - paths_to_ids: &mut HashMap, + context: &mut ConstructContext, parent_instance_id: RbxId, instance_name: &str, file_path: &Path, -) { - match vfs.get(&file_path) { +) -> RbxId { + match context.vfs.get(&file_path) { Some(VfsItem::File(file)) => { let contents = str::from_utf8(&file.contents).unwrap(); @@ -136,8 +164,10 @@ fn construct_sync_point_node( properties, }; - let id = tree.insert_instance(instance, parent_instance_id); - paths_to_ids.insert(file.path.clone(), id); + let id = context.tree.insert_instance(instance, parent_instance_id); + context.paths_to_ids.insert(file.path.clone(), id); + + id }, Some(VfsItem::Directory(directory)) => { let instance = RbxInstance { @@ -146,13 +176,15 @@ fn construct_sync_point_node( properties: HashMap::new(), }; - let id = tree.insert_instance(instance, parent_instance_id); - paths_to_ids.insert(directory.path.clone(), id); + let id = context.tree.insert_instance(instance, parent_instance_id); + context.paths_to_ids.insert(directory.path.clone(), id); for child_path in &directory.children { let child_instance_name = child_path.file_name().unwrap().to_str().unwrap(); - construct_sync_point_node(tree, vfs, paths_to_ids, id, child_instance_name, child_path); + construct_sync_point_node(context, id, child_instance_name, child_path); } + + id }, None => panic!("Couldn't read {} from disk", file_path.display()), } diff --git a/server/src/session.rs b/server/src/session.rs index a546c18b..f072fdd9 100644 --- a/server/src/session.rs +++ b/server/src/session.rs @@ -24,7 +24,7 @@ use crate::{ const WATCH_TIMEOUT_MS: u64 = 100; pub struct Session { - project: Arc, + pub project: Arc, pub session_id: SessionId, pub message_queue: Arc, pub rbx_session: Arc>, diff --git a/server/src/web.rs b/server/src/web.rs index 150c019f..c76ebe2e 100644 --- a/server/src/web.rs +++ b/server/src/web.rs @@ -11,6 +11,7 @@ use crate::{ message_queue::Message, session::Session, session_id::SessionId, + project::Project, }; #[derive(Debug, Serialize, Deserialize)] @@ -20,6 +21,8 @@ pub struct ServerInfoResponse<'a> { pub server_version: &'a str, pub protocol_version: u64, pub root_instance_id: RbxId, + pub project: Cow<'a, Project>, + pub project_paths_to_ids: Cow<'a, HashMap>, } #[derive(Debug, Serialize, Deserialize)] @@ -71,6 +74,8 @@ impl Server { protocol_version: 2, session_id: self.session.session_id, root_instance_id: tree.get_root_id(), + project: Cow::Borrowed(&self.session.project), + project_paths_to_ids: Cow::Borrowed(rbx_session.get_project_path_map()), }) },