Make Rojo build with rbx_tree

This commit is contained in:
Lucien Greathouse
2018-11-08 13:22:09 -08:00
parent 31e1f61548
commit 5a99281e23
6 changed files with 33 additions and 229 deletions

View File

@@ -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;

View File

@@ -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<String, RbxValue>,
/// The unique ID of the instance
id: Id,
/// All of the children of this instance. Order is relevant to preserve!
children: Vec<Id>,
/// The parent of the instance, if there is one.
parent: Option<Id>,
}
impl RbxInstance {
pub fn get_id(&self) -> Id {
self.id
}
}
pub struct Descendants<'a> {
tree: &'a RbxTree,
ids_to_visit: Vec<Id>,
}
impl<'a> Iterator for Descendants<'a> {
type Item = &'a RbxInstance;
fn next(&mut self) -> Option<Self::Item> {
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<Id, RbxInstance>,
// 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<Id, RbxInstance> {
&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<Id> {
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![],
}
},
}
}
}

View File

@@ -15,9 +15,10 @@ use notify::{
Watcher,
};
use rbx_tree::RbxTree;
use ::{
message_queue::MessageQueue,
rbx::RbxTree,
project::{Project, ProjectNode},
vfs::Vfs,
};

View File

@@ -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<Id, Cow<'a, RbxInstance>>,
pub instances: HashMap<RbxId, Cow<'a, RootedRbxInstance>>,
}
#[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<Vec<Id>, _> = id_list
let requested_ids: Option<Vec<RbxId>> = 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));
}
},