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_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)",
]

View File

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

View File

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

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 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;
pub mod web_util;
// TODO: Remove
pub mod id;

View File

@@ -63,20 +63,16 @@ impl SourceProjectNode {
#[serde(rename_all = "camelCase")]
struct SourceProject {
name: String,
tree: HashMap<String, SourceProjectNode>,
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<String, ProjectNode>,
pub tree: ProjectNode,
pub file_location: PathBuf,
}

View File

@@ -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<MessageQueue>,
pub tree: Arc<RwLock<RbxTree>>,
vfs: Arc<Mutex<Vfs>>,
watchers: Vec<RecommendedWatcher>,
}
impl Session {
pub fn new(project: Project) -> Session {
let session_id = rand::random::<u64>().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<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, 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 {

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 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<RbxId, Cow<'a, RootedRbxInstance>>,
}
@@ -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,
})