/// <inheritdoc /> public override bool ProcessDeserializedData(AssetPropertyGraphContainer graphContainer, object targetRootObject, Type targetMemberType, ref object data, bool isRootDataObjectReference, AssetId?sourceId, YamlAssetMetadata <OverrideType> overrides, YamlAssetPath basePath) { var asset = (AssetCompositeHierarchy <TAssetPartDesign, TAssetPart>)targetRootObject; var hierarchy = data as AssetCompositeHierarchyData <TAssetPartDesign, TAssetPart>; if (hierarchy == null) { return(false); } // Create a temporary asset to host the hierarchy to paste, so we have a property graph to manipulate it. var tempAsset = (AssetCompositeHierarchy <TAssetPartDesign, TAssetPart>)Activator.CreateInstance(asset.GetType()); tempAsset.Hierarchy = hierarchy; // Use temporary containers so that any created nodes are discarded after the processing. var tempNodeContainer = new AssetNodeContainer { NodeBuilder = { NodeFactory = new AssetNodeFactory() } }; var definition = AssetQuantumRegistry.GetDefinition(asset.GetType()); var rootNode = tempNodeContainer.GetOrCreateNode(tempAsset); // If different asset or if at least one part already exists, create a custom clone. if (asset.Id != sourceId || hierarchy.Parts.Values.Any(part => asset.ContainsPart(part.Part.Id))) { // Clone again to create new ids for any IIdentifiable, but keep references to external object intact. var cloneExternalReferences = ExternalReferenceCollector.GetExternalReferences(definition, rootNode); hierarchy = AssetCloner.Clone(hierarchy, AssetClonerFlags.GenerateNewIdsForIdentifiableObjects, cloneExternalReferences, out var idRemapping); // Remap indices of parts in Hierarchy.Part AssetCloningHelper.RemapIdentifiablePaths(overrides, idRemapping, basePath); // Make new base instances ids in case the part are inherited. AssetPartsAnalysis.GenerateNewBaseInstanceIds(hierarchy); // Update the temporary asset with this cloned hierarchy. rootNode[nameof(AssetCompositeHierarchy <TAssetPartDesign, TAssetPart> .Hierarchy)].Update(hierarchy); } // Collect all referenceable objects from the target asset (where we're pasting) var targetPropertyGraph = graphContainer.TryGetGraph(asset.Id); var referenceableObjects = IdentifiableObjectCollector.Collect(targetPropertyGraph.Definition, targetPropertyGraph.RootNode); // Replace references in the hierarchy being pasted by the real objects from the target asset. var externalReferences = new HashSet <Guid>(ExternalReferenceCollector.GetExternalReferences(definition, rootNode).Select(x => x.Id)); var visitor = new ObjectReferencePathGenerator(definition) { ShouldOutputReference = x => externalReferences.Contains(x) }; visitor.Visit(rootNode); FixupObjectReferences.FixupReferences(tempAsset, visitor.Result, referenceableObjects, true); data = hierarchy; return(true); }
public SettingsCategoryViewModel(IViewModelServiceProvider serviceProvider, SettingsProfile profile, string name, SettingsCategoryViewModel parent, AssetNodeContainer nodeContainer) : base(serviceProvider) { this.nodeContainer = nodeContainer; Name = name; Parent = parent; SubCategories = new SortedObservableCollection <SettingsCategoryViewModel>(); // Get all settings key and sort them by display name var settingsKeys = profile.Container.GetAllSettingsKeys(); var settingsPath = Path; if (!settingsPath.EndsWith("/")) { settingsPath += "/"; } int pathLength = settingsPath.Length; settingsKeys.Sort(new AnonymousComparer <SettingsKey>((x, y) => x.DisplayName.CompareTo(y.DisplayName))); // We keep settings that starts by settingsPath and does not contains subsequent slashes foreach (SettingsKey key in settingsKeys) { var displayName = key.DisplayName.ToString(); if (displayName.StartsWith(settingsPath) && !displayName.Substring(pathLength).Contains("/")) { var settingsObject = PackageSettingsWrapper.SettingsKeyWrapper.Create(key, profile); settingsList.Add(key.DisplayName.GetFileName(), settingsObject); } } // Add the settings commands var commands = EditorSettings.GetAllCommands(); foreach (SettingsCommand command in commands) { var displayName = command.DisplayName.ToString(); if (displayName.StartsWith(settingsPath) && !displayName.Substring(pathLength).Contains("/")) { settingsList.Add(command.DisplayName.GetFileName(), command); } } }