Ejemplo n.º 1
0
        /// <summary>
        /// Clones a sub-hierarchy of this asset.
        /// </summary>
        /// <param name="sourceRootId">The id of the root of the sub-hierarchy to clone</param>
        /// <param name="cleanReference">If true, any reference to a part external to the cloned hierarchy will be set to null.</param>
        /// <param name="idRemapping">A dictionary containing the mapping of ids from the source parts to the new parts.</param>
        /// <returns>A <see cref="AssetCompositeHierarchyData{UIElementDesign, UIElement}"/> corresponding to the cloned parts.</returns>
        public override AssetCompositeHierarchyData <UIElementDesign, UIElement> CloneSubHierarchy(Guid sourceRootId, bool cleanReference, out Dictionary <Guid, Guid> idRemapping)
        {
            if (!Hierarchy.Parts.ContainsKey(sourceRootId))
            {
                throw new ArgumentException(@"The source root part must be an part of this asset.", nameof(sourceRootId));
            }

            // Note: Instead of copying the whole asset (with its potentially big hierarchy),
            // we first copy the asset only (without the hierarchy), then the sub-hierarchy to extract.
            var subTreeRoot      = Hierarchy.Parts[sourceRootId];
            var subTreeHierarchy = new AssetCompositeHierarchyData <UIElementDesign, UIElement> {
                Parts = { subTreeRoot }, RootPartIds = { sourceRootId }
            };

            foreach (var subTreeDesign in EnumerateChildParts(subTreeRoot, Hierarchy, true))
            {
                subTreeHierarchy.Parts.Add(Hierarchy.Parts[subTreeDesign.UIElement.Id]);
            }

            // clone the parts of the sub-tree
            var clonedHierarchy = (AssetCompositeHierarchyData <UIElementDesign, UIElement>)AssetCloner.Clone(subTreeHierarchy);
            //clonedHierarchy.Parts[sourceRootEntity].UIElement.Parent = null;

            //if (cleanReference)
            //{
            //    // set to null reference outside of the sub-tree
            //    var tempAsset = new PrefabAsset { Hierarchy = clonedHierarchy };
            //    tempAsset.FixupPartReferences();
            //}

            // temporary nullify the hierarchy to avoid to clone it
            var sourceHierarchy = Hierarchy;

            Hierarchy = null;

            // revert the source hierarchy
            Hierarchy = sourceHierarchy;

            // Generate part mapping
            idRemapping = new Dictionary <Guid, Guid>();
            foreach (var partDesign in clonedHierarchy.Parts)
            {
                // Generate new Id
                var newPartId = Guid.NewGuid();

                // Update mappings
                idRemapping.Add(partDesign.UIElement.Id, newPartId);

                // Update part with new id
                partDesign.UIElement.Id = newPartId;
            }

            // Rewrite part references
            // Should we nullify invalid references?
            AssetPartsAnalysis.RemapPartsId(clonedHierarchy, idRemapping);

            return(clonedHierarchy);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Clones a sub-hierarchy of this asset.
        /// </summary>
        /// <param name="sourceRootIds">The ids that are the roots of the sub-hierarchies to clone.</param>
        /// <param name="cleanReference">If true, any reference to a part external to the cloned hierarchy will be set to null.</param>
        /// <param name="idRemapping">A dictionary containing the mapping of ids from the source parts to the new parts.</param>
        /// <returns>A <see cref="AssetCompositeHierarchyData{TAssetPartDesign, TAssetPart}"/> corresponding to the cloned parts.</returns>
        /// <remarks>The parts passed to this methods must be independent in the hierarchy.</remarks>
        public AssetCompositeHierarchyData <TAssetPartDesign, TAssetPart> CloneSubHierarchies(IEnumerable <Guid> sourceRootIds, bool cleanReference, out Dictionary <Guid, Guid> idRemapping)
        {
            // Note: Instead of copying the whole asset (with its potentially big hierarchy),
            // we first copy the asset only (without the hierarchy), then the sub-hierarchy to extract.
            var subTreeHierarchy = new AssetCompositeHierarchyData <TAssetPartDesign, TAssetPart>();

            foreach (var rootId in sourceRootIds)
            {
                if (!Hierarchy.Parts.ContainsKey(rootId))
                {
                    throw new ArgumentException(@"The source root parts must be parts of this asset.", nameof(sourceRootIds));
                }

                subTreeHierarchy.RootPartIds.Add(rootId);

                subTreeHierarchy.Parts.Add(Hierarchy.Parts[rootId]);
                foreach (var subTreePart in EnumerateChildParts(Hierarchy.Parts[rootId].Part, true))
                {
                    subTreeHierarchy.Parts.Add(Hierarchy.Parts[subTreePart.Id]);
                }
            }
            // clone the parts of the sub-tree
            var clonedHierarchy = AssetCloner.Clone(subTreeHierarchy);

            foreach (var rootEntity in clonedHierarchy.RootPartIds)
            {
                PostClonePart(clonedHierarchy.Parts[rootEntity].Part);
            }
            if (cleanReference)
            {
                ClearPartReferences(clonedHierarchy);
            }
            // Generate part mapping
            idRemapping = new Dictionary <Guid, Guid>();
            foreach (var partDesign in clonedHierarchy.Parts)
            {
                // Generate new Id
                var newId = Guid.NewGuid();
                // Update mappings
                idRemapping.Add(partDesign.Part.Id, newId);
                // Update part with new id
                partDesign.Part.Id = newId;
            }
            // Rewrite part references
            // Should we nullify invalid references?
            AssetPartsAnalysis.RemapPartsId(clonedHierarchy, idRemapping);
            return(clonedHierarchy);
        }
        public override Asset CreateDerivedAsset(string baseLocation, out Dictionary <Guid, Guid> idRemapping)
        {
            var newAsset = (AssetCompositeHierarchy <TAssetPartDesign, TAssetPart>)base.CreateDerivedAsset(baseLocation, out idRemapping);

            var instanceId = Guid.NewGuid();

            foreach (var part in Hierarchy.Parts)
            {
                var newPart = newAsset.Hierarchy.Parts[idRemapping[part.Part.Id]];
                newPart.Base = new BasePart(new AssetReference(Id, baseLocation), part.Part.Id, instanceId);
            }

            AssetPartsAnalysis.RemapPartsId(newAsset.Hierarchy, idRemapping);

            return(newAsset);
        }
Ejemplo n.º 4
0
        public override Asset CreateDerivedAsset(string baseLocation, IDictionary <Guid, Guid> idRemapping = null)
        {
            var newAsset = (AssetCompositeHierarchy <TAssetPartDesign, TAssetPart>)base.CreateDerivedAsset(baseLocation, idRemapping);

            var remappingDictionary = idRemapping ?? new Dictionary <Guid, Guid>();

            var instanceId = Guid.NewGuid();

            foreach (var part in newAsset.Hierarchy.Parts)
            {
                part.Base = new BasePart(new AssetReference(Id, baseLocation), part.Part.Id, instanceId);
                // Create and register a new id for this part
                var newId = Guid.NewGuid();
                remappingDictionary.Add(part.Part.Id, newId);
                // Apply the new Guid
                part.Part.Id = newId;
            }

            AssetPartsAnalysis.RemapPartsId(newAsset.Hierarchy, remappingDictionary);

            return(newAsset);
        }
Ejemplo n.º 5
0
        public override Asset CreateChildAsset(string baseLocation, IDictionary<Guid, Guid> idRemapping = null)
        {
            var newAsset = (AssetCompositeHierarchy<TAssetPartDesign, TAssetPart>)base.CreateChildAsset(baseLocation);

            var remappingDictionary = idRemapping ?? new Dictionary<Guid, Guid>();

            foreach (var part in newAsset.Hierarchy.Parts)
            {
                // Store the baseid of the new version
                part.BaseId = part.Part.Id;
                // Make sure that we don't replicate the base part InstanceId
                part.BasePartInstanceId = null;
                // Create and register a new id for this part
                var newId = Guid.NewGuid();
                remappingDictionary.Add(part.Part.Id, newId);
                // Apply the new Guid
                part.Part.Id = newId;
            }

            AssetPartsAnalysis.RemapPartsId(newAsset.Hierarchy, remappingDictionary);

            return newAsset;
        }
        /// <summary>
        /// Clones a sub-hierarchy of this asset.
        /// </summary>
        /// <param name="sourceRootIds">The ids that are the roots of the sub-hierarchies to clone.</param>
        /// <param name="cleanReference">If true, any reference to a part external to the cloned hierarchy will be set to null.</param>
        /// <param name="generateNewIdsForIdentifiableObjects">If true, the cloned objects that implement <see cref="IIdentifiable"/> will have new ids.</param>
        /// <param name="idRemapping">A dictionary containing the remapping of <see cref="IIdentifiable.Id"/> if <see cref="AssetClonerFlags.GenerateNewIdsForIdentifiableObjects"/> has been passed to the cloner.</param>
        /// <returns>A <see cref="AssetCompositeHierarchyData{TAssetPartDesign, TAssetPart}"/> corresponding to the cloned parts.</returns>
        /// <remarks>The parts passed to this methods must be independent in the hierarchy.</remarks>
        public AssetCompositeHierarchyData <TAssetPartDesign, TAssetPart> CloneSubHierarchies(IEnumerable <Guid> sourceRootIds, bool cleanReference, bool generateNewIdsForIdentifiableObjects, bool generateNewBaseInstanceIds, out Dictionary <Guid, Guid> idRemapping)
        {
            // Note: Instead of copying the whole asset (with its potentially big hierarchy),
            // we first copy the asset only (without the hierarchy), then the sub-hierarchy to extract.
            var subTreeHierarchy = new AssetCompositeHierarchyData <TAssetPartDesign, TAssetPart>();

            foreach (var rootId in sourceRootIds)
            {
                if (!Hierarchy.Parts.ContainsKey(rootId))
                {
                    throw new ArgumentException(@"The source root parts must be parts of this asset.", nameof(sourceRootIds));
                }

                subTreeHierarchy.RootPartIds.Add(rootId);

                subTreeHierarchy.Parts.Add(Hierarchy.Parts[rootId]);
                foreach (var subTreePart in EnumerateChildParts(Hierarchy.Parts[rootId].Part, true))
                {
                    subTreeHierarchy.Parts.Add(Hierarchy.Parts[subTreePart.Id]);
                }
            }
            // clone the parts of the sub-tree
            var clonedHierarchy = AssetCloner.Clone(subTreeHierarchy, generateNewIdsForIdentifiableObjects ? AssetClonerFlags.GenerateNewIdsForIdentifiableObjects : AssetClonerFlags.None, out idRemapping);

            // Remap ids from the root id collection to the new ids generated during cloning
            AssetPartsAnalysis.RemapPartsId(clonedHierarchy, idRemapping);

            foreach (var rootEntity in clonedHierarchy.RootPartIds)
            {
                PostClonePart(clonedHierarchy.Parts[rootEntity].Part);
            }
            if (cleanReference)
            {
                // set to null reference outside of the sub-tree
                var tempAsset = (AssetCompositeHierarchy <TAssetPartDesign, TAssetPart>)Activator.CreateInstance(GetType());
                tempAsset.Hierarchy = clonedHierarchy;
                tempAsset.FixupPartReferences();
            }
            else
            {
                // restore initial ids for reference outside of the subtree, so they can be fixed up later.
                var tempAsset = (AssetCompositeHierarchy <TAssetPartDesign, TAssetPart>)Activator.CreateInstance(GetType());
                tempAsset.Hierarchy = clonedHierarchy;
                var visitor = new AssetCompositePartReferenceCollector();
                visitor.VisitAsset(tempAsset);
                var references        = visitor.Result;
                var revertedIdMapping = idRemapping.ToDictionary(x => x.Value, x => x.Key);
                foreach (var referencedPart in references.Select(x => x.AssetPart).OfType <IIdentifiable>())
                {
                    var realPart = tempAsset.ResolvePartReference(referencedPart);
                    if (realPart == null)
                    {
                        referencedPart.Id = revertedIdMapping[referencedPart.Id];
                    }
                }
            }

            if (generateNewBaseInstanceIds)
            {
                AssetPartsAnalysis.GenerateNewBaseInstanceIds(clonedHierarchy);
            }

            return(clonedHierarchy);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Clones a sub-hierarchy of this asset.
        /// </summary>
        /// <param name="sourceRootEntities">The entities that are the roots of the sub-hierarchies to clone</param>
        /// <param name="cleanReference">If true, any reference to an entity external to the cloned hierarchy will be set to null.</param>
        /// <param name="entityMapping">A dictionary containing the mapping of ids from the source entites to the new entities.</param>
        /// <returns>A <see cref="AssetCompositeHierarchyData{EntityDesign, Entity}"/> corresponding to the cloned entities.</returns>
        /// <remarks>The entities passed to this methods must be independent in the hierarchy.</remarks>
        public AssetCompositeHierarchyData <EntityDesign, Entity> CloneSubHierarchies(IEnumerable <Guid> sourceRootEntities, bool cleanReference, out Dictionary <Guid, Guid> entityMapping)
        {
            // Note: Instead of copying the whole asset (with its potentially big hierarchy),
            // we first copy the asset only (without the hierarchy), then the sub-hierarchy to extract.
            var subTreeHierarchy = new AssetCompositeHierarchyData <EntityDesign, Entity>();

            foreach (var sourceRootEntity in sourceRootEntities)
            {
                if (!Hierarchy.Parts.ContainsKey(sourceRootEntity))
                {
                    throw new ArgumentException(@"The source root entities must be entities of this asset.", nameof(sourceRootEntities));
                }

                var subTreeRoot = Hierarchy.Parts[sourceRootEntity].Entity;
                subTreeHierarchy.Parts.Add(new EntityDesign(subTreeRoot));
                subTreeHierarchy.RootPartIds.Add(sourceRootEntity);
                foreach (var subTreeEntity in EnumerateChildParts(subTreeRoot, true))
                {
                    subTreeHierarchy.Parts.Add(Hierarchy.Parts[subTreeEntity.Id]);
                }
            }

            // clone the entities of the sub-tree
            var clonedHierarchy = (AssetCompositeHierarchyData <EntityDesign, Entity>)AssetCloner.Clone(subTreeHierarchy);

            foreach (var rootEntity in clonedHierarchy.RootPartIds)
            {
                clonedHierarchy.Parts[rootEntity].Entity.Transform.Parent = null;
            }

            if (cleanReference)
            {
                // set to null reference outside of the sub-tree
                var tempAsset = new PrefabAsset {
                    Hierarchy = clonedHierarchy
                };
                tempAsset.FixupPartReferences();
            }

            // temporary nullify the hierarchy to avoid to clone it
            var sourceHierarchy = Hierarchy;

            Hierarchy = null;

            // revert the source hierarchy
            Hierarchy = sourceHierarchy;

            // Generate entity mapping
            entityMapping = new Dictionary <Guid, Guid>();
            foreach (var entityDesign in clonedHierarchy.Parts)
            {
                // Generate new Id
                var newEntityId = Guid.NewGuid();

                // Update mappings
                entityMapping.Add(entityDesign.Entity.Id, newEntityId);

                // Update entity with new id
                entityDesign.Entity.Id = newEntityId;
            }

            // Rewrite entity references
            // Should we nullify invalid references?
            AssetPartsAnalysis.RemapPartsId(clonedHierarchy, entityMapping);

            return(clonedHierarchy);
        }