mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-22 05:35:10 +00:00
Upgrade to rbx_dom_weak 2.0 (#377)
* Mostly mechanical port bits * Almost there * It builds again! * Turn on all the code again * Tests compiling but not passing * Stub work for value resolution * Implement resolution minus enums and derived properties * Implement property descriptor resolution * Update referent snapshots * Update unions test project Using a place file instead of a model yields better error messages in Roblox Studio. * Add easy shortcut to testing with local rbx-dom * Update rbx-dom * Add enum resolution * Update init.meta.json to use UnresolvedValue * Expand value resolution support, add test * Filter SharedString values from web API * Add 'property' builder method to InstanceSnapshot * Change InstanceSnapshot/InstanceBuilder boundary * Fix remove_file crash * rustfmt * Update to latest rbx_dom_lua * Update dependencies, including rbx_dom_weak * Update to latest rbx-dom * Update dependencies * Update rbx-dom, fixing more bugs * Remove experimental warning on binary place builds * Remove unused imports
This commit is contained in:
committed by
GitHub
parent
b84aab0960
commit
59ef5f05ea
@@ -2,11 +2,11 @@
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use rbx_dom_weak::{RbxId, RbxInstanceProperties, RbxValue};
|
||||
use rbx_dom_weak::types::{Ref, Variant};
|
||||
|
||||
use super::{
|
||||
patch::{AppliedPatchSet, AppliedPatchUpdate, PatchSet, PatchUpdate},
|
||||
InstancePropertiesWithMeta, InstanceSnapshot, RojoTree,
|
||||
InstanceSnapshot, RojoTree,
|
||||
};
|
||||
|
||||
/// Consumes the input `PatchSet`, applying all of its prescribed changes to the
|
||||
@@ -37,7 +37,7 @@ pub fn apply_patch_set(tree: &mut RojoTree, patch_set: PatchSet) -> AppliedPatch
|
||||
struct PatchApplyContext {
|
||||
/// A map from transient snapshot IDs (generated by snapshot middleware) to
|
||||
/// instance IDs in the actual tree. These are both the same data type so
|
||||
/// that they fit into the same `RbxValue::Ref` type.
|
||||
/// that they fit into the same `Variant::Ref` type.
|
||||
///
|
||||
/// At this point in the patch process, IDs in instance properties have been
|
||||
/// partially translated from 'snapshot space' into 'tree space' by the
|
||||
@@ -53,7 +53,7 @@ struct PatchApplyContext {
|
||||
/// #2 should not occur in well-formed projects, but is indistinguishable
|
||||
/// from #1 right now. It could happen if two model files try to reference
|
||||
/// eachother.
|
||||
snapshot_id_to_instance_id: HashMap<RbxId, RbxId>,
|
||||
snapshot_id_to_instance_id: HashMap<Ref, Ref>,
|
||||
|
||||
/// The properties of instances added by the current `PatchSet`.
|
||||
///
|
||||
@@ -68,7 +68,7 @@ struct PatchApplyContext {
|
||||
///
|
||||
/// This doesn't affect updated instances, since they're always applied
|
||||
/// after we've added all the instances from the patch.
|
||||
added_instance_properties: HashMap<RbxId, HashMap<String, RbxValue>>,
|
||||
added_instance_properties: HashMap<Ref, HashMap<String, Variant>>,
|
||||
|
||||
/// The current applied patch result, describing changes made to the tree.
|
||||
applied_patch_set: AppliedPatchSet,
|
||||
@@ -93,11 +93,10 @@ fn finalize_patch_application(context: PatchApplyContext, tree: &mut RojoTree) -
|
||||
.expect("Invalid instance ID in deferred property map");
|
||||
|
||||
for (key, mut property_value) in properties {
|
||||
if let RbxValue::Ref { value: Some(id) } = property_value {
|
||||
if let Some(&instance_id) = context.snapshot_id_to_instance_id.get(&id) {
|
||||
property_value = RbxValue::Ref {
|
||||
value: Some(instance_id),
|
||||
};
|
||||
if let Variant::Ref(referent) = property_value {
|
||||
if let Some(&instance_referent) = context.snapshot_id_to_instance_id.get(&referent)
|
||||
{
|
||||
property_value = Variant::Ref(instance_referent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,50 +107,40 @@ fn finalize_patch_application(context: PatchApplyContext, tree: &mut RojoTree) -
|
||||
context.applied_patch_set
|
||||
}
|
||||
|
||||
fn apply_remove_instance(context: &mut PatchApplyContext, tree: &mut RojoTree, removed_id: RbxId) {
|
||||
match tree.remove_instance(removed_id) {
|
||||
Some(_) => context.applied_patch_set.removed.push(removed_id),
|
||||
None => {
|
||||
log::warn!(
|
||||
"Patch misapplication: Tried to remove instance {} but it did not exist.",
|
||||
removed_id
|
||||
);
|
||||
}
|
||||
}
|
||||
fn apply_remove_instance(context: &mut PatchApplyContext, tree: &mut RojoTree, removed_id: Ref) {
|
||||
tree.remove(removed_id);
|
||||
context.applied_patch_set.removed.push(removed_id);
|
||||
}
|
||||
|
||||
fn apply_add_child(
|
||||
context: &mut PatchApplyContext,
|
||||
tree: &mut RojoTree,
|
||||
parent_id: RbxId,
|
||||
parent_id: Ref,
|
||||
snapshot: InstanceSnapshot,
|
||||
) {
|
||||
let properties = InstancePropertiesWithMeta {
|
||||
properties: RbxInstanceProperties {
|
||||
name: snapshot.name.into_owned(),
|
||||
class_name: snapshot.class_name.into_owned(),
|
||||
let snapshot_id = snapshot.snapshot_id;
|
||||
let properties = snapshot.properties;
|
||||
let children = snapshot.children;
|
||||
|
||||
// Property assignment is deferred until after we know about all
|
||||
// instances in this patch. See `PatchApplyContext` for details.
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
metadata: snapshot.metadata,
|
||||
};
|
||||
|
||||
let id = tree.insert_instance(properties, parent_id);
|
||||
// Property application is deferred until after all children
|
||||
// are constructed. This helps apply referents correctly.
|
||||
let remaining_snapshot = InstanceSnapshot::new()
|
||||
.name(snapshot.name)
|
||||
.class_name(snapshot.class_name)
|
||||
.metadata(snapshot.metadata)
|
||||
.snapshot_id(snapshot.snapshot_id);
|
||||
|
||||
let id = tree.insert_instance(parent_id, remaining_snapshot);
|
||||
context.applied_patch_set.added.push(id);
|
||||
|
||||
context
|
||||
.added_instance_properties
|
||||
.insert(id, snapshot.properties);
|
||||
context.added_instance_properties.insert(id, properties);
|
||||
|
||||
if let Some(snapshot_id) = snapshot.snapshot_id {
|
||||
if let Some(snapshot_id) = snapshot_id {
|
||||
context.snapshot_id_to_instance_id.insert(snapshot_id, id);
|
||||
}
|
||||
|
||||
for child_snapshot in snapshot.children {
|
||||
apply_add_child(context, tree, id, child_snapshot);
|
||||
for child in children {
|
||||
apply_add_child(context, tree, id, child);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +156,7 @@ fn apply_update_child(context: &mut PatchApplyContext, tree: &mut RojoTree, patc
|
||||
Some(instance) => instance,
|
||||
None => {
|
||||
log::warn!(
|
||||
"Patch misapplication: Instance {}, referred to by update patch, did not exist.",
|
||||
"Patch misapplication: Instance {:?}, referred to by update patch, did not exist.",
|
||||
patch.id
|
||||
);
|
||||
return;
|
||||
@@ -189,23 +178,24 @@ fn apply_update_child(context: &mut PatchApplyContext, tree: &mut RojoTree, patc
|
||||
// Ref values need to be potentially rewritten from snapshot IDs to
|
||||
// instance IDs if they referred to an instance that was created as
|
||||
// part of this patch.
|
||||
Some(RbxValue::Ref { value: Some(id) }) => {
|
||||
Some(Variant::Ref(referent)) => {
|
||||
if referent.is_none() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If our ID is not found in this map, then it either refers to
|
||||
// an existing instance NOT added by this patch, or there was an
|
||||
// error. See `PatchApplyContext::snapshot_id_to_instance_id`
|
||||
// for more info.
|
||||
let new_id = context
|
||||
let new_referent = context
|
||||
.snapshot_id_to_instance_id
|
||||
.get(&id)
|
||||
.get(&referent)
|
||||
.copied()
|
||||
.unwrap_or(id);
|
||||
.unwrap_or(referent);
|
||||
|
||||
instance.properties_mut().insert(
|
||||
key.clone(),
|
||||
RbxValue::Ref {
|
||||
value: Some(new_id),
|
||||
},
|
||||
);
|
||||
instance
|
||||
.properties_mut()
|
||||
.insert(key.clone(), Variant::Ref(new_referent));
|
||||
}
|
||||
Some(ref value) => {
|
||||
instance.properties_mut().insert(key.clone(), value.clone());
|
||||
@@ -225,10 +215,10 @@ fn apply_update_child(context: &mut PatchApplyContext, tree: &mut RojoTree, patc
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
use std::{borrow::Cow, collections::HashMap};
|
||||
use std::borrow::Cow;
|
||||
|
||||
use maplit::hashmap;
|
||||
use rbx_dom_weak::RbxValue;
|
||||
use rbx_dom_weak::types::Variant;
|
||||
|
||||
use super::super::PatchAdd;
|
||||
|
||||
@@ -236,14 +226,7 @@ mod test {
|
||||
fn add_from_empty() {
|
||||
let _ = env_logger::try_init();
|
||||
|
||||
let mut tree = RojoTree::new(InstancePropertiesWithMeta {
|
||||
properties: RbxInstanceProperties {
|
||||
name: "Folder".to_owned(),
|
||||
class_name: "Folder".to_owned(),
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
metadata: Default::default(),
|
||||
});
|
||||
let mut tree = RojoTree::new(InstanceSnapshot::new());
|
||||
|
||||
let root_id = tree.get_root_id();
|
||||
|
||||
@@ -253,7 +236,7 @@ mod test {
|
||||
name: Cow::Borrowed("Foo"),
|
||||
class_name: Cow::Borrowed("Bar"),
|
||||
properties: hashmap! {
|
||||
"Baz".to_owned() => RbxValue::Int32 { value: 5 },
|
||||
"Baz".to_owned() => Variant::Int32(5),
|
||||
},
|
||||
children: Vec::new(),
|
||||
};
|
||||
@@ -282,18 +265,14 @@ mod test {
|
||||
fn update_existing() {
|
||||
let _ = env_logger::try_init();
|
||||
|
||||
let mut tree = RojoTree::new(InstancePropertiesWithMeta {
|
||||
properties: RbxInstanceProperties {
|
||||
name: "OldName".to_owned(),
|
||||
class_name: "OldClassName".to_owned(),
|
||||
properties: hashmap! {
|
||||
"Foo".to_owned() => RbxValue::Int32 { value: 7 },
|
||||
"Bar".to_owned() => RbxValue::Int32 { value: 3 },
|
||||
"Unchanged".to_owned() => RbxValue::Int32 { value: -5 },
|
||||
},
|
||||
},
|
||||
metadata: Default::default(),
|
||||
});
|
||||
let mut tree = RojoTree::new(
|
||||
InstanceSnapshot::new()
|
||||
.class_name("OldClassName")
|
||||
.name("OldName")
|
||||
.property("Foo", 7i32)
|
||||
.property("Bar", 3i32)
|
||||
.property("Unchanged", -5i32),
|
||||
);
|
||||
|
||||
let root_id = tree.get_root_id();
|
||||
|
||||
@@ -303,13 +282,13 @@ mod test {
|
||||
changed_class_name: Some("NewClassName".to_owned()),
|
||||
changed_properties: hashmap! {
|
||||
// The value of Foo has changed
|
||||
"Foo".to_owned() => Some(RbxValue::Int32 { value: 8 }),
|
||||
"Foo".to_owned() => Some(Variant::Int32(8)),
|
||||
|
||||
// Bar has been deleted
|
||||
"Bar".to_owned() => None,
|
||||
|
||||
// Baz has been added
|
||||
"Baz".to_owned() => Some(RbxValue::Int32 { value: 10 }),
|
||||
"Baz".to_owned() => Some(Variant::Int32(10)),
|
||||
},
|
||||
changed_metadata: None,
|
||||
};
|
||||
@@ -322,9 +301,9 @@ mod test {
|
||||
apply_patch_set(&mut tree, patch_set);
|
||||
|
||||
let expected_properties = hashmap! {
|
||||
"Foo".to_owned() => RbxValue::Int32 { value: 8 },
|
||||
"Baz".to_owned() => RbxValue::Int32 { value: 10 },
|
||||
"Unchanged".to_owned() => RbxValue::Int32 { value: -5 },
|
||||
"Foo".to_owned() => Variant::Int32(8),
|
||||
"Baz".to_owned() => Variant::Int32(10),
|
||||
"Unchanged".to_owned() => Variant::Int32(-5),
|
||||
};
|
||||
|
||||
let root_instance = tree.get_instance(root_id).unwrap();
|
||||
|
||||
Reference in New Issue
Block a user