mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-20 20:55:50 +00:00
Path and change tracking working
This commit is contained in:
@@ -18,8 +18,7 @@ use crate::{
|
||||
|
||||
pub struct RbxSession {
|
||||
tree: RbxTree,
|
||||
paths_to_node_ids: PathMap<RbxId>,
|
||||
ids_to_project_paths: HashMap<RbxId, String>,
|
||||
path_map: PathMap<RbxId>,
|
||||
message_queue: Arc<MessageQueue<InstanceChanges>>,
|
||||
imfs: Arc<Mutex<Imfs>>,
|
||||
project: Arc<Project>,
|
||||
@@ -31,19 +30,16 @@ impl RbxSession {
|
||||
imfs: Arc<Mutex<Imfs>>,
|
||||
message_queue: Arc<MessageQueue<InstanceChanges>>,
|
||||
) -> RbxSession {
|
||||
let mut path_map = PathMap::new();
|
||||
|
||||
let tree = {
|
||||
let temp_imfs = imfs.lock().unwrap();
|
||||
construct_initial_tree(&project, &temp_imfs)
|
||||
construct_initial_tree(&project, &temp_imfs, &mut path_map)
|
||||
};
|
||||
|
||||
// TODO: Restore these?
|
||||
let paths_to_node_ids = PathMap::new();
|
||||
let ids_to_project_paths = HashMap::new();
|
||||
|
||||
RbxSession {
|
||||
tree,
|
||||
paths_to_node_ids,
|
||||
ids_to_project_paths,
|
||||
path_map,
|
||||
message_queue,
|
||||
imfs,
|
||||
project,
|
||||
@@ -51,18 +47,25 @@ impl RbxSession {
|
||||
}
|
||||
|
||||
fn path_created_or_updated(&mut self, path: &Path) {
|
||||
let imfs = self.imfs.lock().unwrap();
|
||||
let root_path = imfs.get_root_for_path(path)
|
||||
.expect("Path was outside in-memory filesystem roots");
|
||||
|
||||
let closest_path = self.paths_to_node_ids.descend(root_path, path);
|
||||
let &instance_id = self.paths_to_node_ids.get(&closest_path).unwrap();
|
||||
|
||||
let snapshot = snapshot_instances_from_imfs(&imfs, &closest_path)
|
||||
.expect("Could not generate instance snapshot");
|
||||
|
||||
let mut changes = InstanceChanges::default();
|
||||
reconcile_subtree(&mut self.tree, instance_id, &snapshot, &mut changes);
|
||||
|
||||
{
|
||||
let imfs = self.imfs.lock().unwrap();
|
||||
let root_path = imfs.get_root_for_path(path)
|
||||
.expect("Path was outside in-memory filesystem roots");
|
||||
|
||||
let closest_path = self.path_map.descend(root_path, path);
|
||||
let &instance_id = self.path_map.get(&closest_path).unwrap();
|
||||
|
||||
let snapshot = snapshot_instances_from_imfs(&imfs, &closest_path)
|
||||
.expect("Could not generate instance snapshot");
|
||||
|
||||
reconcile_subtree(&mut self.tree, instance_id, &snapshot, &mut self.path_map, &mut changes);
|
||||
}
|
||||
|
||||
if !changes.is_empty() {
|
||||
self.message_queue.push_messages(&[changes]);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn path_created(&mut self, path: &Path) {
|
||||
@@ -90,7 +93,7 @@ impl RbxSession {
|
||||
pub fn path_removed(&mut self, path: &Path) {
|
||||
info!("Path removed: {}", path.display());
|
||||
|
||||
let instance_id = match self.paths_to_node_ids.remove(path) {
|
||||
let instance_id = match self.path_map.remove(path) {
|
||||
Some(id) => id,
|
||||
None => return,
|
||||
};
|
||||
@@ -121,19 +124,17 @@ impl RbxSession {
|
||||
pub fn get_tree(&self) -> &RbxTree {
|
||||
&self.tree
|
||||
}
|
||||
|
||||
pub fn get_project_path_map(&self) -> &HashMap<RbxId, String> {
|
||||
&self.ids_to_project_paths
|
||||
}
|
||||
}
|
||||
|
||||
pub fn construct_oneoff_tree(project: &Project, imfs: &Imfs) -> RbxTree {
|
||||
construct_initial_tree(project, imfs)
|
||||
let mut path_map = PathMap::new();
|
||||
construct_initial_tree(project, imfs, &mut path_map)
|
||||
}
|
||||
|
||||
fn construct_initial_tree(
|
||||
project: &Project,
|
||||
imfs: &Imfs,
|
||||
path_map: &mut PathMap<RbxId>,
|
||||
) -> RbxTree {
|
||||
let snapshot = construct_project_node(
|
||||
imfs,
|
||||
@@ -142,8 +143,9 @@ fn construct_initial_tree(
|
||||
);
|
||||
|
||||
let mut changes = InstanceChanges::default();
|
||||
let tree = reify_root(&snapshot, path_map, &mut changes);
|
||||
|
||||
reify_root(&snapshot, &mut changes)
|
||||
tree
|
||||
}
|
||||
|
||||
fn construct_project_node<'a>(
|
||||
|
||||
@@ -7,6 +7,8 @@ use std::{
|
||||
|
||||
use rbx_tree::{RbxTree, RbxId, RbxInstance, RbxValue};
|
||||
|
||||
use crate::path_map::PathMap;
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct InstanceChanges {
|
||||
pub added: HashSet<RbxId>,
|
||||
@@ -28,37 +30,61 @@ pub struct RbxSnapshotInstance<'a> {
|
||||
pub source_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
pub fn reify_root(snapshot: &RbxSnapshotInstance, changes: &mut InstanceChanges) -> RbxTree {
|
||||
pub fn reify_root(
|
||||
snapshot: &RbxSnapshotInstance,
|
||||
path_map: &mut PathMap<RbxId>,
|
||||
changes: &mut InstanceChanges,
|
||||
) -> RbxTree {
|
||||
let instance = reify_core(snapshot);
|
||||
let mut tree = RbxTree::new(instance);
|
||||
let root_id = tree.get_root_id();
|
||||
|
||||
if let Some(source_path) = &snapshot.source_path {
|
||||
path_map.insert(source_path.clone(), root_id);
|
||||
}
|
||||
|
||||
changes.added.insert(root_id);
|
||||
|
||||
for child in &snapshot.children {
|
||||
reify_subtree(child, &mut tree, root_id, changes);
|
||||
reify_subtree(child, &mut tree, root_id, path_map, changes);
|
||||
}
|
||||
|
||||
tree
|
||||
}
|
||||
|
||||
pub fn reify_subtree(snapshot: &RbxSnapshotInstance, tree: &mut RbxTree, parent_id: RbxId, changes: &mut InstanceChanges) {
|
||||
pub fn reify_subtree(
|
||||
snapshot: &RbxSnapshotInstance,
|
||||
tree: &mut RbxTree,
|
||||
parent_id: RbxId,
|
||||
path_map: &mut PathMap<RbxId>,
|
||||
changes: &mut InstanceChanges,
|
||||
) {
|
||||
let instance = reify_core(snapshot);
|
||||
let id = tree.insert_instance(instance, parent_id);
|
||||
|
||||
if let Some(source_path) = &snapshot.source_path {
|
||||
path_map.insert(source_path.clone(), id);
|
||||
}
|
||||
|
||||
changes.added.insert(id);
|
||||
|
||||
for child in &snapshot.children {
|
||||
reify_subtree(child, tree, id, changes);
|
||||
reify_subtree(child, tree, id, path_map, changes);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reconcile_subtree(tree: &mut RbxTree, id: RbxId, snapshot: &RbxSnapshotInstance, changes: &mut InstanceChanges) {
|
||||
pub fn reconcile_subtree(
|
||||
tree: &mut RbxTree,
|
||||
id: RbxId,
|
||||
snapshot: &RbxSnapshotInstance,
|
||||
path_map: &mut PathMap<RbxId>,
|
||||
changes: &mut InstanceChanges,
|
||||
) {
|
||||
if reconcile_instance_properties(tree.get_instance_mut(id).unwrap(), snapshot) {
|
||||
changes.updated.insert(id);
|
||||
}
|
||||
|
||||
reconcile_instance_children(tree, id, snapshot, changes);
|
||||
reconcile_instance_children(tree, id, snapshot, path_map, changes);
|
||||
}
|
||||
|
||||
fn reify_core(snapshot: &RbxSnapshotInstance) -> RbxInstance {
|
||||
@@ -138,7 +164,8 @@ fn reconcile_instance_children(
|
||||
tree: &mut RbxTree,
|
||||
id: RbxId,
|
||||
snapshot: &RbxSnapshotInstance,
|
||||
changes: &mut InstanceChanges
|
||||
path_map: &mut PathMap<RbxId>,
|
||||
changes: &mut InstanceChanges,
|
||||
) {
|
||||
let children_ids = tree.get_instance(id).unwrap().get_children_ids().to_vec();
|
||||
let child_count = children_ids.len().max(snapshot.children.len());
|
||||
@@ -168,7 +195,7 @@ fn reconcile_instance_children(
|
||||
}
|
||||
|
||||
for child_snapshot in &children_to_add {
|
||||
reify_subtree(child_snapshot, tree, id, changes);
|
||||
reify_subtree(child_snapshot, tree, id, path_map, changes);
|
||||
}
|
||||
|
||||
for child_id in &children_to_remove {
|
||||
@@ -180,6 +207,6 @@ fn reconcile_instance_children(
|
||||
}
|
||||
|
||||
for (child_id, child_snapshot) in &children_to_update {
|
||||
reconcile_subtree(tree, *child_id, child_snapshot, changes);
|
||||
reconcile_subtree(tree, *child_id, child_snapshot, path_map, changes);
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,6 @@ pub struct ServerInfoResponse<'a> {
|
||||
pub protocol_version: u64,
|
||||
pub root_instance_id: RbxId,
|
||||
pub project: Cow<'a, Project>,
|
||||
pub ids_to_project_paths: Cow<'a, HashMap<RbxId, String>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
@@ -80,7 +79,6 @@ impl Server {
|
||||
session_id: self.session.session_id,
|
||||
root_instance_id: tree.get_root_id(),
|
||||
project: Cow::Borrowed(&self.session.project),
|
||||
ids_to_project_paths: Cow::Borrowed(rbx_session.get_project_path_map()),
|
||||
})
|
||||
},
|
||||
|
||||
@@ -97,7 +95,7 @@ impl Server {
|
||||
if !new_messages.is_empty() {
|
||||
return Response::json(&SubscribeResponse {
|
||||
session_id: self.session.session_id,
|
||||
messages: Cow::Borrowed(&[]),
|
||||
messages: Cow::Borrowed(&new_messages),
|
||||
message_cursor: new_cursor,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user