forked from rojo-rbx/rojo
Iterating on project format to make it friendlier
This commit is contained in:
1
server/Cargo.lock
generated
1
server/Cargo.lock
generated
@@ -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)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,41 +14,27 @@ 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 {
|
|
||||||
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(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn start(&mut self) -> io::Result<()> {
|
|
||||||
fn add_sync_points(vfs: &mut Vfs, project_node: &ProjectNode) -> io::Result<()> {
|
|
||||||
match project_node {
|
match project_node {
|
||||||
ProjectNode::Regular { children, .. } => {
|
ProjectNode::Regular { children, .. } => {
|
||||||
for child in children.values() {
|
for child in children.values() {
|
||||||
@@ -62,26 +47,32 @@ impl Session {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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_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
11
server/src/session_id.rs
Normal 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())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user