コード例 #1
0
        public void TestCloneSubHierarchyInstanceWithRemoveOverrides()
        {
            var baseAsset     = AssetHierarchyHelper.BuildAssetContainer(1, 2, 1, null, x => x.Parts[x.RootParts.Single().Id].Part.Name = "BaseName");
            var container     = baseAsset.Container.NodeContainer;
            var derivedAsset  = AssetHierarchyHelper.BuildAssetContainer(1, 2, 1, baseAsset.Container);
            var instances     = baseAsset.Asset.CreatePartInstances();
            var derivedRootId = instances.RootParts.Single().Id;

            derivedAsset.Graph.AddPartToAsset(instances.Parts, instances.Parts[derivedRootId], derivedAsset.Asset.Hierarchy.RootParts.Single(), 1);
            derivedAsset.Graph.RefreshBase();
            var partToChange = (AssetObjectNode)container.GetNode(instances.Parts.Single(x => x.Value.Part.Name == "BaseName").Value.Part);

            partToChange[nameof(Types.MyPart.Name)].Update("Overridden");
            Debug.Write(AssetHierarchyHelper.PrintHierarchy(derivedAsset.Asset));
            var originalRoot = derivedAsset.Asset.Hierarchy.RootParts.Single();
            Dictionary <Guid, Guid> remapping;
            var clone = AssetCompositeHierarchyPropertyGraph <Types.MyPartDesign, Types.MyPart> .CloneSubHierarchies(container, derivedAsset.Asset, originalRoot.Id.Yield(), SubHierarchyCloneFlags.RemoveOverrides, out remapping);

            var cloneAsset = AssetHierarchyHelper.BuildAssetContainer(0, 0, 0, baseAsset.Container);
            var cloneRoot  = clone.Parts[clone.RootParts.Single().Id];

            cloneAsset.Graph.AddPartToAsset(clone.Parts, cloneRoot, null, 0);
            cloneAsset.Graph.RefreshBase();
            Assert.Empty(remapping);
            Assert.Equal(4, clone.Parts.Count);
            Assert.Single(clone.RootParts);
            foreach (var rootPart in clone.RootParts)
            {
                Assert.Contains(rootPart, clone.Parts.Values.Select(x => x.Part));
            }
            foreach (var part in clone.Parts.Values)
            {
                var matchingPart = derivedAsset.Asset.Hierarchy.Parts[part.Part.Id];
                Assert.NotEqual(matchingPart, part);
                Assert.NotEqual(matchingPart.Part, part.Part);
                Assert.Equal(matchingPart.Part.Id, part.Part.Id);
                Assert.Equal(matchingPart.Part.Name, part.Part.Name);
            }
            Assert.Equal(originalRoot.Id, cloneRoot.Part.Id);
            Assert.NotEqual(originalRoot.Children[0], cloneRoot.Part.Children[0]);
            Assert.NotEqual(originalRoot.Children[1], cloneRoot.Part.Children[1]);
            Assert.Equal(originalRoot.Children[0].Id, cloneRoot.Part.Children[0].Id);
            Assert.Equal(originalRoot.Children[1].Id, cloneRoot.Part.Children[1].Id);
            Assert.NotEqual(originalRoot.Children[0].Parent, cloneRoot.Part.Children[0].Parent);
            Assert.NotEqual(originalRoot.Children[1].Parent, cloneRoot.Part.Children[1].Parent);
            Assert.Equal(cloneRoot.Part, cloneRoot.Part.Children[0].Parent);
            Assert.Equal(cloneRoot.Part, cloneRoot.Part.Children[1].Parent);
            var clonedChangedPart = (AssetObjectNode)container.GetNode(clone.Parts.Single(x => x.Value.Part.Id == (Guid)partToChange[nameof(IIdentifiable.Id)].Retrieve()).Value.Part);

            // Note: currently, using RemoveOverrides does not clear the base (it just clears the overrides), so we should expect to still have the base linked.
            // This behavior could be changed in the future
            Assert.False(clonedChangedPart[nameof(Types.MyPart.Name)].IsContentOverridden());
            Assert.True(clonedChangedPart[nameof(Types.MyPart.Name)].IsContentInherited());
            Assert.Equal("Overridden", clonedChangedPart[nameof(Types.MyPart.Name)].Retrieve());
            Assert.Equal(partToChange[nameof(Types.MyPart.Name)].BaseNode, clonedChangedPart[nameof(Types.MyPart.Name)].BaseNode);
        }
コード例 #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DeletedPartsTrackingOperation{TAssetPartDesign,TAssetPart}"/> class.
 /// </summary>
 /// <param name="viewmodel"></param>
 /// <param name="deletedPartsMapping">A mapping of the base information (base part id, instance id) of the deleted parts that have a base.</param>
 public DeletedPartsTrackingOperation([NotNull] AssetCompositeHierarchyViewModel <TAssetPartDesign, TAssetPart> viewmodel, [NotNull] HashSet <Tuple <Guid, Guid> > deletedPartsMapping)
     : base(viewmodel.SafeArgument(nameof(viewmodel)).Dirtiables)
 {
     if (deletedPartsMapping == null)
     {
         throw new ArgumentNullException(nameof(deletedPartsMapping));
     }
     this.deletedPartsMapping = deletedPartsMapping;
     propertyGraph            = viewmodel.AssetHierarchyPropertyGraph;
 }
コード例 #3
0
        /// <inheritdoc/>
        protected override bool ShouldAddNewPartFromBase(AssetCompositeHierarchyPropertyGraph <UIElementDesign, UIElement> baseAssetGraph, UIElementDesign newPart, UIElement newPartParent, Guid instanceId)
        {
            if (!base.ShouldAddNewPartFromBase(baseAssetGraph, newPart, newPartParent, instanceId))
            {
                return(false);
            }

            // Don't add other root element.
            // Remark: child elements of root elements that have been already discarded will also be automatically discarded
            return(newPartParent != null);
        }
コード例 #4
0
        public void TestCloneSubHierarchyWithGenerateNewIdsForIdentifiableObjects()
        {
            var graph = AssetHierarchyHelper.BuildAssetAndGraph(2, 2, 2);

            Debug.Write(AssetHierarchyHelper.PrintHierarchy(graph.Asset));
            var originalRoot = graph.Asset.Hierarchy.Parts[graph.Asset.Hierarchy.RootParts[1].Id];
            Dictionary <Guid, Guid> remapping;
            var clone = AssetCompositeHierarchyPropertyGraph <Types.MyPartDesign, Types.MyPart> .CloneSubHierarchies(graph.Container.NodeContainer, graph.Asset, originalRoot.Part.Id.Yield(), SubHierarchyCloneFlags.GenerateNewIdsForIdentifiableObjects, out remapping);

            var cloneRoot = clone.Parts[clone.RootParts.Single().Id];

            Assert.NotNull(remapping);
            Assert.Equal(3, clone.Parts.Count);
            Assert.Single(clone.RootParts);
            foreach (var rootPart in clone.RootParts)
            {
                Assert.Contains(rootPart, clone.Parts.Values.Select(x => x.Part));
            }
            foreach (var part in clone.Parts.Values)
            {
                Assert.Contains(part.Part.Id, remapping.Values);
                var matchingId = remapping.Single(x => x.Value == part.Part.Id).Key;
                Assert.NotEqual(part.Part.Id, matchingId);
                var matchingPart = graph.Asset.Hierarchy.Parts[matchingId];
                Assert.NotEqual(matchingPart, part);
                Assert.NotEqual(matchingPart.Part, part.Part);
                Assert.NotEqual(matchingPart.Part.Id, part.Part.Id);
                Assert.Equal(matchingPart.Part.Name, part.Part.Name);
            }
            Assert.NotEqual(originalRoot.Part.Id, cloneRoot.Part.Id);
            Assert.Contains(originalRoot.Part.Id, remapping.Keys);
            Assert.Equal(remapping[originalRoot.Part.Id], cloneRoot.Part.Id);
            Assert.NotEqual(originalRoot.Part.Children[0], cloneRoot.Part.Children[0]);
            Assert.NotEqual(originalRoot.Part.Children[1], cloneRoot.Part.Children[1]);
            Assert.NotEqual(originalRoot.Part.Children[0].Id, cloneRoot.Part.Children[0].Id);
            Assert.Contains(originalRoot.Part.Children[0].Id, remapping.Keys);
            Assert.Equal(remapping[originalRoot.Part.Children[0].Id], cloneRoot.Part.Children[0].Id);
            Assert.NotEqual(originalRoot.Part.Children[1].Id, cloneRoot.Part.Children[1].Id);
            Assert.Contains(originalRoot.Part.Children[1].Id, remapping.Keys);
            Assert.Equal(remapping[originalRoot.Part.Children[1].Id], cloneRoot.Part.Children[1].Id);
            Assert.NotEqual(originalRoot.Part.Children[0].Parent, cloneRoot.Part.Children[0].Parent);
            Assert.NotEqual(originalRoot.Part.Children[1].Parent, cloneRoot.Part.Children[1].Parent);
            Assert.Equal(cloneRoot.Part, cloneRoot.Part.Children[0].Parent);
            Assert.Equal(cloneRoot.Part, cloneRoot.Part.Children[1].Parent);
        }
コード例 #5
0
        public void TestCloneSubHierarchyWithExternalReferencesWithCleanExternalReferences()
        {
            var graph = AssetHierarchyHelper.BuildAssetAndGraph(2, 2, 2, x => x.Parts[GuidGenerator.Get(5)].Part.MyReferences = new List <Types.MyPart> {
                x.Parts[GuidGenerator.Get(2)].Part
            });

            Debug.Write(AssetHierarchyHelper.PrintHierarchy(graph.Asset));
            var originalRoot = graph.Asset.Hierarchy.Parts[graph.Asset.Hierarchy.RootParts[1].Id];
            Dictionary <Guid, Guid> remapping;
            var clone = AssetCompositeHierarchyPropertyGraph <Types.MyPartDesign, Types.MyPart> .CloneSubHierarchies(graph.Container.NodeContainer, graph.Asset, originalRoot.Part.Id.Yield(), SubHierarchyCloneFlags.CleanExternalReferences, out remapping);

            var cloneRoot = clone.Parts[clone.RootParts.Single().Id];

            Assert.Empty(remapping);
            Assert.Equal(3, clone.Parts.Count);
            Assert.Single(clone.RootParts);
            foreach (var rootPart in clone.RootParts)
            {
                Assert.Contains(rootPart, clone.Parts.Values.Select(x => x.Part));
            }
            foreach (var part in clone.Parts.Values)
            {
                var matchingPart = graph.Asset.Hierarchy.Parts[part.Part.Id];
                Assert.NotEqual(matchingPart, part);
                Assert.NotEqual(matchingPart.Part, part.Part);
                Assert.Equal(matchingPart.Part.Id, part.Part.Id);
                Assert.Equal(matchingPart.Part.Name, part.Part.Name);
            }
            Assert.Equal(originalRoot.Part.Id, cloneRoot.Part.Id);
            Assert.NotEqual(originalRoot.Part.Children[0], cloneRoot.Part.Children[0]);
            Assert.NotEqual(originalRoot.Part.Children[1], cloneRoot.Part.Children[1]);
            Assert.Equal(originalRoot.Part.Children[0].Id, cloneRoot.Part.Children[0].Id);
            Assert.Equal(originalRoot.Part.Children[1].Id, cloneRoot.Part.Children[1].Id);
            Assert.NotEqual(originalRoot.Part.Children[0].Parent, cloneRoot.Part.Children[0].Parent);
            Assert.NotEqual(originalRoot.Part.Children[1].Parent, cloneRoot.Part.Children[1].Parent);
            Assert.Equal(cloneRoot.Part, cloneRoot.Part.Children[0].Parent);
            Assert.Equal(cloneRoot.Part, cloneRoot.Part.Children[1].Parent);
            Assert.Null(cloneRoot.Part.Children[0].MyReferences[0]);
        }
コード例 #6
0
        protected IEnumerable <TAssetPart> ClonePartsForGameSide([NotNull] AssetCompositeHierarchy <TAssetPartDesign, TAssetPart> asset, [NotNull] IEnumerable <TAssetPart> parts)
        {
            var flags           = SubHierarchyCloneFlags.RemoveOverrides;
            var sourceContainer = Asset.PropertyGraph.Container.NodeContainer;
            var targetContainer = GameSideNodeContainer;
            var clone           = AssetCompositeHierarchyPropertyGraph <TAssetPartDesign, TAssetPart> .CloneSubHierarchies(sourceContainer, targetContainer, asset, parts.Select(p => p.Id), flags, out _);

            // Collect external references after cloning, we need to fix them up!
            var rootNode             = GameSideNodeContainer.GetOrCreateNode(clone);
            var definition           = AssetQuantumRegistry.GetDefinition(asset.GetType());
            var unresolvedReferences = ExternalReferenceCollector.GetExternalReferenceAccessors(definition, rootNode);

            // Retrieve all available game-side identifiable objects, so we can try to resolve external references with items from this collection.
            var identifiableObjects = CollectIdentifiableObjects();

            foreach (var reference in unresolvedReferences)
            {
                if (identifiableObjects.TryGetValue(reference.Key.Id, out var realObject))
                {
                    // Target object found, let's update the reference with the real game-side object.
                    foreach (var accessor in reference.Value)
                    {
                        accessor.UpdateValue(realObject);
                    }
                }
                else
                {
                    // Target object not found, let's clear the reference since the currently set object could be asset-side, or a temporary proxy, etc.
                    foreach (var accessor in reference.Value)
                    {
                        accessor.UpdateValue(null);
                    }
                }
            }
            return(clone.RootParts);
        }
コード例 #7
0
        public void TestSimpleCloneSubHierarchy()
        {
            var graph = AssetHierarchyHelper.BuildAssetAndGraph(2, 2, 2);

            Debug.Write(AssetHierarchyHelper.PrintHierarchy(graph.Asset));
            var originalRoot = graph.Asset.Hierarchy.Parts[graph.Asset.Hierarchy.RootParts[1].Id];
            Dictionary <Guid, Guid> remapping;
            var clone = AssetCompositeHierarchyPropertyGraph <Types.MyPartDesign, Types.MyPart> .CloneSubHierarchies(graph.Container.NodeContainer, graph.Asset, originalRoot.Part.Id.Yield(), SubHierarchyCloneFlags.None, out remapping);

            var cloneRoot = clone.Parts[clone.RootParts.Single().Id];

            Assert.Empty(remapping);
            Assert.Equal(3, clone.Parts.Count);
            Assert.Equal(1, clone.RootParts.Count);
            foreach (var rootPart in clone.RootParts)
            {
                Assert.True(clone.Parts.Values.Select(x => x.Part).Contains(rootPart));
            }
            foreach (var part in clone.Parts.Values)
            {
                var matchingPart = graph.Asset.Hierarchy.Parts[part.Part.Id];
                Assert.NotEqual(matchingPart, part);
                Assert.NotEqual(matchingPart.Part, part.Part);
                Assert.Equal(matchingPart.Part.Id, part.Part.Id);
                Assert.Equal(matchingPart.Part.Name, part.Part.Name);
            }
            Assert.Equal(originalRoot.Part.Id, cloneRoot.Part.Id);
            Assert.NotEqual(originalRoot.Part.Children[0], cloneRoot.Part.Children[0]);
            Assert.NotEqual(originalRoot.Part.Children[1], cloneRoot.Part.Children[1]);
            Assert.Equal(originalRoot.Part.Children[0].Id, cloneRoot.Part.Children[0].Id);
            Assert.Equal(originalRoot.Part.Children[1].Id, cloneRoot.Part.Children[1].Id);
            Assert.NotEqual(originalRoot.Part.Children[0].Parent, cloneRoot.Part.Children[0].Parent);
            Assert.NotEqual(originalRoot.Part.Children[1].Parent, cloneRoot.Part.Children[1].Parent);
            Assert.Equal(cloneRoot.Part, cloneRoot.Part.Children[0].Parent);
            Assert.Equal(cloneRoot.Part, cloneRoot.Part.Children[1].Parent);
        }
コード例 #8
0
 /// <inheritdoc />
 protected override void FreezeContent()
 {
     propertyGraph = null;
 }