Iterating on project format to make it friendlier

This commit is contained in:
Lucien Greathouse
2018-11-16 14:51:14 -08:00
parent a29c4f2b65
commit 60c5c2d344
8 changed files with 86 additions and 73 deletions

1
server/Cargo.lock generated
View File

@@ -708,6 +708,7 @@ dependencies = [
"serde_derive 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)",
"serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]

View File

@@ -31,6 +31,7 @@ lazy_static = "1.0"
log = "0.4" log = "0.4"
env_logger = "0.5" env_logger = "0.5"
rbx-tree = { path = "../../rbx-tree" } rbx-tree = { path = "../../rbx-tree" }
uuid = { version = "0.7", features = ["v4", "serde"] }
[dev-dependencies] [dev-dependencies]
tempfile = "3.0" tempfile = "3.0"

View File

@@ -27,12 +27,7 @@ pub fn serve(fuzzy_project_location: &Path) {
// roblox_studio::install_bundled_plugin().unwrap(); // roblox_studio::install_bundled_plugin().unwrap();
let session = Arc::new({ let session = Arc::new(Session::new(project).unwrap());
let mut session = Session::new(project);
session.start().unwrap();
session
});
let server = Server::new(Arc::clone(&session)); let server = Server::new(Arc::clone(&session));
println!("Server listening on port 34872"); println!("Server listening on port 34872");

View File

@@ -1,24 +1,28 @@
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate rouille;
#[macro_use] extern crate lazy_static; #[macro_use] extern crate lazy_static;
#[macro_use] extern crate log; #[macro_use] extern crate log;
#[macro_use] extern crate rouille;
#[macro_use] extern crate serde_derive;
extern crate notify; extern crate notify;
extern crate rand; extern crate rand;
extern crate rbx_tree;
extern crate regex;
extern crate serde; extern crate serde;
extern crate serde_json; extern crate serde_json;
extern crate regex; extern crate uuid;
extern crate rbx_tree;
#[cfg(test)] #[cfg(test)]
extern crate tempfile; extern crate tempfile;
// pub mod roblox_studio;
pub mod commands; pub mod commands;
pub mod id;
pub mod message_queue; pub mod message_queue;
pub mod pathext; pub mod pathext;
pub mod project; pub mod project;
// pub mod roblox_studio;
pub mod session; pub mod session;
pub mod session_id;
pub mod vfs; pub mod vfs;
pub mod web; pub mod web;
pub mod web_util; pub mod web_util;
// TODO: Remove
pub mod id;

View File

@@ -63,20 +63,16 @@ impl SourceProjectNode {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
struct SourceProject { struct SourceProject {
name: String, name: String,
tree: HashMap<String, SourceProjectNode>, tree: SourceProjectNode,
} }
impl SourceProject { impl SourceProject {
pub fn into_project(mut self, project_file_location: &Path) -> Project { pub fn into_project(self, project_file_location: &Path) -> Project {
let mut tree = HashMap::new(); let tree = self.tree.into_project_node(project_file_location);
for (node_name, node) in self.tree.drain() {
tree.insert(node_name, node.into_project_node(project_file_location));
}
Project { Project {
name: self.name, name: self.name,
tree: tree, tree,
file_location: PathBuf::from(project_file_location), file_location: PathBuf::from(project_file_location),
} }
} }
@@ -157,7 +153,7 @@ pub enum ProjectNode {
#[derive(Debug)] #[derive(Debug)]
pub struct Project { pub struct Project {
pub name: String, pub name: String,
pub tree: HashMap<String, ProjectNode>, pub tree: ProjectNode,
pub file_location: PathBuf, pub file_location: PathBuf,
} }

View File

@@ -1,12 +1,11 @@
use std::{ use std::{
collections::HashMap,
sync::{Arc, RwLock, Mutex, mpsc}, sync::{Arc, RwLock, Mutex, mpsc},
thread, thread,
io, io,
time::Duration, time::Duration,
}; };
use rand;
use notify::{ use notify::{
self, self,
DebouncedEvent, DebouncedEvent,
@@ -15,73 +14,65 @@ use notify::{
Watcher, Watcher,
}; };
use rbx_tree::RbxTree; use rbx_tree::{RbxTree, RbxInstance};
use ::{ use crate::{
message_queue::MessageQueue, message_queue::MessageQueue,
project::{Project, ProjectNode}, project::{Project, ProjectNode},
vfs::Vfs, vfs::Vfs,
session_id::SessionId,
}; };
const WATCH_TIMEOUT_MS: u64 = 100; const WATCH_TIMEOUT_MS: u64 = 100;
pub struct Session { pub struct Session {
project: Project, project: Project,
pub session_id: String, pub session_id: SessionId,
pub message_queue: Arc<MessageQueue>, pub message_queue: Arc<MessageQueue>,
pub tree: Arc<RwLock<RbxTree>>, pub tree: Arc<RwLock<RbxTree>>,
vfs: Arc<Mutex<Vfs>>, vfs: Arc<Mutex<Vfs>>,
watchers: Vec<RecommendedWatcher>, watchers: Vec<RecommendedWatcher>,
} }
impl Session { fn add_sync_points(vfs: &mut Vfs, project_node: &ProjectNode) -> io::Result<()> {
pub fn new(project: Project) -> Session { match project_node {
let session_id = rand::random::<u64>().to_string(); ProjectNode::Regular { children, .. } => {
for child in children.values() {
Session { add_sync_points(vfs, child)?;
session_id, }
project, },
message_queue: Arc::new(MessageQueue::new()), ProjectNode::SyncPoint { path } => {
tree: Arc::new(RwLock::new(RbxTree::new())), vfs.add_root(path)?;
vfs: Arc::new(Mutex::new(Vfs::new())), },
watchers: Vec::new(),
}
} }
pub fn start(&mut self) -> io::Result<()> { Ok(())
fn add_sync_points(vfs: &mut Vfs, project_node: &ProjectNode) -> io::Result<()> { }
match project_node {
ProjectNode::Regular { children, .. } => {
for child in children.values() {
add_sync_points(vfs, child)?;
}
},
ProjectNode::SyncPoint { path } => {
vfs.add_root(path)?;
},
}
Ok(()) impl Session {
} pub fn new(project: Project) -> io::Result<Session> {
let session_id = SessionId::new();
let vfs = Arc::new(Mutex::new(Vfs::new()));
let message_queue = Arc::new(MessageQueue::new());
let mut watchers = Vec::new();
{ {
let mut vfs = self.vfs.lock().unwrap(); let mut vfs_temp = vfs.lock().unwrap();
for child in self.project.tree.values() { add_sync_points(&mut vfs_temp, &project.tree)
add_sync_points(&mut vfs, child)?; .expect("Could not add sync points when starting new Rojo session");
}
for root in vfs.get_roots() {
info!("Watching {}", root.display());
for root in vfs_temp.get_roots() {
let (watch_tx, watch_rx) = mpsc::channel(); let (watch_tx, watch_rx) = mpsc::channel();
let mut watcher = notify::watcher(watch_tx, Duration::from_millis(WATCH_TIMEOUT_MS)).unwrap(); let mut watcher = notify::watcher(watch_tx, Duration::from_millis(WATCH_TIMEOUT_MS)).unwrap();
watcher.watch(root, RecursiveMode::Recursive).unwrap(); watcher.watch(root, RecursiveMode::Recursive)
self.watchers.push(watcher); .expect("Could not watch directory");
let vfs = Arc::clone(&self.vfs); watchers.push(watcher);
let vfs = Arc::clone(&vfs);
thread::spawn(move || { thread::spawn(move || {
loop { loop {
@@ -112,7 +103,20 @@ impl Session {
} }
} }
Ok(()) let tree = RbxTree::new(RbxInstance {
name: "ahhhh".to_string(),
class_name: "ahhh help me".to_string(),
properties: HashMap::new(),
});
Ok(Session {
session_id,
project,
message_queue,
tree: Arc::new(RwLock::new(tree)),
vfs,
watchers: Vec::new(),
})
} }
pub fn get_project(&self) -> &Project { pub fn get_project(&self) -> &Project {

11
server/src/session_id.rs Normal file
View File

@@ -0,0 +1,11 @@
use serde_derive::{Serialize, Deserialize};
use uuid::Uuid;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct SessionId(Uuid);
impl SessionId {
pub fn new() -> SessionId {
SessionId(Uuid::new_v4())
}
}

View File

@@ -7,15 +7,16 @@ use std::{
use rouille::{self, Request, Response}; use rouille::{self, Request, Response};
use rbx_tree::{RbxId, RootedRbxInstance}; use rbx_tree::{RbxId, RootedRbxInstance};
use ::{ use crate::{
message_queue::Message, message_queue::Message,
session::Session, session::Session,
session_id::SessionId,
}; };
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ServerInfoResponse<'a> { pub struct ServerInfoResponse<'a> {
pub session_id: &'a str, pub session_id: SessionId,
pub server_version: &'a str, pub server_version: &'a str,
pub protocol_version: u64, pub protocol_version: u64,
pub root_instance_id: RbxId, pub root_instance_id: RbxId,
@@ -24,7 +25,7 @@ pub struct ServerInfoResponse<'a> {
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ReadResponse<'a> { pub struct ReadResponse<'a> {
pub session_id: &'a str, pub session_id: SessionId,
pub message_cursor: u32, pub message_cursor: u32,
pub instances: HashMap<RbxId, Cow<'a, RootedRbxInstance>>, pub instances: HashMap<RbxId, Cow<'a, RootedRbxInstance>>,
} }
@@ -32,7 +33,7 @@ pub struct ReadResponse<'a> {
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SubscribeResponse<'a> { pub struct SubscribeResponse<'a> {
pub session_id: &'a str, pub session_id: SessionId,
pub message_cursor: u32, pub message_cursor: u32,
pub messages: Cow<'a, [Message]>, pub messages: Cow<'a, [Message]>,
} }
@@ -67,8 +68,8 @@ impl Server {
Response::json(&ServerInfoResponse { Response::json(&ServerInfoResponse {
server_version: self.server_version, server_version: self.server_version,
protocol_version: 2, protocol_version: 2,
session_id: &self.session.session_id, session_id: self.session.session_id,
root_instance_id: *tree.get_root_ids().iter().nth(0).unwrap(), // TODO root_instance_id: tree.get_root_id(),
}) })
}, },
@@ -84,7 +85,7 @@ impl Server {
if new_messages.len() > 0 { if new_messages.len() > 0 {
return Response::json(&SubscribeResponse { return Response::json(&SubscribeResponse {
session_id: &self.session.session_id, session_id: self.session.session_id,
messages: Cow::Borrowed(&[]), messages: Cow::Borrowed(&[]),
message_cursor: new_cursor, message_cursor: new_cursor,
}) })
@@ -106,7 +107,7 @@ impl Server {
let (new_cursor, new_messages) = message_queue.get_messages_since(cursor); let (new_cursor, new_messages) = message_queue.get_messages_since(cursor);
return Response::json(&SubscribeResponse { return Response::json(&SubscribeResponse {
session_id: &self.session.session_id, session_id: self.session.session_id,
messages: Cow::Owned(new_messages), messages: Cow::Owned(new_messages),
message_cursor: new_cursor, message_cursor: new_cursor,
}) })
@@ -146,7 +147,7 @@ impl Server {
} }
Response::json(&ReadResponse { Response::json(&ReadResponse {
session_id: &self.session.session_id, session_id: self.session.session_id,
message_cursor, message_cursor,
instances, instances,
}) })