diff --git a/server/Cargo.lock b/server/Cargo.lock index caedd382..083fe9ff 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -641,6 +641,15 @@ name = "rand_core" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rbx-tree" +version = "0.1.0" +dependencies = [ + "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "redox_syscall" version = "0.1.40" @@ -692,6 +701,7 @@ dependencies = [ "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "notify 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rbx-tree 0.1.0", "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "rouille 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", @@ -976,6 +986,15 @@ dependencies = [ "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "uuid" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "vec_map" version = "0.8.1" @@ -1169,6 +1188,7 @@ dependencies = [ "checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6" "checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4" "checksum uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "78c590b5bd79ed10aad8fb75f078a59d8db445af6c743e55c4a53227fc01c13f" +"checksum uuid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dab5c5526c5caa3d106653401a267fed923e7046f35895ffcb5ca42db64942e6" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051" "checksum walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "af464bc7be7b785c7ac72e266a6b67c4c9070155606f51655a650a6686204e35" diff --git a/server/Cargo.toml b/server/Cargo.toml index c773efd1..3381e44b 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -30,6 +30,7 @@ regex = "1.0" lazy_static = "1.0" log = "0.4" env_logger = "0.5" +rbx-tree = { path = "../../rbx-tree" } [dev-dependencies] tempfile = "3.0" diff --git a/server/src/lib.rs b/server/src/lib.rs index 41d3fd7e..e0e28ba8 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -7,6 +7,7 @@ extern crate rand; extern crate serde; extern crate serde_json; extern crate regex; +extern crate rbx_tree; #[cfg(test)] extern crate tempfile; @@ -16,7 +17,6 @@ pub mod id; pub mod message_queue; pub mod pathext; pub mod project; -pub mod rbx; // pub mod roblox_studio; pub mod session; pub mod vfs; diff --git a/server/src/rbx.rs b/server/src/rbx.rs deleted file mode 100644 index 29f55072..00000000 --- a/server/src/rbx.rs +++ /dev/null @@ -1,217 +0,0 @@ -use std::collections::HashMap; - -use id::{Id, get_id}; - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(tag = "type")] -pub enum RbxValue { - String { - value: String, - }, - Number { - value: f64, - }, - Bool { - value: bool, - }, - Vector3 { - value: [f64; 3], - }, - Color3 { - value: [u8; 3], - }, -} - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct RbxInstance { - /// Maps to the `Name` property on Instance. - pub name: String, - - /// Maps to the `ClassName` property on Instance. - pub class_name: String, - - /// Contains all other properties of an Instance. - pub properties: HashMap, - - /// The unique ID of the instance - id: Id, - - /// All of the children of this instance. Order is relevant to preserve! - children: Vec, - - /// The parent of the instance, if there is one. - parent: Option, -} - -impl RbxInstance { - pub fn get_id(&self) -> Id { - self.id - } -} - -pub struct Descendants<'a> { - tree: &'a RbxTree, - ids_to_visit: Vec, -} - -impl<'a> Iterator for Descendants<'a> { - type Item = &'a RbxInstance; - - fn next(&mut self) -> Option { - loop { - let id = match self.ids_to_visit.pop() { - Some(id) => id, - None => break, - }; - - match self.tree.get_instance(id) { - Some(instance) => { - for child_id in &instance.children { - self.ids_to_visit.push(*child_id); - } - - return Some(instance); - }, - None => continue, - } - } - - None - } -} - -pub struct RbxTree { - instances: HashMap, - // TODO: Make private - pub root_instance_id: Id, -} - -impl RbxTree { - pub fn new() -> RbxTree { - let root_instance_id = get_id(); - let root_instance = RbxInstance { - name: "game".to_string(), - class_name: "DataModel".to_string(), - properties: HashMap::new(), - id: root_instance_id, - children: Vec::new(), - parent: None, - }; - - let mut instances = HashMap::new(); - instances.insert(root_instance_id, root_instance); - - RbxTree { - instances, - root_instance_id, - } - } - - pub fn get_instance(&self, id: Id) -> Option<&RbxInstance> { - self.instances.get(&id) - } - - pub fn get_all_instances(&self) -> &HashMap { - &self.instances - } - - // TODO: Test this function! - pub fn insert_tree(&mut self, parent_id: Id, tree: &RbxTree) { - let mut to_visit = vec![tree.root_instance_id]; - - loop { - let id = match to_visit.pop() { - Some(id) => id, - None => break, - }; - - let mut new_child = tree.get_instance(id).unwrap().clone(); - - for child in &new_child.children { - to_visit.push(*child); - } - - if id == tree.root_instance_id { - new_child.parent = Some(parent_id); - } - - self.insert_instance(new_child); - } - } - - pub fn insert_instance(&mut self, mut instance: RbxInstance) { - match instance.parent { - Some(parent_id) => { - match self.instances.get_mut(&parent_id) { - Some(mut parent) => { - if !parent.children.contains(&instance.id) { - parent.children.push(instance.id); - } - }, - None => { - panic!("Tree consistency error, parent {} was not present in tree.", parent_id); - } - } - }, - None => { - instance.parent = Some(self.root_instance_id); - }, - } - - self.instances.insert(instance.id, instance); - } - - pub fn delete_instance(&mut self, id: Id) -> Vec { - let mut ids_to_visit = vec![id]; - let mut ids_deleted = Vec::new(); - - // We only need to explicitly remove a child from the first instance we - // delete, since all others will descend from this instance. - let parent_id = match self.instances.get(&id) { - Some(instance) => instance.parent, - None => None, - }; - - if let Some(parent_id) = parent_id { - let mut parent = self.instances.get_mut(&parent_id).unwrap(); - let index = parent.children.iter().position(|&v| v == id).unwrap(); - - parent.children.remove(index); - } - - loop { - let id = match ids_to_visit.pop() { - Some(id) => id, - None => break, - }; - - match self.instances.get(&id) { - Some(instance) => ids_to_visit.extend_from_slice(&instance.children), - None => continue, - } - - self.instances.remove(&id); - ids_deleted.push(id); - } - - ids_deleted - } - - pub fn iter_descendants<'a>(&'a self, id: Id) -> Descendants<'a> { - match self.get_instance(id) { - Some(instance) => { - Descendants { - tree: self, - ids_to_visit: instance.children.clone(), - } - }, - None => { - Descendants { - tree: self, - ids_to_visit: vec![], - } - }, - } - } -} \ No newline at end of file diff --git a/server/src/session.rs b/server/src/session.rs index 7a69bed9..b08810fe 100644 --- a/server/src/session.rs +++ b/server/src/session.rs @@ -15,9 +15,10 @@ use notify::{ Watcher, }; +use rbx_tree::RbxTree; + use ::{ message_queue::MessageQueue, - rbx::RbxTree, project::{Project, ProjectNode}, vfs::Vfs, }; diff --git a/server/src/web.rs b/server/src/web.rs index 8ec85213..919fcba9 100644 --- a/server/src/web.rs +++ b/server/src/web.rs @@ -5,11 +5,10 @@ use std::{ }; use rouille::{self, Request, Response}; +use rbx_tree::{RbxId, RootedRbxInstance}; use ::{ - id::Id, message_queue::Message, - rbx::RbxInstance, session::Session, }; @@ -19,7 +18,7 @@ pub struct ServerInfoResponse<'a> { pub session_id: &'a str, pub server_version: &'a str, pub protocol_version: u64, - pub root_instance_id: Id, + pub root_instance_id: RbxId, } #[derive(Debug, Serialize, Deserialize)] @@ -27,7 +26,7 @@ pub struct ServerInfoResponse<'a> { pub struct ReadResponse<'a> { pub session_id: &'a str, pub message_cursor: u32, - pub instances: HashMap>, + pub instances: HashMap>, } #[derive(Debug, Serialize, Deserialize)] @@ -69,7 +68,7 @@ impl Server { server_version: self.server_version, protocol_version: 2, session_id: &self.session.session_id, - root_instance_id: tree.root_instance_id, + root_instance_id: *tree.get_root_ids().iter().nth(0).unwrap(), // TODO }) }, @@ -117,14 +116,14 @@ impl Server { (GET) (/api/read/{ id_list: String }) => { let message_queue = Arc::clone(&self.session.message_queue); - let requested_ids: Result, _> = id_list + let requested_ids: Option> = id_list .split(",") - .map(str::parse) + .map(RbxId::parse_str) .collect(); let requested_ids = match requested_ids { - Ok(id) => id, - Err(_) => return rouille::Response::text("Malformed ID list").with_status_code(400), + Some(id) => id, + None => return rouille::Response::text("Malformed ID list").with_status_code(400), }; let tree = self.session.tree.read().unwrap(); @@ -138,7 +137,7 @@ impl Server { Some(instance) => { instances.insert(instance.get_id(), Cow::Borrowed(instance)); - for descendant in tree.iter_descendants(requested_id) { + for descendant in tree.descendants(requested_id) { instances.insert(descendant.get_id(), Cow::Borrowed(descendant)); } },