/// <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); }
/// <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); }
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); }
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); }
/// <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); }