public void RestoreHierarchy(AssetDocumentHierarchyElementContainer hierarchyElementContainer, IPsiSourceFile sourceFile)
        {
            if (myIsRestored)
            {
                return;
            }

            lock (myLockObject)
            {
                if (myIsRestored)
                {
                    return;
                }

                myIsRestored = true;

                AssetDocumentHierarchyElementContainer = hierarchyElementContainer;
                IsScene = sourceFile.GetLocation().ExtensionWithDot.Equals(UnityYamlConstants.Scene);


                var offset = 0;
                // concating arrays to one by index. see GetElementByInternalIndex too
                PrepareElements(myOtherBoxedElements, offset);
                offset += myOtherBoxedElements.Count;

                PrepareElements(myTransformElements, offset);
                offset += myTransformElements.Count;

                PrepareElements(myGameObjectHierarchies, offset);
                offset += myGameObjectHierarchies.Count;

                PrepareElements(myComponentElements, offset);
                offset += myComponentElements.Count;

                PrepareElements(myScriptComponentElements, offset);
                offset += myScriptComponentElements.Count;

                foreach (var prefabInstanceHierarchy in GetPrefabInstanceHierarchies())
                {
                    var correspondingSourceObjects = new HashSet <ExternalReference>();
                    foreach (var modification in prefabInstanceHierarchy.PrefabModifications)
                    {
                        var target = modification.Target;
                        if (!(target is ExternalReference externalReference))
                        {
                            continue;
                        }
                        correspondingSourceObjects.Add(externalReference);
                    }

                    foreach (var correspondingSourceObject in correspondingSourceObjects)
                    {
                        var fakeAnchor = PrefabsUtil.GetImportedDocumentAnchor(prefabInstanceHierarchy.Location.LocalDocumentAnchor, correspondingSourceObject.LocalDocumentAnchor);
                        myOtherFakeStrippedElements.Add(new StrippedHierarchyElement(
                                                            new LocalReference(sourceFile.PsiStorage.PersistentIndex, fakeAnchor),
                                                            prefabInstanceHierarchy.Location, correspondingSourceObject));
                    }
                }
            }
        }
        public IHierarchyElement GetHierarchyElement(string ownerGuid, ulong anchor, PrefabImportCache prefabImportCache)
        {
            if (myLocalAnchorToHierarchyElement.TryGetValue(anchor, out var result))
            {
                if (!result.IsStripped || prefabImportCache == null) // stipped means, that element is not real and we should import prefab
                {
                    return(result);
                }
            }

            if (result != null && IsScene && result.IsStripped)
            {
                var prefabInstance      = result.PrefabInstance;
                var correspondingObject = result.CorrespondingSourceObject;
                if (prefabInstance != null && correspondingObject != null)
                {
                    anchor = PrefabsUtil.Import(prefabInstance.LocalDocumentAnchor, correspondingObject.LocalDocumentAnchor);
                }
            }

            if (prefabImportCache != null)
            {
                var elements = prefabImportCache.GetImportedElementsFor(ownerGuid, this);

                if (elements.TryGetValue(anchor, out var importedResult))
                {
                    return(importedResult);
                }
            }

            return(null);
        }
        public IHierarchyElement GetHierarchyElement(Guid?ownerGuid, ulong anchor, PrefabImportCache prefabImportCache)
        {
            var result = SearchForAnchor(anchor);

            if (result != null)
            {
                if (!(result is IStrippedHierarchyElement) || prefabImportCache == null) // stipped means, that element is not real and we should import prefab
                {
                    return(result);
                }
            }

            // In prefabs files, anchor for stripped element is always generated by formula in PrefabsUtil. This means
            // that after we import elements from prefab file into another file, we could reuse anchor from stripped element to
            // get real element (in current implementation, imported objects are store in PrefabImportCache)
            // It is not true(!!!) for scene files, anchors for scene files could be generated by sequence generator. This means,
            // that anchor for stripped element could be '19' for example, but imported element will have another anchor.
            //
            // To unify all logic, if ownerGuid is related to scene file and achor points to stripped file, we will
            // use new anchor which calculated in same way with prefab import
            if (result != null && IsScene && result is IStrippedHierarchyElement strippedHierarchyElement)
            {
                var prefabInstance      = strippedHierarchyElement.PrefabInstance;
                var correspondingObject = strippedHierarchyElement.CorrespondingSourceObject;
                anchor = PrefabsUtil.GetImportedDocumentAnchor(prefabInstance.LocalDocumentAnchor, correspondingObject.LocalDocumentAnchor);
            }

            if (prefabImportCache != null && ownerGuid != null)
            {
                var elements = prefabImportCache.GetImportedElementsFor(ownerGuid.Value, this);

                if (elements.TryGetValue(anchor, out var importedResult))
                {
                    return(importedResult);
                }
            }

            return(null);
        }
        private ImportedInspectorValues ProcessPrefabModifications(IPsiSourceFile currentSourceFile, AssetDocument assetDocument)
        {
            var result = new ImportedInspectorValues();

            if (assetDocument.HierarchyElement is IPrefabInstanceHierarchy prefabInstanceHierarchy)
            {
                foreach (var modification in prefabInstanceHierarchy.PrefabModifications)
                {
                    if (!(modification.Target is ExternalReference externalReference))
                    {
                        continue;
                    }

                    if (modification.PropertyPath.Contains("."))
                    {
                        continue;
                    }

                    var location = new LocalReference(currentSourceFile.PsiStorage.PersistentIndex.NotNull("owningPsiPersistentIndex != null"), PrefabsUtil.GetImportedDocumentAnchor(prefabInstanceHierarchy.Location.LocalDocumentAnchor, externalReference.LocalDocumentAnchor));
                    result.Modifications[new ImportedValueReference(location, modification.PropertyPath)] = (modification.Value, new AssetReferenceValue(modification.ObjectReference));
                }
            }

            return(result);
        }
示例#5
0
        private ImportedUnityEventData ProcessPrefabModifications(IPsiSourceFile currentFile, AssetDocument document)
        {
            var result = new ImportedUnityEventData();

            if (document.HierarchyElement is IPrefabInstanceHierarchy prefabInstanceHierarchy)
            {
                var assetMethodDataToModifiedFields = new OneToSetMap <(LocalReference, string, int), string>();
                foreach (var modification in prefabInstanceHierarchy.PrefabModifications)
                {
                    if (!(modification.Target is ExternalReference externalReference))
                    {
                        continue;
                    }

                    if (!modification.PropertyPath.Contains("m_PersistentCalls"))
                    {
                        continue;
                    }

                    var location       = new LocalReference(currentFile.PsiStorage.PersistentIndex, PrefabsUtil.GetImportedDocumentAnchor(prefabInstanceHierarchy.Location.LocalDocumentAnchor, externalReference.LocalDocumentAnchor));
                    var parts          = modification.PropertyPath.Split('.');
                    var unityEventName = parts[0];


                    var dataPart = parts.FirstOrDefault(t => t.StartsWith("data"));
                    if (dataPart == null)
                    {
                        continue;
                    }

                    if (!int.TryParse(dataPart.RemoveStart("data[").RemoveEnd("]"), out var index))
                    {
                        continue;
                    }

                    result.UnityEventToModifiedIndex.Add((location, unityEventName), index);
                    var last = parts.Last();
                    if (last.Equals("m_MethodName") && modification.Value is AssetSimpleValue assetSimpleValue)
                    {
                        result.AssetMethodNameInModifications.Add(assetSimpleValue.SimpleValue);
                    }

                    assetMethodDataToModifiedFields.Add((location, unityEventName, index), last);
                }

                foreach (var(_, set) in assetMethodDataToModifiedFields)
                {
                    if (!set.Contains("m_MethodName"))
                    {
                        result.HasEventModificationWithoutMethodName = true;
                    }
                }
            }

            return(result);
        }