mirror of
https://github.com/lune-org/lune.git
synced 2024-12-12 13:00:37 +00:00
Use clone_multiple_into_external in Document instance methods (#117)
This commit is contained in:
parent
74d7f3d66f
commit
c43648faec
4 changed files with 109 additions and 47 deletions
|
@ -1,4 +1,4 @@
|
||||||
use rbx_dom_weak::{InstanceBuilder as DomInstanceBuilder, WeakDom};
|
use rbx_dom_weak::{types::Ref as DomRef, InstanceBuilder as DomInstanceBuilder, WeakDom};
|
||||||
use rbx_xml::{
|
use rbx_xml::{
|
||||||
DecodeOptions as XmlDecodeOptions, DecodePropertyBehavior as XmlDecodePropertyBehavior,
|
DecodeOptions as XmlDecodeOptions, DecodePropertyBehavior as XmlDecodePropertyBehavior,
|
||||||
EncodeOptions as XmlEncodeOptions, EncodePropertyBehavior as XmlEncodePropertyBehavior,
|
EncodeOptions as XmlEncodeOptions, EncodePropertyBehavior as XmlEncodePropertyBehavior,
|
||||||
|
@ -247,11 +247,13 @@ impl Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut dom = WeakDom::new(DomInstanceBuilder::new("ROOT"));
|
let mut dom = WeakDom::new(DomInstanceBuilder::new("ROOT"));
|
||||||
|
let children: Vec<DomRef> = i
|
||||||
|
.get_children()
|
||||||
|
.iter()
|
||||||
|
.map(|instance| instance.dom_ref)
|
||||||
|
.collect();
|
||||||
|
|
||||||
for data_model_child in i.get_children() {
|
Instance::clone_multiple_into_external_dom(&children, &mut dom);
|
||||||
data_model_child.clone_into_external_dom(&mut dom);
|
|
||||||
}
|
|
||||||
|
|
||||||
postprocess_dom_for_place(&mut dom);
|
postprocess_dom_for_place(&mut dom);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
@ -274,11 +276,9 @@ impl Document {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut dom = WeakDom::new(DomInstanceBuilder::new("ROOT"));
|
let mut dom = WeakDom::new(DomInstanceBuilder::new("ROOT"));
|
||||||
|
let instances: Vec<DomRef> = v.iter().map(|instance| instance.dom_ref).collect();
|
||||||
|
|
||||||
for instance in v {
|
Instance::clone_multiple_into_external_dom(&instances, &mut dom);
|
||||||
instance.clone_into_external_dom(&mut dom);
|
|
||||||
}
|
|
||||||
|
|
||||||
postprocess_dom_for_model(&mut dom);
|
postprocess_dom_for_model(&mut dom);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|
|
@ -144,6 +144,21 @@ impl Instance {
|
||||||
cloned
|
cloned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clone_multiple_into_external_dom(
|
||||||
|
referents: &[DomRef],
|
||||||
|
external_dom: &mut WeakDom,
|
||||||
|
) -> Vec<DomRef> {
|
||||||
|
let dom = INTERNAL_DOM.lock().expect("Failed to lock document");
|
||||||
|
|
||||||
|
let cloned = dom.clone_multiple_into_external(referents, external_dom);
|
||||||
|
|
||||||
|
for referent in cloned.iter() {
|
||||||
|
external_dom.transfer_within(*referent, external_dom.root_ref());
|
||||||
|
}
|
||||||
|
|
||||||
|
cloned
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Clones the instance and all of its descendants, and orphans it.
|
Clones the instance and all of its descendants, and orphans it.
|
||||||
|
|
||||||
|
|
|
@ -2,31 +2,53 @@ local fs = require("@lune/fs")
|
||||||
local roblox = require("@lune/roblox")
|
local roblox = require("@lune/roblox")
|
||||||
local Instance = roblox.Instance
|
local Instance = roblox.Instance
|
||||||
|
|
||||||
local instances = {
|
-- Smoke tests
|
||||||
Instance.new("Model"),
|
do
|
||||||
Instance.new("Part"),
|
local instances = {
|
||||||
}
|
Instance.new("Model"),
|
||||||
|
Instance.new("Part"),
|
||||||
|
}
|
||||||
|
|
||||||
local modelAsBinary = roblox.serializeModel(instances)
|
local modelAsBinary = roblox.serializeModel(instances)
|
||||||
local modelAsXml = roblox.serializeModel(instances, true)
|
local modelAsXml = roblox.serializeModel(instances, true)
|
||||||
|
|
||||||
fs.writeFile("bin/temp-model.rbxm", modelAsBinary)
|
fs.writeFile("bin/temp-model.rbxm", modelAsBinary)
|
||||||
fs.writeFile("bin/temp-model.rbxmx", modelAsXml)
|
fs.writeFile("bin/temp-model.rbxmx", modelAsXml)
|
||||||
|
|
||||||
local savedFileBinary = fs.readFile("bin/temp-model.rbxm")
|
local savedFileBinary = fs.readFile("bin/temp-model.rbxm")
|
||||||
local savedFileXml = fs.readFile("bin/temp-model.rbxmx")
|
local savedFileXml = fs.readFile("bin/temp-model.rbxmx")
|
||||||
|
|
||||||
local savedBinary = roblox.deserializeModel(savedFileBinary)
|
local savedBinary = roblox.deserializeModel(savedFileBinary)
|
||||||
local savedXml = roblox.deserializeModel(savedFileXml)
|
local savedXml = roblox.deserializeModel(savedFileXml)
|
||||||
|
|
||||||
assert(savedBinary[1].Name ~= "ROOT")
|
assert(savedBinary[1].Name ~= "ROOT")
|
||||||
assert(savedXml[1].Name ~= "ROOT")
|
assert(savedXml[1].Name ~= "ROOT")
|
||||||
|
|
||||||
assert(savedBinary[1].Name ~= "DataModel")
|
assert(savedBinary[1].Name ~= "DataModel")
|
||||||
assert(savedXml[1].Name ~= "DataModel")
|
assert(savedXml[1].Name ~= "DataModel")
|
||||||
|
|
||||||
assert(savedBinary[1].ClassName == "Model")
|
assert(savedBinary[1].ClassName == "Model")
|
||||||
assert(savedBinary[2].ClassName == "Part")
|
assert(savedBinary[2].ClassName == "Part")
|
||||||
|
|
||||||
assert(savedXml[1].ClassName == "Model")
|
assert(savedXml[1].ClassName == "Model")
|
||||||
assert(savedXml[2].ClassName == "Part")
|
assert(savedXml[2].ClassName == "Part")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Ensure Ref properties are preserved across descendants of multi-root model siblings
|
||||||
|
do
|
||||||
|
local part = Instance.new("Part")
|
||||||
|
|
||||||
|
local particleEmitter = Instance.new("ParticleEmitter")
|
||||||
|
particleEmitter.Parent = part
|
||||||
|
|
||||||
|
local folder = Instance.new("Folder")
|
||||||
|
|
||||||
|
local objectValue = Instance.new("ObjectValue") :: any
|
||||||
|
objectValue.Value = particleEmitter
|
||||||
|
objectValue.Parent = folder
|
||||||
|
|
||||||
|
local serialized = roblox.serializeModel({ part, folder })
|
||||||
|
local deserialized = roblox.deserializeModel(serialized) :: any
|
||||||
|
|
||||||
|
assert(deserialized[2].ObjectValue.Value == deserialized[1].ParticleEmitter)
|
||||||
|
end
|
||||||
|
|
|
@ -2,30 +2,55 @@ local fs = require("@lune/fs")
|
||||||
local roblox = require("@lune/roblox")
|
local roblox = require("@lune/roblox")
|
||||||
local Instance = roblox.Instance
|
local Instance = roblox.Instance
|
||||||
|
|
||||||
local game = Instance.new("DataModel")
|
-- Smoke tests
|
||||||
|
do
|
||||||
|
local game = Instance.new("DataModel")
|
||||||
|
|
||||||
local workspace = game:GetService("Workspace")
|
local workspace = game:GetService("Workspace")
|
||||||
|
|
||||||
local model = Instance.new("Model")
|
local model = Instance.new("Model")
|
||||||
local part = Instance.new("Part")
|
local part = Instance.new("Part")
|
||||||
|
|
||||||
part.Parent = model
|
part.Parent = model
|
||||||
model.Parent = workspace
|
model.Parent = workspace
|
||||||
|
|
||||||
local placeAsBinary = roblox.serializePlace(game)
|
local placeAsBinary = roblox.serializePlace(game)
|
||||||
local placeAsXml = roblox.serializePlace(game, true)
|
local placeAsXml = roblox.serializePlace(game, true)
|
||||||
|
|
||||||
fs.writeFile("bin/temp-place.rbxl", placeAsBinary)
|
fs.writeFile("bin/temp-place.rbxl", placeAsBinary)
|
||||||
fs.writeFile("bin/temp-place.rbxlx", placeAsXml)
|
fs.writeFile("bin/temp-place.rbxlx", placeAsXml)
|
||||||
|
|
||||||
local savedFileBinary = fs.readFile("bin/temp-place.rbxl")
|
local savedFileBinary = fs.readFile("bin/temp-place.rbxl")
|
||||||
local savedFileXml = fs.readFile("bin/temp-place.rbxlx")
|
local savedFileXml = fs.readFile("bin/temp-place.rbxlx")
|
||||||
|
|
||||||
local savedBinary = roblox.deserializePlace(savedFileBinary)
|
local savedBinary = roblox.deserializePlace(savedFileBinary)
|
||||||
local savedXml = roblox.deserializePlace(savedFileXml)
|
local savedXml = roblox.deserializePlace(savedFileXml)
|
||||||
|
|
||||||
assert(savedBinary.Name ~= "ROOT")
|
assert(savedBinary.Name ~= "ROOT")
|
||||||
assert(savedXml.Name ~= "ROOT")
|
assert(savedXml.Name ~= "ROOT")
|
||||||
|
|
||||||
assert(savedBinary.ClassName == "DataModel")
|
assert(savedBinary.ClassName == "DataModel")
|
||||||
assert(savedXml.ClassName == "DataModel")
|
assert(savedXml.ClassName == "DataModel")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Ensure Ref properties are preserved across services
|
||||||
|
do
|
||||||
|
local game = Instance.new("DataModel")
|
||||||
|
local ReplicatedStorage = Instance.new("ReplicatedStorage")
|
||||||
|
local Workspace = Instance.new("Workspace")
|
||||||
|
|
||||||
|
Workspace.Parent = game
|
||||||
|
ReplicatedStorage.Parent = game
|
||||||
|
|
||||||
|
local part = Instance.new("Part")
|
||||||
|
part.Parent = ReplicatedStorage
|
||||||
|
|
||||||
|
local objectValue = Instance.new("ObjectValue") :: any
|
||||||
|
objectValue.Value = part
|
||||||
|
objectValue.Parent = Workspace
|
||||||
|
|
||||||
|
local serialized = roblox.serializePlace(game)
|
||||||
|
local deserialized = roblox.deserializePlace(serialized) :: any
|
||||||
|
|
||||||
|
assert(deserialized.Workspace.ObjectValue.Value == deserialized.ReplicatedStorage.Part)
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in a new issue