Ejemplo n.º 1
0
        public AssetPropertyGraph(AssetPropertyGraphContainer container, AssetItem assetItem, ILogger logger)
        {
            if (container == null)
            {
                throw new ArgumentNullException(nameof(container));
            }
            if (assetItem == null)
            {
                throw new ArgumentNullException(nameof(assetItem));
            }
            Container = container;
            AssetCollectionItemIdHelper.GenerateMissingItemIds(assetItem.Asset);
            CollectionItemIdsAnalysis.FixupItemIds(assetItem, logger);
            Asset    = assetItem.Asset;
            RootNode = (AssetObjectNode)Container.NodeContainer.GetOrCreateNode(assetItem.Asset);
            ApplyOverrides(RootNode, assetItem.Overrides);
            nodeListener           = new GraphNodeChangeListener(RootNode, ShouldListenToTargetNode);
            nodeListener.Changing += AssetContentChanging;
            nodeListener.Changed  += AssetContentChanged;

            baseLinker = new AssetToBaseNodeLinker(this)
            {
                LinkAction = LinkBaseNode
            };
        }
Ejemplo n.º 2
0
 public void PrepareForSave(ILogger logger, AssetItem assetItem)
 {
     if (assetItem.Asset != Asset)
     {
         throw new ArgumentException($@"The given {nameof(AssetItem)} does not match the asset associated with this instance", nameof(assetItem));
     }
     AssetCollectionItemIdHelper.GenerateMissingItemIds(assetItem.Asset);
     CollectionItemIdsAnalysis.FixupItemIds(assetItem, logger);
     assetItem.Overrides = GenerateOverridesForSerialization(RootNode);
 }
        private static Dictionary <AssetViewModel, List <ItemToReload> > PrepareAssemblyReloading(SessionViewModel session, UnloadingVisitor visitor, IUndoRedoService actionService)
        {
            var assetItemsToReload = new Dictionary <AssetViewModel, List <ItemToReload> >();

            // Serialize old objects from unloaded assemblies to Yaml streams
            foreach (var asset in session.LocalPackages.SelectMany(x => x.Assets))
            {
                // Asset has no quantum graph (eg. text asset), let's skip it
                if (asset.PropertyGraph == null)
                {
                    continue;
                }

                // Generate missing ids for safetly
                AssetCollectionItemIdHelper.GenerateMissingItemIds(asset.Asset);

                // Serialize objects with types to unload to Yaml
                // Objects that were already IUnloadable will also be included
                var rootNode      = session.AssetNodeContainer.GetNode(asset.Asset);
                var itemsToReload = visitor.Run(asset.PropertyGraph);

                if (itemsToReload.Count > 0)
                {
                    // We apply changes in opposite visit order so that indices remains valid when we remove objects while iterating
                    for (int index = itemsToReload.Count - 1; index >= 0; index--)
                    {
                        var itemToReload = itemsToReload[index];

                        // Transform path to Quantum
                        itemToReload.GraphPath = GraphNodePath.From(rootNode, itemToReload.Path, out itemToReload.GraphPathIndex);

                        // Remove (collections) or replace nodes with null (members) so that we can unload assemblies
                        ClearNode(actionService, asset, itemToReload);
                    }

                    // Add to list of items to reload for PostAssemblyReloading
                    assetItemsToReload.Add(asset, new List <ItemToReload>(itemsToReload));
                }
            }

            return(assetItemsToReload);
        }
Ejemplo n.º 4
0
        private AssetViewModel CreateAsset(DirectoryBaseViewModel directory, AssetItem assetItem, bool canUndoRedoCreation, LoggerResult loggerResult, bool isLoading)
        {
            if (directory == null)
            {
                throw new ArgumentNullException(nameof(directory));
            }
            if (assetItem == null)
            {
                throw new ArgumentNullException(nameof(assetItem));
            }

            AssetCollectionItemIdHelper.GenerateMissingItemIds(assetItem.Asset);
            var parameters = new AssetViewModelConstructionParameters(ServiceProvider, directory, Package, assetItem, directory.Session.AssetNodeContainer, canUndoRedoCreation);

            Session.GraphContainer.InitializeAsset(assetItem, loggerResult);
            var assetType          = assetItem.Asset.GetType();
            var assetViewModelType = typeof(AssetViewModel <>);

            while (assetType != null)
            {
                if (Session.AssetViewModelTypes.TryGetValue(assetType, out assetViewModelType))
                {
                    break;
                }

                assetViewModelType = typeof(AssetViewModel <>);
                assetType          = assetType.BaseType;
            }
            if (assetViewModelType.IsGenericType)
            {
                assetViewModelType = assetViewModelType.MakeGenericType(assetItem.Asset.GetType());
            }
            var asset = (AssetViewModel)Activator.CreateInstance(assetViewModelType, parameters);

            if (!isLoading)
            {
                asset.Initialize();
            }
            return(asset);
        }
Ejemplo n.º 5
0
        internal void OnItemChanged(object sender, ItemChangeEventArgs e)
        {
            var value = node.Retrieve();

            if (!CollectionItemIdHelper.HasCollectionItemIds(value))
            {
                return;
            }

            // Make sure that we have item ids everywhere we're supposed to.
            AssetCollectionItemIdHelper.GenerateMissingItemIds(e.Collection.Retrieve());

            // Clear the cached item identifier collection.
            collectionItemIdentifiers = null;

            // Create new ids for collection items
            var baseNode             = (AssetObjectNode)BaseNode;
            var removedId            = ItemId.Empty;
            var isOverriding         = baseNode != null && !PropertyGraph.UpdatingPropertyFromBase;
            var itemIds              = CollectionItemIdHelper.GetCollectionItemIds(value);
            var collectionDescriptor = node.Descriptor as CollectionDescriptor;

            switch (e.ChangeType)
            {
            case ContentChangeType.CollectionUpdate:
                break;

            case ContentChangeType.CollectionAdd:
            {
                // Compute the id we will add for this item
                var itemId = restoringId != ItemId.Empty ? restoringId : ItemId.New();
                // Add the id to the proper location (insert or add)
                if (collectionDescriptor != null)
                {
                    if (e.Index == Index.Empty)
                    {
                        throw new InvalidOperationException("An item has been added to a collection that does not have a predictable Add. Consider using NonIdentifiableCollectionItemsAttribute on this collection.");
                    }

                    itemIds.Insert(e.Index.Int, itemId);
                }
                else
                {
                    itemIds[e.Index.Value] = itemId;
                }
                break;
            }

            case ContentChangeType.CollectionRemove:
            {
                var itemId = itemIds[e.Index.Value];
                // update isOverriding, it should be true only if the item being removed exist in the base.
                isOverriding = isOverriding && baseNode.HasId(itemId);
                removedId    = collectionDescriptor != null?itemIds.DeleteAndShift(e.Index.Int, isOverriding) : itemIds.Delete(e.Index.Value, isOverriding);

                break;
            }

            default:
                throw new ArgumentOutOfRangeException();
            }


            // Don't update override if propagation from base is disabled.
            if (PropertyGraph?.Container?.PropagateChangesFromBase == false)
            {
                return;
            }

            // Mark it as New if it does not come from the base
            if (!ResettingOverride)
            {
                if (e.ChangeType != ContentChangeType.CollectionRemove && isOverriding)
                {
                    // If it's an add or an updating, there is no scenario where we can be "un-overriding" without ResettingOverride, so we pass true.
                    OverrideItem(true, e.Index);
                }
                else if (e.ChangeType == ContentChangeType.CollectionRemove)
                {
                    // If it's a delete, it could be an item that was previously added as an override, and that should not be marked as "deleted-overridden", so we pass isOverriding
                    OverrideDeletedItem(isOverriding, removedId);
                }
            }
        }
Ejemplo n.º 6
0
        private void ContentChanged(object sender, ContentChangeEventArgs e)
        {
            // Make sure that we have item ids everywhere we're supposed to.
            AssetCollectionItemIdHelper.GenerateMissingItemIds(e.Content.Retrieve());

            var node = (AssetNode)e.Content.OwnerNode;

            if (node.IsNonIdentifiableCollectionContent)
            {
                return;
            }

            // Create new ids for collection items
            var baseNode     = (AssetNode)BaseContent?.OwnerNode;
            var isOverriding = !baseNode?.contentUpdating == true;
            var removedId    = ItemId.Empty;

            switch (e.ChangeType)
            {
            case ContentChangeType.ValueChange:
                break;

            case ContentChangeType.CollectionAdd:
            {
                var collectionDescriptor = e.Content.Descriptor as CollectionDescriptor;
                var itemIds = CollectionItemIdHelper.GetCollectionItemIds(e.Content.Retrieve());
                // Compute the id we will add for this item
                ItemId itemId;
                if (baseNode?.contentUpdating == true)
                {
                    var baseCollection = baseNode.Content.Retrieve();
                    var baseIds        = CollectionItemIdHelper.GetCollectionItemIds(baseCollection);
                    itemId = itemIds.FindMissingId(baseIds);
                }
                else
                {
                    itemId = restoringId != ItemId.Empty ? restoringId : ItemId.New();
                }
                // Add the id to the proper location (insert or add)
                if (collectionDescriptor != null)
                {
                    if (e.Index != Index.Empty)
                    {
                        itemIds.Insert(e.Index.Int, itemId);
                    }
                    else
                    {
                        throw new InvalidOperationException("An item has been added to a collection that does not have a predictable Add. Consider using NonIdentifiableCollectionItemsAttribute on this collection.");
                    }
                }
                else
                {
                    itemIds[e.Index.Value] = itemId;
                }
            }
            break;

            case ContentChangeType.CollectionRemove:
            {
                var collectionDescriptor = e.Content.Descriptor as CollectionDescriptor;
                if (collectionDescriptor != null)
                {
                    var itemIds = CollectionItemIdHelper.GetCollectionItemIds(e.Content.Retrieve());
                    removedId = itemIds.DeleteAndShift(e.Index.Int, isOverriding);
                }
                else
                {
                    var itemIds = CollectionItemIdHelper.GetCollectionItemIds(e.Content.Retrieve());
                    removedId = itemIds.Delete(e.Index.Value, isOverriding);
                }
            }
            break;

            default:
                throw new ArgumentOutOfRangeException();
            }


            // Don't update override if propagation from base is disabled.
            if (PropertyGraph?.Container?.PropagateChangesFromBase == false)
            {
                return;
            }

            // Mark it as New if it does not come from the base
            if (!baseNode?.contentUpdating == true && !ResettingOverride)
            {
                if (e.ChangeType != ContentChangeType.CollectionRemove)
                {
                    if (e.Index == Index.Empty)
                    {
                        OverrideContent(!ResettingOverride);
                    }
                    else
                    {
                        OverrideItem(!ResettingOverride, e.Index);
                    }
                }
                else
                {
                    OverrideDeletedItem(true, removedId);
                }
            }
        }
Ejemplo n.º 7
0
        public void TestIdsGeneration()
        {
            ShadowObject.Enable = true;
            CollectionItemIdentifiers ids;

            var obj1 = new ContainerCollection("Root")
            {
                Strings = { "aaa", "bbb", "ccc" },
                Objects = { new ContainerCollection("obj1"), new ContainerCollection("obj2") }
            };
            var hashSet = new HashSet <ItemId>();

            Assert.False(CollectionItemIdHelper.TryGetCollectionItemIds(obj1.Strings, out ids));
            Assert.False(CollectionItemIdHelper.TryGetCollectionItemIds(obj1.Strings, out ids));
            Assert.False(CollectionItemIdHelper.TryGetCollectionItemIds(obj1.Objects, out ids));
            Assert.False(CollectionItemIdHelper.TryGetCollectionItemIds(obj1.Objects, out ids));
            AssetCollectionItemIdHelper.GenerateMissingItemIds(obj1);
            Assert.True(CollectionItemIdHelper.TryGetCollectionItemIds(obj1.Strings, out ids));
            Assert.Equal(3, ids.KeyCount);
            Assert.Equal(0, ids.DeletedCount);
            Assert.True(ids.ContainsKey(0));
            Assert.True(ids.ContainsKey(1));
            Assert.True(ids.ContainsKey(2));
            hashSet.Add(ids[0]);
            hashSet.Add(ids[1]);
            hashSet.Add(ids[2]);
            Assert.True(CollectionItemIdHelper.TryGetCollectionItemIds(obj1.Objects, out ids));
            Assert.Equal(2, ids.KeyCount);
            Assert.Equal(0, ids.DeletedCount);
            Assert.True(ids.ContainsKey(0));
            Assert.True(ids.ContainsKey(1));
            hashSet.Add(ids[0]);
            hashSet.Add(ids[1]);
            Assert.Equal(5, hashSet.Count);

            var obj2 = new ContainerDictionary("Root")
            {
                Strings = { { GuidGenerator.Get(200), "aaa" }, { GuidGenerator.Get(100), "bbb" }, { GuidGenerator.Get(300), "ccc" } },
                Objects = { { "key3", new ContainerCollection("obj1") }, { "key4", new ContainerCollection("obj2") } },
            };

            hashSet.Clear();
            Assert.False(CollectionItemIdHelper.TryGetCollectionItemIds(obj2.Strings, out ids));
            Assert.False(CollectionItemIdHelper.TryGetCollectionItemIds(obj2.Strings, out ids));
            Assert.False(CollectionItemIdHelper.TryGetCollectionItemIds(obj2.Objects, out ids));
            Assert.False(CollectionItemIdHelper.TryGetCollectionItemIds(obj2.Objects, out ids));
            AssetCollectionItemIdHelper.GenerateMissingItemIds(obj2);
            Assert.True(CollectionItemIdHelper.TryGetCollectionItemIds(obj2.Strings, out ids));
            Assert.Equal(3, ids.KeyCount);
            Assert.Equal(0, ids.DeletedCount);
            Assert.True(ids.ContainsKey(GuidGenerator.Get(200)));
            Assert.True(ids.ContainsKey(GuidGenerator.Get(100)));
            Assert.True(ids.ContainsKey(GuidGenerator.Get(300)));
            hashSet.Add(ids[GuidGenerator.Get(200)]);
            hashSet.Add(ids[GuidGenerator.Get(100)]);
            hashSet.Add(ids[GuidGenerator.Get(300)]);
            Assert.True(CollectionItemIdHelper.TryGetCollectionItemIds(obj2.Objects, out ids));
            Assert.Equal(2, ids.KeyCount);
            Assert.Equal(0, ids.DeletedCount);
            Assert.True(ids.ContainsKey("key3"));
            Assert.True(ids.ContainsKey("key4"));
            hashSet.Add(ids["key3"]);
            hashSet.Add(ids["key4"]);
            Assert.Equal(5, hashSet.Count);
        }
Ejemplo n.º 8
0
 public void PrepareForSave(ILogger logger)
 {
     AssetCollectionItemIdHelper.GenerateMissingItemIds(AssetItem.Asset);
     CollectionItemIdsAnalysis.FixupItemIds(AssetItem, logger);
     AssetItem.Overrides = GenerateOverridesForSerialization(RootNode);
 }