diff --git a/server/Cargo.lock b/server/Cargo.lock index 083fe9ff..26c6120d 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -708,6 +708,7 @@ dependencies = [ "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)", "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)", ] diff --git a/server/Cargo.toml b/server/Cargo.toml index 3381e44b..9afa0d53 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -31,6 +31,7 @@ lazy_static = "1.0" log = "0.4" env_logger = "0.5" rbx-tree = { path = "../../rbx-tree" } +uuid = { version = "0.7", features = ["v4", "serde"] } [dev-dependencies] tempfile = "3.0" diff --git a/server/src/commands/serve.rs b/server/src/commands/serve.rs index 4164026d..c00eec8d 100644 --- a/server/src/commands/serve.rs +++ b/server/src/commands/serve.rs @@ -27,12 +27,7 @@ pub fn serve(fuzzy_project_location: &Path) { // roblox_studio::install_bundled_plugin().unwrap(); - let session = Arc::new({ - let mut session = Session::new(project); - session.start().unwrap(); - session - }); - + let session = Arc::new(Session::new(project).unwrap()); let server = Server::new(Arc::clone(&session)); println!("Server listening on port 34872"); diff --git a/server/src/lib.rs b/server/src/lib.rs index e0e28ba8..065245bd 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -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 log; +#[macro_use] extern crate rouille; +#[macro_use] extern crate serde_derive; extern crate notify; extern crate rand; +extern crate rbx_tree; +extern crate regex; extern crate serde; extern crate serde_json; -extern crate regex; -extern crate rbx_tree; +extern crate uuid; #[cfg(test)] extern crate tempfile; +// pub mod roblox_studio; pub mod commands; -pub mod id; pub mod message_queue; pub mod pathext; pub mod project; -// pub mod roblox_studio; pub mod session; +pub mod session_id; pub mod vfs; pub mod web; -pub mod web_util; \ No newline at end of file +pub mod web_util; + +// TODO: Remove +pub mod id; \ No newline at end of file diff --git a/server/src/project.rs b/server/src/project.rs index b0a39e5a..5bec5112 100644 --- a/server/src/project.rs +++ b/server/src/project.rs @@ -63,20 +63,16 @@ impl SourceProjectNode { #[serde(rename_all = "camelCase")] struct SourceProject { name: String, - tree: HashMap, + tree: SourceProjectNode, } impl SourceProject { - pub fn into_project(mut self, project_file_location: &Path) -> Project { - let mut tree = HashMap::new(); - - for (node_name, node) in self.tree.drain() { - tree.insert(node_name, node.into_project_node(project_file_location)); - } + pub fn into_project(self, project_file_location: &Path) -> Project { + let tree = self.tree.into_project_node(project_file_location); Project { name: self.name, - tree: tree, + tree, file_location: PathBuf::from(project_file_location), } } @@ -157,7 +153,7 @@ pub enum ProjectNode { #[derive(Debug)] pub struct Project { pub name: String, - pub tree: HashMap, + pub tree: ProjectNode, pub file_location: PathBuf, } diff --git a/server/src/session.rs b/server/src/session.rs index b08810fe..3aef342f 100644 --- a/server/src/session.rs +++ b/server/src/session.rs @@ -1,12 +1,11 @@ use std::{ + collections::HashMap, sync::{Arc, RwLock, Mutex, mpsc}, thread, io, time::Duration, }; -use rand; - use notify::{ self, DebouncedEvent, @@ -15,73 +14,65 @@ use notify::{ Watcher, }; -use rbx_tree::RbxTree; +use rbx_tree::{RbxTree, RbxInstance}; -use ::{ +use crate::{ message_queue::MessageQueue, project::{Project, ProjectNode}, vfs::Vfs, + session_id::SessionId, }; const WATCH_TIMEOUT_MS: u64 = 100; pub struct Session { project: Project, - pub session_id: String, + pub session_id: SessionId, pub message_queue: Arc, pub tree: Arc>, vfs: Arc>, watchers: Vec, } -impl Session { - pub fn new(project: Project) -> Session { - let session_id = rand::random::().to_string(); - - Session { - session_id, - project, - message_queue: Arc::new(MessageQueue::new()), - tree: Arc::new(RwLock::new(RbxTree::new())), - vfs: Arc::new(Mutex::new(Vfs::new())), - watchers: Vec::new(), - } +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)?; + }, } - pub fn start(&mut self) -> io::Result<()> { - 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(()) +} - Ok(()) - } +impl Session { + pub fn new(project: Project) -> io::Result { + 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, child)?; - } - - for root in vfs.get_roots() { - info!("Watching {}", root.display()); + add_sync_points(&mut vfs_temp, &project.tree) + .expect("Could not add sync points when starting new Rojo session"); + for root in vfs_temp.get_roots() { let (watch_tx, watch_rx) = mpsc::channel(); let mut watcher = notify::watcher(watch_tx, Duration::from_millis(WATCH_TIMEOUT_MS)).unwrap(); - watcher.watch(root, RecursiveMode::Recursive).unwrap(); - self.watchers.push(watcher); + watcher.watch(root, RecursiveMode::Recursive) + .expect("Could not watch directory"); - let vfs = Arc::clone(&self.vfs); + watchers.push(watcher); + + let vfs = Arc::clone(&vfs); thread::spawn(move || { 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 { diff --git a/server/src/session_id.rs b/server/src/session_id.rs new file mode 100644 index 00000000..67783a7f --- /dev/null +++ b/server/src/session_id.rs @@ -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()) + } +} \ No newline at end of file diff --git a/server/src/web.rs b/server/src/web.rs index 919fcba9..4f19e39c 100644 --- a/server/src/web.rs +++ b/server/src/web.rs @@ -7,15 +7,16 @@ use std::{ use rouille::{self, Request, Response}; use rbx_tree::{RbxId, RootedRbxInstance}; -use ::{ +use crate::{ message_queue::Message, session::Session, + session_id::SessionId, }; #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ServerInfoResponse<'a> { - pub session_id: &'a str, + pub session_id: SessionId, pub server_version: &'a str, pub protocol_version: u64, pub root_instance_id: RbxId, @@ -24,7 +25,7 @@ pub struct ServerInfoResponse<'a> { #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ReadResponse<'a> { - pub session_id: &'a str, + pub session_id: SessionId, pub message_cursor: u32, pub instances: HashMap>, } @@ -32,7 +33,7 @@ pub struct ReadResponse<'a> { #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SubscribeResponse<'a> { - pub session_id: &'a str, + pub session_id: SessionId, pub message_cursor: u32, pub messages: Cow<'a, [Message]>, } @@ -67,8 +68,8 @@ impl Server { Response::json(&ServerInfoResponse { server_version: self.server_version, protocol_version: 2, - session_id: &self.session.session_id, - root_instance_id: *tree.get_root_ids().iter().nth(0).unwrap(), // TODO + session_id: self.session.session_id, + root_instance_id: tree.get_root_id(), }) }, @@ -84,7 +85,7 @@ impl Server { if new_messages.len() > 0 { return Response::json(&SubscribeResponse { - session_id: &self.session.session_id, + session_id: self.session.session_id, messages: Cow::Borrowed(&[]), message_cursor: new_cursor, }) @@ -106,7 +107,7 @@ impl Server { let (new_cursor, new_messages) = message_queue.get_messages_since(cursor); return Response::json(&SubscribeResponse { - session_id: &self.session.session_id, + session_id: self.session.session_id, messages: Cow::Owned(new_messages), message_cursor: new_cursor, }) @@ -146,7 +147,7 @@ impl Server { } Response::json(&ReadResponse { - session_id: &self.session.session_id, + session_id: self.session.session_id, message_cursor, instances, })