mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-21 05:06:29 +00:00
Vfs -> Imfs, clean up and document a bit
This commit is contained in:
10
server/Cargo.lock
generated
10
server/Cargo.lock
generated
@@ -349,11 +349,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
@@ -698,6 +695,7 @@ version = "0.5.0"
|
||||
dependencies = [
|
||||
"clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"notify 4.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -875,7 +873,7 @@ name = "thread_local"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1117,7 +1115,7 @@ dependencies = [
|
||||
"checksum inotify 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887fcc180136e77a85e6a6128579a719027b1bab9b1c38ea4444244fe262c20c"
|
||||
"checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"
|
||||
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
|
||||
"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
|
||||
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
||||
"checksum log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cba860f648db8e6f269df990180c2217f333472b4a6e901e97446858487971e2"
|
||||
|
||||
@@ -35,3 +35,4 @@ uuid = { version = "0.7", features = ["v4", "serde"] }
|
||||
[dev-dependencies]
|
||||
tempfile = "3.0"
|
||||
walkdir = "2.1"
|
||||
lazy_static = "1.2"
|
||||
|
||||
@@ -13,18 +13,18 @@ use notify::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
vfs::Vfs,
|
||||
imfs::Imfs,
|
||||
rbx_session::RbxSession,
|
||||
};
|
||||
|
||||
const WATCH_TIMEOUT: Duration = Duration::from_millis(100);
|
||||
|
||||
fn handle_event(vfs: &Mutex<Vfs>, rbx_session: &Mutex<RbxSession>, event: DebouncedEvent) {
|
||||
fn handle_event(imfs: &Mutex<Imfs>, rbx_session: &Mutex<RbxSession>, event: DebouncedEvent) {
|
||||
match event {
|
||||
DebouncedEvent::Create(path) => {
|
||||
{
|
||||
let mut vfs = vfs.lock().unwrap();
|
||||
vfs.path_created(&path).unwrap();
|
||||
let mut imfs = imfs.lock().unwrap();
|
||||
imfs.path_created(&path).unwrap();
|
||||
}
|
||||
|
||||
{
|
||||
@@ -34,8 +34,8 @@ fn handle_event(vfs: &Mutex<Vfs>, rbx_session: &Mutex<RbxSession>, event: Deboun
|
||||
},
|
||||
DebouncedEvent::Write(path) => {
|
||||
{
|
||||
let mut vfs = vfs.lock().unwrap();
|
||||
vfs.path_updated(&path).unwrap();
|
||||
let mut imfs = imfs.lock().unwrap();
|
||||
imfs.path_updated(&path).unwrap();
|
||||
}
|
||||
|
||||
{
|
||||
@@ -45,8 +45,8 @@ fn handle_event(vfs: &Mutex<Vfs>, rbx_session: &Mutex<RbxSession>, event: Deboun
|
||||
},
|
||||
DebouncedEvent::Remove(path) => {
|
||||
{
|
||||
let mut vfs = vfs.lock().unwrap();
|
||||
vfs.path_removed(&path).unwrap();
|
||||
let mut imfs = imfs.lock().unwrap();
|
||||
imfs.path_removed(&path).unwrap();
|
||||
}
|
||||
|
||||
{
|
||||
@@ -56,8 +56,8 @@ fn handle_event(vfs: &Mutex<Vfs>, rbx_session: &Mutex<RbxSession>, event: Deboun
|
||||
},
|
||||
DebouncedEvent::Rename(from_path, to_path) => {
|
||||
{
|
||||
let mut vfs = vfs.lock().unwrap();
|
||||
vfs.path_moved(&from_path, &to_path).unwrap();
|
||||
let mut imfs = imfs.lock().unwrap();
|
||||
imfs.path_moved(&from_path, &to_path).unwrap();
|
||||
}
|
||||
|
||||
{
|
||||
@@ -77,13 +77,13 @@ pub struct FsWatcher {
|
||||
}
|
||||
|
||||
impl FsWatcher {
|
||||
pub fn start(vfs: Arc<Mutex<Vfs>>, rbx_session: Arc<Mutex<RbxSession>>) -> FsWatcher {
|
||||
pub fn start(imfs: Arc<Mutex<Imfs>>, rbx_session: Arc<Mutex<RbxSession>>) -> FsWatcher {
|
||||
let mut watchers = Vec::new();
|
||||
|
||||
{
|
||||
let vfs_temp = vfs.lock().unwrap();
|
||||
let imfs_temp = imfs.lock().unwrap();
|
||||
|
||||
for root_path in vfs_temp.get_roots() {
|
||||
for root_path in imfs_temp.get_roots() {
|
||||
let (watch_tx, watch_rx) = mpsc::channel();
|
||||
|
||||
let mut watcher = notify::watcher(watch_tx, WATCH_TIMEOUT)
|
||||
@@ -94,7 +94,7 @@ impl FsWatcher {
|
||||
|
||||
watchers.push(watcher);
|
||||
|
||||
let vfs = Arc::clone(&vfs);
|
||||
let imfs = Arc::clone(&imfs);
|
||||
let rbx_session = Arc::clone(&rbx_session);
|
||||
let root_path = root_path.clone();
|
||||
|
||||
@@ -102,7 +102,7 @@ impl FsWatcher {
|
||||
info!("Watcher thread ({}) started", root_path.display());
|
||||
loop {
|
||||
match watch_rx.recv() {
|
||||
Ok(event) => handle_event(&vfs, &rbx_session, event),
|
||||
Ok(event) => handle_event(&imfs, &rbx_session, event),
|
||||
Err(_) => break,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,15 +5,18 @@ use std::{
|
||||
io,
|
||||
};
|
||||
|
||||
/// The in-memory filesystem keeps a mirror of all files being watcher by Rojo
|
||||
/// in order to deduplicate file changes in the case of bidirectional syncing
|
||||
/// from Roblox Studio.
|
||||
#[derive(Debug)]
|
||||
pub struct Vfs {
|
||||
items: HashMap<PathBuf, VfsItem>,
|
||||
pub struct Imfs {
|
||||
items: HashMap<PathBuf, ImfsItem>,
|
||||
roots: HashSet<PathBuf>,
|
||||
}
|
||||
|
||||
impl Vfs {
|
||||
pub fn new() -> Vfs {
|
||||
Vfs {
|
||||
impl Imfs {
|
||||
pub fn new() -> Imfs {
|
||||
Imfs {
|
||||
items: HashMap::new(),
|
||||
roots: HashSet::new(),
|
||||
}
|
||||
@@ -23,7 +26,7 @@ impl Vfs {
|
||||
&self.roots
|
||||
}
|
||||
|
||||
pub fn get(&self, path: &Path) -> Option<&VfsItem> {
|
||||
pub fn get(&self, path: &Path) -> Option<&ImfsItem> {
|
||||
debug_assert!(path.is_absolute());
|
||||
debug_assert!(self.is_within_roots(path));
|
||||
|
||||
@@ -36,7 +39,7 @@ impl Vfs {
|
||||
|
||||
self.roots.insert(path.to_path_buf());
|
||||
|
||||
VfsItem::read_from_disk(self, path)?;
|
||||
ImfsItem::read_from_disk(self, path)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -50,7 +53,7 @@ impl Vfs {
|
||||
}
|
||||
}
|
||||
|
||||
VfsItem::read_from_disk(self, path)?;
|
||||
ImfsItem::read_from_disk(self, path)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -64,7 +67,7 @@ impl Vfs {
|
||||
}
|
||||
}
|
||||
|
||||
VfsItem::read_from_disk(self, path)?;
|
||||
ImfsItem::read_from_disk(self, path)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -74,14 +77,14 @@ impl Vfs {
|
||||
|
||||
if let Some(parent_path) = path.parent() {
|
||||
if self.is_within_roots(parent_path) {
|
||||
if let Some(VfsItem::Directory(parent)) = self.items.get_mut(parent_path) {
|
||||
if let Some(ImfsItem::Directory(parent)) = self.items.get_mut(parent_path) {
|
||||
parent.children.remove(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match self.items.remove(path) {
|
||||
Some(VfsItem::Directory(directory)) => {
|
||||
Some(ImfsItem::Directory(directory)) => {
|
||||
for child_path in &directory.children {
|
||||
self.path_removed(child_path)?;
|
||||
}
|
||||
@@ -115,30 +118,30 @@ impl Vfs {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VfsFile {
|
||||
pub struct ImfsFile {
|
||||
pub path: PathBuf,
|
||||
pub contents: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VfsDirectory {
|
||||
pub struct ImfsDirectory {
|
||||
pub path: PathBuf,
|
||||
pub children: HashSet<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum VfsItem {
|
||||
File(VfsFile),
|
||||
Directory(VfsDirectory),
|
||||
pub enum ImfsItem {
|
||||
File(ImfsFile),
|
||||
Directory(ImfsDirectory),
|
||||
}
|
||||
|
||||
impl VfsItem {
|
||||
fn read_from_disk<'a, 'b>(vfs: &'a mut Vfs, path: &'b Path) -> io::Result<&'a VfsItem> {
|
||||
impl ImfsItem {
|
||||
fn read_from_disk<'a, 'b>(vfs: &'a mut Imfs, path: &'b Path) -> io::Result<&'a ImfsItem> {
|
||||
let metadata = fs::metadata(path)?;
|
||||
|
||||
if metadata.is_file() {
|
||||
let contents = fs::read(path)?;
|
||||
let item = VfsItem::File(VfsFile {
|
||||
let item = ImfsItem::File(ImfsFile {
|
||||
path: path.to_path_buf(),
|
||||
contents,
|
||||
});
|
||||
@@ -153,12 +156,12 @@ impl VfsItem {
|
||||
let entry = entry?;
|
||||
let child_path = entry.path();
|
||||
|
||||
VfsItem::read_from_disk(vfs, &child_path)?;
|
||||
ImfsItem::read_from_disk(vfs, &child_path)?;
|
||||
|
||||
children.insert(child_path);
|
||||
}
|
||||
|
||||
let item = VfsItem::Directory(VfsDirectory {
|
||||
let item = ImfsItem::Directory(ImfsDirectory {
|
||||
path: path.to_path_buf(),
|
||||
children,
|
||||
});
|
||||
@@ -20,6 +20,6 @@ pub mod project;
|
||||
pub mod rbx_session;
|
||||
pub mod session;
|
||||
pub mod session_id;
|
||||
pub mod vfs;
|
||||
pub mod imfs;
|
||||
pub mod web;
|
||||
pub mod web_util;
|
||||
@@ -10,7 +10,7 @@ use rbx_tree::{RbxTree, RbxId, RbxInstance, RbxValue};
|
||||
use crate::{
|
||||
project::{Project, ProjectNode, InstanceProjectNode},
|
||||
message_queue::MessageQueue,
|
||||
vfs::{Vfs, VfsItem},
|
||||
imfs::{Imfs, ImfsItem},
|
||||
};
|
||||
|
||||
pub struct RbxSession {
|
||||
@@ -18,15 +18,15 @@ pub struct RbxSession {
|
||||
paths_to_ids: HashMap<PathBuf, RbxId>,
|
||||
ids_to_project_paths: HashMap<RbxId, String>,
|
||||
message_queue: Arc<MessageQueue>,
|
||||
vfs: Arc<Mutex<Vfs>>,
|
||||
imfs: Arc<Mutex<Imfs>>,
|
||||
project: Arc<Project>,
|
||||
}
|
||||
|
||||
impl RbxSession {
|
||||
pub fn new(project: Arc<Project>, vfs: Arc<Mutex<Vfs>>, message_queue: Arc<MessageQueue>) -> RbxSession {
|
||||
pub fn new(project: Arc<Project>, imfs: Arc<Mutex<Imfs>>, message_queue: Arc<MessageQueue>) -> RbxSession {
|
||||
let (tree, paths_to_ids, ids_to_project_paths) = {
|
||||
let temp_vfs = vfs.lock().unwrap();
|
||||
construct_initial_tree(&project, &temp_vfs)
|
||||
let temp_imfs = imfs.lock().unwrap();
|
||||
construct_initial_tree(&project, &temp_imfs)
|
||||
};
|
||||
|
||||
RbxSession {
|
||||
@@ -34,7 +34,7 @@ impl RbxSession {
|
||||
paths_to_ids,
|
||||
ids_to_project_paths,
|
||||
message_queue,
|
||||
vfs,
|
||||
imfs,
|
||||
project,
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ impl RbxSession {
|
||||
|
||||
fn construct_initial_tree(
|
||||
project: &Project,
|
||||
vfs: &Vfs,
|
||||
imfs: &Imfs,
|
||||
) -> (RbxTree, HashMap<PathBuf, RbxId>, HashMap<RbxId, String>) {
|
||||
let paths_to_ids = HashMap::new();
|
||||
let ids_to_project_paths = HashMap::new();
|
||||
@@ -80,7 +80,7 @@ fn construct_initial_tree(
|
||||
|
||||
let mut context = ConstructContext {
|
||||
tree,
|
||||
vfs,
|
||||
imfs,
|
||||
paths_to_ids,
|
||||
ids_to_project_paths,
|
||||
};
|
||||
@@ -98,7 +98,7 @@ fn construct_initial_tree(
|
||||
|
||||
struct ConstructContext<'a> {
|
||||
tree: RbxTree,
|
||||
vfs: &'a Vfs,
|
||||
imfs: &'a Imfs,
|
||||
paths_to_ids: HashMap<PathBuf, RbxId>,
|
||||
ids_to_project_paths: HashMap<RbxId, String>,
|
||||
}
|
||||
@@ -151,8 +151,8 @@ fn construct_sync_point_node(
|
||||
instance_name: &str,
|
||||
file_path: &Path,
|
||||
) -> RbxId {
|
||||
match context.vfs.get(&file_path) {
|
||||
Some(VfsItem::File(file)) => {
|
||||
match context.imfs.get(&file_path) {
|
||||
Some(ImfsItem::File(file)) => {
|
||||
let contents = str::from_utf8(&file.contents).unwrap();
|
||||
|
||||
let mut properties = HashMap::new();
|
||||
@@ -169,7 +169,7 @@ fn construct_sync_point_node(
|
||||
|
||||
id
|
||||
},
|
||||
Some(VfsItem::Directory(directory)) => {
|
||||
Some(ImfsItem::Directory(directory)) => {
|
||||
let instance = RbxInstance {
|
||||
class_name: "Folder".to_string(),
|
||||
name: instance_name.to_string(),
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
use crate::{
|
||||
message_queue::MessageQueue,
|
||||
project::{Project, ProjectNode},
|
||||
vfs::Vfs,
|
||||
imfs::Imfs,
|
||||
session_id::SessionId,
|
||||
rbx_session::RbxSession,
|
||||
fs_watcher::FsWatcher,
|
||||
@@ -20,15 +20,15 @@ pub struct Session {
|
||||
fs_watcher: FsWatcher,
|
||||
}
|
||||
|
||||
fn add_sync_points(vfs: &mut Vfs, project_node: &ProjectNode) -> io::Result<()> {
|
||||
fn add_sync_points(imfs: &mut Imfs, project_node: &ProjectNode) -> io::Result<()> {
|
||||
match project_node {
|
||||
ProjectNode::Instance(node) => {
|
||||
for child in node.children.values() {
|
||||
add_sync_points(vfs, child)?;
|
||||
add_sync_points(imfs, child)?;
|
||||
}
|
||||
},
|
||||
ProjectNode::SyncPoint(node) => {
|
||||
vfs.add_root(&node.path)?;
|
||||
imfs.add_root(&node.path)?;
|
||||
},
|
||||
}
|
||||
|
||||
@@ -37,23 +37,23 @@ fn add_sync_points(vfs: &mut Vfs, project_node: &ProjectNode) -> io::Result<()>
|
||||
|
||||
impl Session {
|
||||
pub fn new(project: Project) -> io::Result<Session> {
|
||||
let mut vfs = Vfs::new();
|
||||
let mut imfs = Imfs::new();
|
||||
|
||||
add_sync_points(&mut vfs, &project.tree)
|
||||
add_sync_points(&mut imfs, &project.tree)
|
||||
.expect("Could not add sync points when starting new Rojo session");
|
||||
|
||||
let vfs = Arc::new(Mutex::new(vfs));
|
||||
let imfs = Arc::new(Mutex::new(imfs));
|
||||
let project = Arc::new(project);
|
||||
let message_queue = Arc::new(MessageQueue::new());
|
||||
|
||||
let rbx_session = Arc::new(Mutex::new(RbxSession::new(
|
||||
Arc::clone(&project),
|
||||
Arc::clone(&vfs),
|
||||
Arc::clone(&imfs),
|
||||
Arc::clone(&message_queue),
|
||||
)));
|
||||
|
||||
let fs_watcher = FsWatcher::start(
|
||||
Arc::clone(&vfs),
|
||||
Arc::clone(&imfs),
|
||||
Arc::clone(&rbx_session),
|
||||
);
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ fn foo() {
|
||||
let project = Project::load_exact(&project_file_location).unwrap();
|
||||
|
||||
assert_eq!(project.name, "foo");
|
||||
assert_eq!(project.tree.len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -31,5 +30,4 @@ fn empty() {
|
||||
let project = Project::load_exact(&project_file_location).unwrap();
|
||||
|
||||
assert_eq!(project.name, "empty");
|
||||
assert_eq!(project.tree.len(), 0);
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "foo",
|
||||
"tree": {
|
||||
"$className": "DataModel",
|
||||
"ReplicatedStorage": {
|
||||
"$className": "ReplicatedStorage",
|
||||
"Rojo": {
|
||||
|
||||
Reference in New Issue
Block a user