mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-25 07:06:12 +00:00
Snapshot madness
This commit is contained in:
@@ -1,17 +1,19 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
borrow::Cow,
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
path::Path,
|
path::Path,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
str,
|
str,
|
||||||
};
|
};
|
||||||
|
|
||||||
use rbx_tree::{RbxTree, RbxId, RbxInstance, RbxValue};
|
use rbx_tree::{RbxTree, RbxId};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
project::{Project, ProjectNode, InstanceProjectNode},
|
project::{Project, ProjectNode, InstanceProjectNode},
|
||||||
message_queue::{Message, MessageQueue},
|
message_queue::{Message, MessageQueue},
|
||||||
imfs::{Imfs, ImfsItem, ImfsFile},
|
imfs::{Imfs, ImfsItem, ImfsFile},
|
||||||
path_map::PathMap,
|
path_map::PathMap,
|
||||||
|
rbx_snapshot::{RbxSnapshotInstance, RbxSnapshotValue, reify_root},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct RbxSession {
|
pub struct RbxSession {
|
||||||
@@ -25,11 +27,15 @@ pub struct RbxSession {
|
|||||||
|
|
||||||
impl RbxSession {
|
impl RbxSession {
|
||||||
pub fn new(project: Arc<Project>, imfs: Arc<Mutex<Imfs>>, message_queue: Arc<MessageQueue>) -> RbxSession {
|
pub fn new(project: Arc<Project>, imfs: Arc<Mutex<Imfs>>, message_queue: Arc<MessageQueue>) -> RbxSession {
|
||||||
let (tree, path_id_tree, ids_to_project_paths) = {
|
let tree = {
|
||||||
let temp_imfs = imfs.lock().unwrap();
|
let temp_imfs = imfs.lock().unwrap();
|
||||||
construct_initial_tree(&project, &temp_imfs)
|
construct_initial_tree(&project, &temp_imfs)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: Restore these?
|
||||||
|
let path_id_tree = PathMap::new();
|
||||||
|
let ids_to_project_paths = HashMap::new();
|
||||||
|
|
||||||
RbxSession {
|
RbxSession {
|
||||||
tree,
|
tree,
|
||||||
path_id_tree,
|
path_id_tree,
|
||||||
@@ -113,11 +119,10 @@ impl RbxSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn construct_oneoff_tree(project: &Project, imfs: &Imfs) -> RbxTree {
|
pub fn construct_oneoff_tree(project: &Project, imfs: &Imfs) -> RbxTree {
|
||||||
construct_initial_tree(project, imfs).0
|
construct_initial_tree(project, imfs)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ConstructContext<'a> {
|
struct ConstructContext<'a> {
|
||||||
tree: Option<RbxTree>,
|
|
||||||
imfs: &'a Imfs,
|
imfs: &'a Imfs,
|
||||||
path_id_tree: PathMap<RbxId>,
|
path_id_tree: PathMap<RbxId>,
|
||||||
ids_to_project_paths: HashMap<RbxId, String>,
|
ids_to_project_paths: HashMap<RbxId, String>,
|
||||||
@@ -126,78 +131,49 @@ struct ConstructContext<'a> {
|
|||||||
fn construct_initial_tree(
|
fn construct_initial_tree(
|
||||||
project: &Project,
|
project: &Project,
|
||||||
imfs: &Imfs,
|
imfs: &Imfs,
|
||||||
) -> (RbxTree, PathMap<RbxId>, HashMap<RbxId, String>) {
|
) -> RbxTree {
|
||||||
let path_id_tree = PathMap::new();
|
let path_id_tree = PathMap::new();
|
||||||
let ids_to_project_paths = HashMap::new();
|
let ids_to_project_paths = HashMap::new();
|
||||||
|
|
||||||
let mut context = ConstructContext {
|
let mut context = ConstructContext {
|
||||||
tree: None,
|
|
||||||
imfs,
|
imfs,
|
||||||
path_id_tree,
|
path_id_tree,
|
||||||
ids_to_project_paths,
|
ids_to_project_paths,
|
||||||
};
|
};
|
||||||
|
|
||||||
construct_project_node(
|
let snapshot = construct_project_node(
|
||||||
&mut context,
|
&mut context,
|
||||||
None,
|
|
||||||
"",
|
"",
|
||||||
&project.name,
|
&project.name,
|
||||||
&project.tree,
|
&project.tree,
|
||||||
);
|
);
|
||||||
|
|
||||||
let tree = context.tree.unwrap();
|
reify_root(&snapshot)
|
||||||
|
|
||||||
(tree, context.path_id_tree, context.ids_to_project_paths)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_or_create_tree(context: &mut ConstructContext, parent_instance_id: Option<RbxId>, instance: RbxInstance) -> RbxId {
|
fn construct_project_node<'a>(
|
||||||
match (&mut context.tree, parent_instance_id) {
|
context: &mut ConstructContext<'a>,
|
||||||
(Some(tree), Some(parent_instance_id)) => {
|
|
||||||
tree.insert_instance(instance, parent_instance_id)
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
let new_tree = RbxTree::new(instance);
|
|
||||||
let root_id = new_tree.get_root_id();
|
|
||||||
|
|
||||||
context.tree = Some(new_tree);
|
|
||||||
root_id
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn construct_project_node(
|
|
||||||
context: &mut ConstructContext,
|
|
||||||
parent_instance_id: Option<RbxId>,
|
|
||||||
instance_path: &str,
|
instance_path: &str,
|
||||||
instance_name: &str,
|
instance_name: &'a str,
|
||||||
project_node: &ProjectNode,
|
project_node: &'a ProjectNode,
|
||||||
) {
|
) -> RbxSnapshotInstance<'a> {
|
||||||
match project_node {
|
match project_node {
|
||||||
ProjectNode::Instance(node) => {
|
ProjectNode::Instance(node) => {
|
||||||
let id = construct_instance_node(context, parent_instance_id, &instance_path, instance_name, node);
|
construct_instance_node(context, &instance_path, instance_name, node)
|
||||||
context.ids_to_project_paths.insert(id, instance_path.to_string());
|
|
||||||
},
|
},
|
||||||
ProjectNode::SyncPoint(node) => {
|
ProjectNode::SyncPoint(node) => {
|
||||||
let id = construct_sync_point_node(context, parent_instance_id, instance_name, &node.path);
|
construct_sync_point_node(context, instance_name, &node.path)
|
||||||
context.ids_to_project_paths.insert(id, instance_path.to_string());
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn construct_instance_node(
|
fn construct_instance_node<'a>(
|
||||||
context: &mut ConstructContext,
|
context: &mut ConstructContext<'a>,
|
||||||
parent_instance_id: Option<RbxId>,
|
|
||||||
instance_path: &str,
|
instance_path: &str,
|
||||||
instance_name: &str,
|
instance_name: &'a str,
|
||||||
project_node: &InstanceProjectNode,
|
project_node: &'a InstanceProjectNode,
|
||||||
) -> RbxId {
|
) -> RbxSnapshotInstance<'a> {
|
||||||
let instance = RbxInstance {
|
let mut children = Vec::new();
|
||||||
class_name: project_node.class_name.clone(),
|
|
||||||
name: instance_name.to_string(),
|
|
||||||
properties: HashMap::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let id = insert_or_create_tree(context, parent_instance_id, instance);
|
|
||||||
|
|
||||||
for (child_name, child_project_node) in &project_node.children {
|
for (child_name, child_project_node) in &project_node.children {
|
||||||
let child_path = if instance_path.is_empty() {
|
let child_path = if instance_path.is_empty() {
|
||||||
@@ -206,10 +182,15 @@ fn construct_instance_node(
|
|||||||
format!("{}/{}", instance_path, child_name)
|
format!("{}/{}", instance_path, child_name)
|
||||||
};
|
};
|
||||||
|
|
||||||
construct_project_node(context, Some(id), &child_path, child_name, child_project_node);
|
children.push(construct_project_node(context, &child_path, child_name, child_project_node));
|
||||||
}
|
}
|
||||||
|
|
||||||
id
|
RbxSnapshotInstance {
|
||||||
|
class_name: Cow::Borrowed(&project_node.class_name),
|
||||||
|
name: Cow::Borrowed(instance_name),
|
||||||
|
properties: HashMap::new(),
|
||||||
|
children,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
@@ -233,12 +214,11 @@ fn classify_file(file: &ImfsFile) -> Option<FileType> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn construct_sync_point_node(
|
fn construct_sync_point_node<'a>(
|
||||||
context: &mut ConstructContext,
|
context: &mut ConstructContext<'a>,
|
||||||
parent_instance_id: Option<RbxId>,
|
instance_name: &'a str,
|
||||||
instance_name: &str,
|
|
||||||
file_path: &Path,
|
file_path: &Path,
|
||||||
) -> RbxId {
|
) -> RbxSnapshotInstance<'a> {
|
||||||
match context.imfs.get(&file_path) {
|
match context.imfs.get(&file_path) {
|
||||||
Some(ImfsItem::File(file)) => {
|
Some(ImfsItem::File(file)) => {
|
||||||
let file_type = classify_file(file).unwrap(); // TODO: Don't die here!
|
let file_type = classify_file(file).unwrap(); // TODO: Don't die here!
|
||||||
@@ -252,35 +232,29 @@ fn construct_sync_point_node(
|
|||||||
let contents = str::from_utf8(&file.contents).unwrap();
|
let contents = str::from_utf8(&file.contents).unwrap();
|
||||||
|
|
||||||
let mut properties = HashMap::new();
|
let mut properties = HashMap::new();
|
||||||
properties.insert("Source".to_string(), RbxValue::String { value: contents.to_string() });
|
properties.insert("Source".to_string(), RbxSnapshotValue::String(Cow::Borrowed(contents)));
|
||||||
|
|
||||||
let instance = RbxInstance {
|
let instance = RbxSnapshotInstance {
|
||||||
class_name: class_name.to_string(),
|
class_name: Cow::Borrowed(class_name),
|
||||||
name: instance_name.to_string(),
|
name: Cow::Borrowed(instance_name),
|
||||||
properties,
|
properties,
|
||||||
|
children: Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let id = insert_or_create_tree(context, parent_instance_id, instance);
|
instance
|
||||||
|
|
||||||
context.path_id_tree.insert(file.path.clone(), id);
|
|
||||||
|
|
||||||
id
|
|
||||||
},
|
},
|
||||||
Some(ImfsItem::Directory(directory)) => {
|
Some(ImfsItem::Directory(directory)) => {
|
||||||
let init_path = directory.path.join("init.lua");
|
let init_path = directory.path.join("init.lua");
|
||||||
|
|
||||||
let id = if directory.children.contains(&init_path) {
|
let mut instance = if directory.children.contains(&init_path) {
|
||||||
construct_sync_point_node(context, parent_instance_id, instance_name, &init_path)
|
construct_sync_point_node(context, instance_name, &init_path)
|
||||||
} else {
|
} else {
|
||||||
let instance = RbxInstance {
|
RbxSnapshotInstance {
|
||||||
class_name: "Folder".to_string(),
|
class_name: Cow::Borrowed("Folder"),
|
||||||
name: instance_name.to_string(),
|
name: Cow::Borrowed(instance_name),
|
||||||
properties: HashMap::new(),
|
properties: HashMap::new(),
|
||||||
};
|
children: Vec::new(),
|
||||||
|
}
|
||||||
let id = insert_or_create_tree(context, parent_instance_id, instance);
|
|
||||||
context.path_id_tree.insert(directory.path.clone(), id);
|
|
||||||
id
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for child_path in &directory.children {
|
for child_path in &directory.children {
|
||||||
@@ -290,11 +264,11 @@ fn construct_sync_point_node(
|
|||||||
ImfsItem::Directory(_) => child_path.file_name().unwrap().to_str().unwrap(),
|
ImfsItem::Directory(_) => child_path.file_name().unwrap().to_str().unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
construct_sync_point_node(context, Some(id), child_instance_name, child_path);
|
instance.children.push(construct_sync_point_node(context, child_instance_name, child_path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
id
|
instance
|
||||||
},
|
},
|
||||||
None => panic!("Couldn't read {} from disk", file_path.display()),
|
None => panic!("Couldn't read {} from disk", file_path.display()),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,57 +4,62 @@ use std::{
|
|||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
};
|
};
|
||||||
|
|
||||||
use rbx_tree::{RbxTree, RbxId};
|
use rbx_tree::{RbxTree, RbxId, RbxInstance, RbxValue};
|
||||||
|
|
||||||
use crate::{
|
|
||||||
imfs::{Imfs, ImfsItem, ImfsFile, ImfsDirectory},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct RbxSnapshotInstance<'a> {
|
pub struct RbxSnapshotInstance<'a> {
|
||||||
name: String,
|
pub name: Cow<'a, str>,
|
||||||
class_name: String,
|
pub class_name: Cow<'a, str>,
|
||||||
properties: HashMap<String, RbxSnapshotValue<'a>>,
|
pub properties: HashMap<String, RbxSnapshotValue<'a>>,
|
||||||
children: Vec<RbxSnapshotInstance<'a>>,
|
pub children: Vec<RbxSnapshotInstance<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum RbxSnapshotValue<'a> {
|
pub enum RbxSnapshotValue<'a> {
|
||||||
String(Cow<'a, str>),
|
String(Cow<'a, str>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reify(snapshot: RbxSnapshotInstance, tree: &mut RbxTree, parent_id: RbxId) {
|
impl<'a> RbxSnapshotValue<'a> {
|
||||||
unimplemented!()
|
pub fn to_rbx_value(&self) -> RbxValue {
|
||||||
}
|
match self {
|
||||||
|
RbxSnapshotValue::String(value) => RbxValue::String {
|
||||||
pub fn render<'a>(imfs: &'a Imfs, imfs_item: &'a ImfsItem) -> RbxSnapshotInstance<'a> {
|
value: value.to_string(),
|
||||||
match imfs_item {
|
},
|
||||||
ImfsItem::File(file) => {
|
}
|
||||||
let name = file.path.file_stem().unwrap().to_str().unwrap();
|
}
|
||||||
let source = str::from_utf8(&file.contents).unwrap();
|
}
|
||||||
let mut properties = HashMap::new();
|
|
||||||
properties.insert("Source".to_string(), RbxSnapshotValue::String(Cow::Borrowed(source)));
|
fn reify_core(snapshot: &RbxSnapshotInstance) -> RbxInstance {
|
||||||
|
let mut properties = HashMap::new();
|
||||||
RbxSnapshotInstance {
|
|
||||||
name: name.to_string(),
|
for (key, value) in &snapshot.properties {
|
||||||
class_name: "ModuleScript".to_string(),
|
properties.insert(key.clone(), value.to_rbx_value());
|
||||||
properties,
|
}
|
||||||
children: Vec::new(),
|
|
||||||
}
|
let instance = RbxInstance {
|
||||||
},
|
name: snapshot.name.to_string(),
|
||||||
ImfsItem::Directory(directory) => {
|
class_name: snapshot.class_name.to_string(),
|
||||||
let name = directory.path.file_name().unwrap().to_str().unwrap();
|
properties,
|
||||||
let mut children = Vec::new();
|
};
|
||||||
|
|
||||||
for child_path in &directory.children {
|
instance
|
||||||
let child_item = imfs.get(child_path).unwrap();
|
}
|
||||||
children.push(render(imfs, child_item));
|
|
||||||
}
|
pub fn reify_root(snapshot: &RbxSnapshotInstance) -> RbxTree {
|
||||||
|
let instance = reify_core(snapshot);
|
||||||
RbxSnapshotInstance {
|
let mut tree = RbxTree::new(instance);
|
||||||
name: name.to_string(),
|
let root_id = tree.get_root_id();
|
||||||
class_name: "Folder".to_string(),
|
|
||||||
properties: HashMap::new(),
|
for child in &snapshot.children {
|
||||||
children,
|
reify_child(child, &mut tree, root_id);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
tree
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reify_child(snapshot: &RbxSnapshotInstance, tree: &mut RbxTree, parent_id: RbxId) {
|
||||||
|
let instance = reify_core(snapshot);
|
||||||
|
let id = tree.insert_instance(instance, parent_id);
|
||||||
|
|
||||||
|
for child in &snapshot.children {
|
||||||
|
reify_child(child, tree, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user