forked from rojo-rbx/rojo
RbxSession refactoring stuff
This commit is contained in:
@@ -1,15 +1,10 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, RwLock, Mutex, mpsc},
|
||||
path::{Path, PathBuf},
|
||||
sync::{Arc, Mutex, mpsc},
|
||||
thread,
|
||||
io,
|
||||
time::Duration,
|
||||
str,
|
||||
};
|
||||
|
||||
use serde_json;
|
||||
|
||||
use notify::{
|
||||
self,
|
||||
DebouncedEvent,
|
||||
@@ -18,142 +13,66 @@ use notify::{
|
||||
Watcher,
|
||||
};
|
||||
|
||||
use rbx_tree::{RbxId, RbxTree, RbxInstance, RbxValue};
|
||||
|
||||
use crate::{
|
||||
message_queue::MessageQueue,
|
||||
project::{Project, ProjectNode},
|
||||
vfs::{Vfs, VfsItem},
|
||||
vfs::Vfs,
|
||||
session_id::SessionId,
|
||||
rbx_session::RbxSession,
|
||||
};
|
||||
|
||||
const WATCH_TIMEOUT_MS: u64 = 100;
|
||||
|
||||
pub struct Session {
|
||||
project: Project,
|
||||
project: Arc<Project>,
|
||||
pub session_id: SessionId,
|
||||
pub message_queue: Arc<MessageQueue>,
|
||||
pub tree: Arc<RwLock<RbxTree>>,
|
||||
paths_to_ids: HashMap<PathBuf, RbxId>,
|
||||
pub rbx_session: Arc<Mutex<RbxSession>>,
|
||||
vfs: Arc<Mutex<Vfs>>,
|
||||
watchers: Vec<RecommendedWatcher>,
|
||||
}
|
||||
|
||||
fn add_sync_points(vfs: &mut Vfs, project_node: &ProjectNode) -> io::Result<()> {
|
||||
match project_node {
|
||||
ProjectNode::Regular { children, .. } => {
|
||||
for child in children.values() {
|
||||
ProjectNode::Instance(node) => {
|
||||
for child in node.children.values() {
|
||||
add_sync_points(vfs, child)?;
|
||||
}
|
||||
},
|
||||
ProjectNode::SyncPoint { path } => {
|
||||
vfs.add_root(path)?;
|
||||
ProjectNode::SyncPoint(node) => {
|
||||
vfs.add_root(&node.path)?;
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_sync_to_rbx(
|
||||
tree: &mut RbxTree,
|
||||
vfs: &Vfs,
|
||||
paths_to_ids: &mut HashMap<PathBuf, RbxId>,
|
||||
parent_node_id: RbxId,
|
||||
project_node_name: &str,
|
||||
path: &Path
|
||||
) {
|
||||
match vfs.get(path) {
|
||||
Some(VfsItem::File(file)) => {
|
||||
let contents = str::from_utf8(vfs.get_contents(&file.path).unwrap()).unwrap();
|
||||
|
||||
let mut properties = HashMap::new();
|
||||
properties.insert("Source".to_string(), RbxValue::String { value: contents.to_string() });
|
||||
|
||||
let instance = RbxInstance {
|
||||
class_name: "ModuleScript".to_string(),
|
||||
name: project_node_name.to_string(),
|
||||
properties,
|
||||
};
|
||||
|
||||
let id = tree.insert_instance(instance, parent_node_id);
|
||||
paths_to_ids.insert(path.to_path_buf(), id);
|
||||
},
|
||||
Some(VfsItem::Directory(directory)) => {
|
||||
let instance = RbxInstance {
|
||||
class_name: "Folder".to_string(),
|
||||
name: project_node_name.to_string(),
|
||||
properties: HashMap::new(),
|
||||
};
|
||||
|
||||
let id = tree.insert_instance(instance, parent_node_id);
|
||||
paths_to_ids.insert(path.to_path_buf(), id);
|
||||
|
||||
for child_path in &directory.children {
|
||||
let child_name = child_path.file_name().unwrap().to_str().unwrap();
|
||||
read_sync_to_rbx(tree, vfs, paths_to_ids, id, child_name, child_path);
|
||||
}
|
||||
},
|
||||
None => panic!("Couldn't read {} from disk", path.display()),
|
||||
}
|
||||
}
|
||||
|
||||
fn read_to_rbx(
|
||||
tree: &mut RbxTree,
|
||||
vfs: &Vfs,
|
||||
paths_to_ids: &mut HashMap<PathBuf, RbxId>,
|
||||
parent_node_id: RbxId,
|
||||
project_node_name: &str,
|
||||
project_node: &ProjectNode
|
||||
) {
|
||||
match project_node {
|
||||
ProjectNode::Regular { children, class_name, .. } => {
|
||||
let instance = RbxInstance {
|
||||
class_name: class_name.clone(),
|
||||
name: project_node_name.to_string(),
|
||||
properties: HashMap::new(),
|
||||
};
|
||||
|
||||
let id = tree.insert_instance(instance, parent_node_id);
|
||||
|
||||
for (child_name, child_project_node) in children {
|
||||
read_to_rbx(tree, vfs, paths_to_ids, id, child_name, child_project_node);
|
||||
}
|
||||
},
|
||||
ProjectNode::SyncPoint { path } => {
|
||||
read_sync_to_rbx(tree, vfs, paths_to_ids, parent_node_id, project_node_name, path);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
impl Session {
|
||||
pub fn new(project: Project) -> io::Result<Session> {
|
||||
let mut vfs = Vfs::new();
|
||||
let project = Arc::new(project);
|
||||
let message_queue = Arc::new(MessageQueue::new());
|
||||
let vfs = Arc::new(Mutex::new(Vfs::new()));
|
||||
|
||||
let (change_tx, change_rx) = mpsc::channel();
|
||||
{
|
||||
let mut vfs = vfs.lock().unwrap();
|
||||
add_sync_points(&mut vfs, &project.tree)
|
||||
.expect("Could not add sync points when starting new Rojo session");
|
||||
}
|
||||
|
||||
add_sync_points(&mut vfs, &project.tree)
|
||||
.expect("Could not add sync points when starting new Rojo session");
|
||||
let rbx_session = Arc::new(Mutex::new(RbxSession::new(
|
||||
Arc::clone(&project),
|
||||
Arc::clone(&vfs),
|
||||
Arc::clone(&message_queue),
|
||||
)));
|
||||
|
||||
let mut tree = RbxTree::new(RbxInstance {
|
||||
name: "ahhhh".to_string(),
|
||||
class_name: "ahhh help me".to_string(),
|
||||
properties: HashMap::new(),
|
||||
});
|
||||
|
||||
let mut paths_to_ids = HashMap::new();
|
||||
|
||||
let root_id = tree.get_root_id();
|
||||
read_to_rbx(&mut tree, &vfs, &mut paths_to_ids, root_id, "root", &project.tree);
|
||||
|
||||
println!("tree:\n{}", serde_json::to_string(&tree).unwrap());
|
||||
|
||||
let vfs = Arc::new(Mutex::new(vfs));
|
||||
let mut watchers = Vec::new();
|
||||
|
||||
{
|
||||
let vfs_temp = vfs.lock().unwrap();
|
||||
|
||||
for root in vfs_temp.get_roots() {
|
||||
println!("Watching {}", root.display());
|
||||
|
||||
let (watch_tx, watch_rx) = mpsc::channel();
|
||||
|
||||
let mut watcher = notify::watcher(watch_tx, Duration::from_millis(WATCH_TIMEOUT_MS)).unwrap();
|
||||
@@ -163,8 +82,8 @@ impl Session {
|
||||
|
||||
watchers.push(watcher);
|
||||
|
||||
let change_tx = change_tx.clone();
|
||||
let vfs = Arc::clone(&vfs);
|
||||
let rbx_session = Arc::clone(&rbx_session);
|
||||
|
||||
thread::spawn(move || {
|
||||
loop {
|
||||
@@ -172,23 +91,40 @@ impl Session {
|
||||
Ok(event) => {
|
||||
match event {
|
||||
DebouncedEvent::Create(path) | DebouncedEvent::Write(path) => {
|
||||
let mut vfs = vfs.lock().unwrap();
|
||||
vfs.add_or_update(&path).unwrap();
|
||||
change_tx.send(path.clone()).unwrap();
|
||||
{
|
||||
let mut vfs = vfs.lock().unwrap();
|
||||
vfs.add_or_update(&path).unwrap();
|
||||
}
|
||||
|
||||
{
|
||||
let mut rbx_session = rbx_session.lock().unwrap();
|
||||
rbx_session.path_created_or_updated(&path);
|
||||
}
|
||||
},
|
||||
DebouncedEvent::Remove(path) => {
|
||||
let mut vfs = vfs.lock().unwrap();
|
||||
vfs.remove(&path);
|
||||
change_tx.send(path.clone()).unwrap();
|
||||
{
|
||||
let mut vfs = vfs.lock().unwrap();
|
||||
vfs.remove(&path);
|
||||
}
|
||||
|
||||
{
|
||||
let mut rbx_session = rbx_session.lock().unwrap();
|
||||
rbx_session.path_removed(&path);
|
||||
}
|
||||
},
|
||||
DebouncedEvent::Rename(from_path, to_path) => {
|
||||
let mut vfs = vfs.lock().unwrap();
|
||||
vfs.remove(&from_path);
|
||||
vfs.add_or_update(&to_path).unwrap();
|
||||
change_tx.send(from_path.clone()).unwrap();
|
||||
change_tx.send(to_path.clone()).unwrap();
|
||||
{
|
||||
let mut vfs = vfs.lock().unwrap();
|
||||
vfs.remove(&from_path);
|
||||
vfs.add_or_update(&to_path).unwrap();
|
||||
}
|
||||
|
||||
{
|
||||
let mut rbx_session = rbx_session.lock().unwrap();
|
||||
rbx_session.path_renamed(&from_path, &to_path);
|
||||
}
|
||||
},
|
||||
_ => continue,
|
||||
_ => {},
|
||||
};
|
||||
},
|
||||
Err(_) => break,
|
||||
@@ -199,17 +135,15 @@ impl Session {
|
||||
}
|
||||
}
|
||||
|
||||
let message_queue = Arc::new(MessageQueue::new());
|
||||
let session_id = SessionId::new();
|
||||
|
||||
Ok(Session {
|
||||
session_id,
|
||||
paths_to_ids,
|
||||
rbx_session,
|
||||
project,
|
||||
message_queue,
|
||||
tree: Arc::new(RwLock::new(tree)),
|
||||
vfs,
|
||||
watchers: Vec::new(),
|
||||
watchers,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user