private void PartRemovedInBaseAsset(object sender, AssetPartChangeEventArgs e) { UpdatingPropertyFromBase = true; foreach (var part in Asset.Hierarchy.Parts.Values.Where(x => x.Base?.BasePartId == e.PartId).ToList()) { RemovePartFromAsset(part); } UpdatingPropertyFromBase = false; }
private void PartAddedInBaseAsset(object sender, [NotNull] AssetPartChangeEventArgs e) { UpdatingPropertyFromBase = true; var baseAsset = (AssetCompositeHierarchy <TAssetPartDesign, TAssetPart>)e.Asset; var newPart = baseAsset.Hierarchy.Parts[e.PartId]; var newPartParent = baseAsset.GetParent(newPart.Part); var baseAssetGraph = Container.TryGetGraph(baseAsset.Id) as AssetCompositeHierarchyPropertyGraph <TAssetPartDesign, TAssetPart>; if (baseAssetGraph == null) { throw new InvalidOperationException("Unable to find the graph corresponding to the base part"); } foreach (var instanceId in basePartAssets[baseAssetGraph]) { // Discard the part if this asset don't want it if (!ShouldAddNewPartFromBase(baseAssetGraph, newPart, newPartParent, instanceId)) { continue; } var insertIndex = FindBestInsertIndex(baseAsset, newPart, newPartParent, instanceId, out TAssetPartDesign instanceParent); if (insertIndex < 0) { continue; } // Now we know where to insert, let's clone the new part. var flags = SubHierarchyCloneFlags.GenerateNewIdsForIdentifiableObjects | SubHierarchyCloneFlags.RemoveOverrides; var baseHierarchy = CloneSubHierarchies(baseAssetGraph.Container.NodeContainer, baseAssetGraph.Asset, newPart.Part.Id.Yield(), flags, out Dictionary <Guid, Guid> mapping); foreach (var ids in mapping) { // Process only ids that correspond to parts if (!baseHierarchy.Parts.TryGetValue(ids.Value, out TAssetPartDesign clone)) { continue; } clone.Base = new BasePart(new AssetReference(e.AssetItem.Id, e.AssetItem.Location), ids.Key, instanceId); // This add could actually be a move (remove + add). So we compare to the existing baseInstanceMapping and reuse the existing part if necessary var mappingKey = Tuple.Create(ids.Key, instanceId); if (!deletedPartsInstanceMapping.Contains(mappingKey) && baseInstanceMapping.TryGetValue(mappingKey, out TAssetPartDesign existingPart)) { ReuseExistingPart(baseHierarchy, clone, existingPart); } } // We might have changed some ids, let's refresh the collection baseHierarchy.Parts.RefreshKeys(); // Then actually add the new part var rootClone = baseHierarchy.Parts[baseHierarchy.RootParts.Single().Id]; AddPartToAsset(baseHierarchy.Parts, rootClone, instanceParent?.Part, insertIndex); } // Reconcile with base RefreshBase(); ReconcileWithBase(); UpdatingPropertyFromBase = false; }