public void TestClone()
        {
            var originAsset = CreateOriginAsset();
            var newAsset    = (EntityGroupAsset)AssetCloner.Clone(originAsset);

            CheckAsset(originAsset, newAsset);
        }
Example #2
0
        public void TestClone()
        {
            var originAsset = CreateOriginAsset();
            var newAsset    = (PrefabAsset)AssetCloner.Clone(originAsset);

            CheckAsset(originAsset, newAsset);
        }
Example #3
0
        private bool MergeAsset(AssetItem item, AssetItem existingBase, List <AssetBase> existingBaseParts)
        {
            // No need to clone existingBaseParts as they are already cloned
            var baseCopy    = (Asset)AssetCloner.Clone(item.Asset.Base?.Asset);
            var newBaseCopy = (Asset)AssetCloner.Clone(existingBase?.Asset);

            // Delegates actual merge to the asset implem
            var result = item.Asset.Merge(baseCopy, newBaseCopy, existingBaseParts);

            if (result.HasErrors)
            {
                result.CopyTo(log);
                return(false);
            }

            item.Asset = (Asset)result.Asset;
            if (item.Asset.Base != null)
            {
                item.Asset.Base = newBaseCopy != null ? new AssetBase(item.Asset.Base.Location, newBaseCopy) : null;
            }

            // Use new existing base parts
            if (existingBaseParts != null)
            {
                item.Asset.BaseParts = existingBaseParts;
            }

            item.IsDirty = true;
            return(true);
        }
Example #4
0
        /// <summary>
        /// This method is called when an asset needs to be tracked
        /// </summary>
        /// <returns>AssetDependencies.</returns>
        private void TrackAsset(AssetId assetId)
        {
            lock (ThisLock)
            {
                if (trackedAssets.ContainsKey(assetId))
                {
                    return;
                }

                // TODO provide an optimized version of TrackAsset method
                // taking directly a well known asset (loaded from a Package...etc.)
                // to avoid session.FindAsset
                var assetItem = session.FindAsset(assetId);
                if (assetItem == null)
                {
                    return;
                }

                // Clone the asset before using it in this instance to make sure that
                // we have some kind of immutable state
                // TODO: This is not handling shadow registry

                // No need to clone assets from readonly package
                var clonedAsset  = assetItem.Package.IsSystem ? assetItem.Asset : AssetCloner.Clone(assetItem.Asset);
                var trackedAsset = new TrackedAsset(this, assetItem.Asset, clonedAsset);

                // Adds to global list
                trackedAssets.Add(assetId, trackedAsset);
            }
        }
Example #5
0
        public void TestNoChanges()
        {
            var baseAsset = new TestDiffAsset()
            {
                Name = "Red", Value = 1, Dynamic = new DiffValueTypeA()
                {
                    Text = "Test1"
                }
            };
            var newBaseAsset = (TestDiffAsset)AssetCloner.Clone(baseAsset);
            var baseItem     = new AssetItem("/base", baseAsset);
            var childAsset   = (TestDiffAsset)baseItem.CreateChildAsset();

            var diff = new AssetDiff(baseAsset, childAsset, newBaseAsset)
            {
                UseOverrideMode = true
            };

            var diffResult = diff.Compute();

            var diffResultStripped = diffResult.FindLeafDifferences().ToList();

            // 6: BuildOrder+Name+Value+(Dynamic: Text+Text2+Text3)
            Assert.AreEqual(6, diffResultStripped.Count);

            // Check that everything is merging from asset2
            Assert.True(diffResultStripped.All(node => node.ChangeType == Diff3ChangeType.MergeFromAsset2));
        }
Example #6
0
        protected virtual object CloneObjectForGameSide(object assetSideObject, IAssetNode assetNode, IGraphNode gameSideNode)
        {
            // Null references, they will be handled by the editor asset loader
            var gameSideValue = AssetCloner.Clone(assetSideObject, AssetClonerFlags.ReferenceAsNull);

            return(gameSideValue);
        }
        /// <inheritdoc />
        public override bool ProcessDeserializedData(AssetPropertyGraphContainer graphContainer, object targetRootObject, Type targetMemberType, ref object data, bool isRootDataObjectReference, AssetId?sourceId, YamlAssetMetadata <OverrideType> overrides, YamlAssetPath basePath)
        {
            if (targetRootObject == null)
            {
                throw new ArgumentNullException(nameof(targetRootObject));
            }
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            var collectionDescriptor = (CollectionDescriptor)TypeDescriptorFactory.Default.Find(targetRootObject.GetType());

            var collection = data as IList <AssetItem>;

            if (collection == null)
            {
                collection = (IList <AssetItem>)Activator.CreateInstance(collectionDescriptor.Type, true);
                collectionDescriptor.Add(collection, data);
            }

            for (var i = 0; i < collection.Count; i++)
            {
                var assetItem = collection[i];
                // If the asset already exists, clone it with new identifiers
                if (session.GetAssetById(assetItem.Id) != null)
                {
                    // Create a derived asset and restore archetype to handle asset-specific cloning process.
                    Dictionary <Guid, Guid> idRemapping;
                    var clone = AssetCloner.Clone(assetItem.Asset, AssetClonerFlags.GenerateNewIdsForIdentifiableObjects, out idRemapping);

                    var assetType = assetItem.Asset.GetType();
                    if (assetType.HasInterface(typeof(AssetCompositeHierarchy <,>)))
                    {
                        try
                        {
                            // TODO: Find a way to fallback to the asset or generalize for all asset composite
                            dynamic assetComposite = clone;
                            // Remap indices of parts in Hierarchy.Part
                            var path = basePath.Clone();
                            path.PushItemId(CollectionItemIdHelper.GetCollectionItemIds(collection)[i]);
                            AssetCloningHelper.RemapIdentifiablePaths(overrides, idRemapping, path);
                            AssetPartsAnalysis.GenerateNewBaseInstanceIds(assetComposite.Hierarchy);
                        }
                        catch (RuntimeBinderException e)
                        {
                            e.Ignore();
                        }
                    }
                    // FIXME: rework this
                    var postProcessor = session.ServiceProvider.Get <ICopyPasteService>().PostProcessors.FirstOrDefault(p => p.Accept(assetType));
                    postProcessor?.PostPasteDeserialization(clone);
                    collection[i] = new AssetItem(assetItem.Location, clone);
                }
            }

            // Get the fixed-up value
            data = collection;
            return(true);
        }
Example #8
0
        public void TestChangeOverrideToBaseSealed()
        {
            var baseAsset = new TestDiffAsset()
            {
                Name = "Red", Value = 1
            };
            var newBaseAsset = (TestDiffAsset)AssetCloner.Clone(baseAsset);

            newBaseAsset.Value = 3;

            var baseItem   = new AssetItem("/base", baseAsset);
            var childAsset = (TestDiffAsset)baseItem.CreateChildAsset();

            // Change base: Name to Base|Sealed
            // This should result into a reset of the value overriden in child

            // Make New on Name value on first element
            var objDesc    = TypeDescriptorFactory.Default.Find(typeof(TestDiffAsset));
            var memberDesc = objDesc.Members.First(t => t.Name == "Value");

            newBaseAsset.SetOverride(memberDesc, OverrideType.Base | OverrideType.Sealed);

            var diff = new AssetDiff(baseAsset, childAsset, newBaseAsset)
            {
                UseOverrideMode = true
            };

            var diffResult = diff.Compute();

            // Check that merged result on Dynamic property is instance from asset2
            var mergeResult = AssetMerge.Merge(diff, AssetMergePolicies.MergePolicyAsset2AsNewBaseOfAsset1);

            Assert.AreEqual(3, childAsset.Value);                                                         // Value is coming from base
            Assert.AreEqual(OverrideType.Base | OverrideType.Sealed, childAsset.GetOverride(memberDesc)); // Value is coming from base
        }
        private void UpdateGameSettings(GameSettingsAsset gameSettings)
        {
            currentGameSettings = AssetCloner.Clone(gameSettings, AssetClonerFlags.RemoveUnloadableObjects);

            bool shouldRefreshAllThumbnails = false;

            if (renderingMode != gameSettings.GetOrCreate <EditorSettings>().RenderingMode)
            {
                renderingMode = gameSettings.GetOrCreate <EditorSettings>().RenderingMode;
                shouldRefreshAllThumbnails = true;
            }
            if (colorSpace != gameSettings.GetOrCreate <RenderingSettings>().ColorSpace)
            {
                colorSpace = gameSettings.GetOrCreate <RenderingSettings>().ColorSpace;
                shouldRefreshAllThumbnails = true;
            }
            if (graphicsProfile != gameSettings.GetOrCreate <RenderingSettings>().DefaultGraphicsProfile)
            {
                graphicsProfile            = gameSettings.GetOrCreate <RenderingSettings>().DefaultGraphicsProfile;
                shouldRefreshAllThumbnails = true;
            }
            if (shouldRefreshAllThumbnails)
            {
                var allAssets = session.AllAssets.Select(x => x.AssetItem).ToList();
                Task.Run(() => AddThumbnailAssetItems(allAssets, QueuePosition.First));
            }
        }
Example #10
0
        /// <inheritdoc />
        protected override IEnumerable <AssetItem> CreateAssets(AssetTemplateGeneratorParameters parameters)
        {
            var importedAssets = new List <AssetItem>();

            foreach (var assetItem in base.CreateAssets(parameters))
            {
                if (assetItem.Asset is SoundAsset soundAsset)
                {
                    using (var media = new FFmpegMedia())
                    {
                        media.Open(soundAsset.Source.ToWindowsPath());
                        var audioStreams = media.Streams.OfType <AudioStream>().ToList();
                        foreach (var audioTrack in audioStreams)
                        {
                            var assetCopy = AssetCloner.Clone(soundAsset);
                            assetCopy.Index      = audioTrack.Index;
                            assetCopy.SampleRate = audioTrack.SampleRate;

                            // If there's more than one streams, append the track index to the asset name
                            var fileLocation = audioStreams.Count > 1
                                ? (UFile)(assetItem.Location + " track " + audioTrack.Index)
                                : assetItem.Location;
                            importedAssets.Add(new AssetItem(fileLocation, assetCopy));
                        }
                    }
                }
            }

            return(MakeUniqueNames(importedAssets));
        }
Example #11
0
        public void TestClone()
        {
            var originAsset = CreateOriginAsset();
            var newAsset    = AssetCloner.Clone(originAsset);

            CheckAsset(originAsset, newAsset, originAsset.Hierarchy.Parts.Select(x => x.Value.Entity.Id).ToDictionary(x => x, x => x));
        }
Example #12
0
        public void TestCloneCollectionIds()
        {
            var obj = new TestObjectWithCollection {
                Name = "Test", Items = { "aaa", "bbb" }
            };
            var ids = CollectionItemIdHelper.GetCollectionItemIds(obj.Items);

            ids.Add(0, new ItemId());
            ids.Add(1, new ItemId());
            ids.MarkAsDeleted(new ItemId());
            var clone = AssetCloner.Clone(obj);
            CollectionItemIdentifiers cloneIds;
            var idsExist = CollectionItemIdHelper.TryGetCollectionItemIds(clone.Items, out cloneIds);

            Assert.True(idsExist);
            Assert.AreEqual(ids.KeyCount, cloneIds.KeyCount);
            Assert.AreEqual(ids.DeletedCount, cloneIds.DeletedCount);
            Assert.AreEqual(ids[0], cloneIds[0]);
            Assert.AreEqual(ids[1], cloneIds[1]);
            Assert.AreEqual(ids.DeletedItems.Single(), cloneIds.DeletedItems.Single());

            clone    = AssetCloner.Clone(obj, AssetClonerFlags.RemoveItemIds);
            idsExist = CollectionItemIdHelper.TryGetCollectionItemIds(clone.Items, out cloneIds);
            Assert.False(idsExist);
        }
Example #13
0
        protected override void Prepare(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result)
        {
            var   asset             = (SpriteFontAsset)assetItem.Asset;
            UFile assetAbsolutePath = assetItem.FullPath;
            var   colorSpace        = context.GetColorSpace();

            var fontTypeSdf = asset.FontType as SignedDistanceFieldSpriteFontType;

            if (fontTypeSdf != null)
            {
                // copy the asset and transform the source and character set file path to absolute paths
                var assetClone     = AssetCloner.Clone(asset);
                var assetDirectory = assetAbsolutePath.GetParent();
                assetClone.FontSource    = asset.FontSource;
                fontTypeSdf.CharacterSet = !string.IsNullOrEmpty(fontTypeSdf.CharacterSet) ? UPath.Combine(assetDirectory, fontTypeSdf.CharacterSet) : null;

                result.BuildSteps = new AssetBuildStep(assetItem);
                result.BuildSteps.Add(new SignedDistanceFieldFontCommand(targetUrlInStorage, assetClone, assetItem.Package));
            }
            else
            if (asset.FontType is RuntimeRasterizedSpriteFontType)
            {
                UFile fontPathOnDisk = asset.FontSource.GetFontPath(result);
                if (fontPathOnDisk == null)
                {
                    result.Error($"Runtime rasterized font compilation failed. Font {asset.FontSource.GetFontName()} was not found on this machine.");
                    result.BuildSteps = new AssetBuildStep(assetItem);
                    result.BuildSteps.Add(new FailedFontCommand());
                    return;
                }

                var fontImportLocation = FontHelper.GetFontPath(asset.FontSource.GetFontName(), asset.FontSource.Style);

                result.BuildSteps = new AssetBuildStep(assetItem);
                result.BuildSteps.Add(new ImportStreamCommand {
                    SourcePath = fontPathOnDisk, Location = fontImportLocation
                });
                result.BuildSteps.Add(new RuntimeRasterizedFontCommand(targetUrlInStorage, asset, assetItem.Package));
            }
            else
            {
                var fontTypeStatic = asset.FontType as OfflineRasterizedSpriteFontType;
                if (fontTypeStatic == null)
                {
                    throw new ArgumentException("Tried to compile a non-offline rasterized sprite font with the compiler for offline resterized fonts!");
                }

                // copy the asset and transform the source and character set file path to absolute paths
                var assetClone     = AssetCloner.Clone(asset);
                var assetDirectory = assetAbsolutePath.GetParent();
                assetClone.FontSource       = asset.FontSource;
                fontTypeStatic.CharacterSet = !string.IsNullOrEmpty(fontTypeStatic.CharacterSet) ? UPath.Combine(assetDirectory, fontTypeStatic.CharacterSet): null;

                result.BuildSteps = new AssetBuildStep(assetItem);
                result.BuildSteps.Add(new OfflineRasterizedFontCommand(targetUrlInStorage, assetClone, colorSpace, assetItem.Package)
                {
                    InputFilesGetter = () => GetInputFiles(assetItem)
                });
            }
        }
Example #14
0
        public void TestCloneAndShadowObject()
        {
            var obj = new TestAssetClonerObject
            {
                Name      = "Test1",
                SubObject = new TestAssetClonerObject()
                {
                    Name = "Test2"
                }
            };

            var objDesc    = TypeDescriptorFactory.Default.Find(typeof(TestAssetClonerObject));
            var memberDesc = objDesc.Members.First(t => t.Name == "Name");

            obj.SetOverride(memberDesc, OverrideType.New);
            obj.SubObject.SetOverride(memberDesc, OverrideType.Sealed);

            var newInstance = (TestAssetClonerObject)AssetCloner.Clone(obj);

            // Check that we are getting shadow objects
            Assert.AreEqual(OverrideType.New, newInstance.GetOverride(memberDesc));
            Assert.AreEqual(OverrideType.Sealed, newInstance.SubObject.GetOverride(memberDesc));

            // Change original object to default, but check that we are working on a shadow object copy on the cloned object
            obj.SetOverride(memberDesc, OverrideType.Base);
            Assert.AreEqual(OverrideType.New, newInstance.GetOverride(memberDesc));
        }
Example #15
0
        /// <inheritdoc />
        protected override IEnumerable <AssetItem> CreateAssets(AssetTemplateGeneratorParameters parameters)
        {
            var importedAssets = new List <AssetItem>();

            foreach (var assetItem in base.CreateAssets(parameters))
            {
                if (assetItem.Asset is SoundAsset soundAsset)
                {
                    using (var media = new FFmpegMedia())
                    {
                        media.Open(soundAsset.Source.ToWindowsPath());
                        foreach (var audioTrack in media.Streams.OfType <AudioStream>().ToList())
                        {
                            var assetCopy = AssetCloner.Clone(soundAsset);
                            assetCopy.Index      = audioTrack.Index;
                            assetCopy.SampleRate = audioTrack.SampleRate;

                            importedAssets.Add(new AssetItem(assetItem.Location + (audioTrack.Index > 0 ? " track " + audioTrack.Index : ""), assetCopy));
                        }
                    }
                }
            }

            return(MakeUniqueNames(importedAssets));
        }
Example #16
0
            private static List <IInlineColliderShapeDesc> CloneDescs(IEnumerable <IInlineColliderShapeDesc> descs)
            {
                var res = new List <IInlineColliderShapeDesc>();

                foreach (var desc in descs)
                {
                    if (desc == null)
                    {
                        res.Add(null);
                    }
                    else
                    {
                        if (desc.GetType() == typeof(ColliderShapeAssetDesc))
                        {
                            var sourceDesc = (ColliderShapeAssetDesc)desc;
                            var assetDesc  = new ColliderShapeAssetDesc
                            {
                                Shape = sourceDesc.Shape
                            };
                            res.Add(assetDesc);
                        }
                        else
                        {
                            var cloned = AssetCloner.Clone(desc, AssetClonerFlags.KeepReferences);
                            res.Add(cloned);
                        }
                    }
                }
                return(res);
            }
Example #17
0
        public void TestMergePropertyContainer()
        {
            var baseDic = new ObjectWithPropertyContainer();

            var newDic = new ObjectWithPropertyContainer();

            var newBaseDic = new ObjectWithPropertyContainer()
            {
                Items = new PropertyContainer()
                {
                    { DiffComponent.Key, new DiffComponent()
                      {
                          Name = "NewComponent"
                      } },
                }
            };

            var diff = new AssetDiff(AssetCloner.Clone(baseDic), newDic, AssetCloner.Clone(newBaseDic))
            {
                UseOverrideMode = true
            };

            var result = AssetMerge.Merge(diff, AssetMergePolicies.MergePolicyAsset2AsNewBaseOfAsset1);

            Assert.False(result.HasErrors);

            Assert.AreEqual(1, newDic.Items.Count);
        }
            protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
            {
                // Reduce trees on CPU
                //var materialReducer = new MaterialTreeReducer(material);
                //materialReducer.ReduceTrees();

                //foreach (var reducedTree in materialReducer.ReducedTrees)
                //{
                //    material.Nodes[reducedTree.Key] = reducedTree.Value;
                //}

                // Reduce on GPU
                // TODO: Use the build engine processed output textures instead of the imported one (not existing any more)
                // TODO: Set the reduced texture output format
                // TODO: The graphics device cannot be shared with the Previewer
                //var graphicsDevice = (GraphicsDevice)context.Attributes.GetOrAdd(CompilerContext.GraphicsDeviceKey, key => GraphicsDevice.New(DeviceCreationFlags.None, GraphicsProfile.Level_11_0));
                //using (var materialTextureLayerFlattener = new MaterialTextureLayerFlattener(material, graphicsDevice))
                //{
                //    materialTextureLayerFlattener.PrepareForFlattening(new UDirectory(assetUrl.Directory));
                //    if (materialTextureLayerFlattener.HasCommands)
                //    {
                //        var compiler = EffectCompileCommand.GetOrCreateEffectCompiler(context);
                //        materialTextureLayerFlattener.Run(compiler);
                //        // store Material with modified textures
                //        material = materialTextureLayerFlattener.Material;
                //    }
                //}

                // TODO: Check with Ben why DoCommandOverride is called without going through the constructor?
                var assetManager    = new ContentManager(MicrothreadLocalDatabases.ProviderService);
                var materialContext = new MaterialGeneratorContext
                {
                    GraphicsProfile = graphicsProfile,
                    Content         = assetManager,
                    ColorSpace      = colorSpace
                };

                materialContext.AddLoadingFromSession(AssetFinder);

                var materialClone = AssetCloner.Clone(Parameters);
                var result        = MaterialGenerator.Generate(new MaterialDescriptor {
                    MaterialId = materialClone.Id, Attributes = materialClone.Attributes, Layers = materialClone.Layers
                }, materialContext, string.Format("{0}:{1}", materialClone.Id, assetUrl));

                if (result.HasErrors)
                {
                    result.CopyTo(commandContext.Logger);
                    return(Task.FromResult(ResultStatus.Failed));
                }

                // Create the parameters
                //var materialParameterCreator = new MaterialParametersCreator(material, assetUrl);
                //if (materialParameterCreator.CreateParameterCollectionData(commandContext.Logger))
                //    return Task.FromResult(ResultStatus.Failed);

                assetManager.Save(assetUrl, result.Material);

                return(Task.FromResult(ResultStatus.Successful));
            }
Example #19
0
        public void TestCloneWithNewIds()
        {
            var originAsset = CreateOriginAsset();
            Dictionary <Guid, Guid> idRemapping;
            var newAsset = AssetCloner.Clone(originAsset, AssetClonerFlags.GenerateNewIdsForIdentifiableObjects, out idRemapping);

            CheckAsset(originAsset, newAsset, idRemapping);
        }
Example #20
0
 public static GameSettingsAsset CloneGameSettingsAsset(this Package package)
 {
     lock (package)
     {
         var gameSettings = package.GetGameSettingsAssetOrDefault();
         return((GameSettingsAsset)AssetCloner.Clone(gameSettings));
     }
 }
Example #21
0
        /// <summary>
        /// Clones a sub-hierarchy of this asset.
        /// </summary>
        /// <param name="sourceRootEntity">The entity that is the root of the sub-hierarchy 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="EntityHierarchyData"/> corresponding to the cloned entities.</returns>
        public EntityHierarchyData CloneSubHierarchy(Guid sourceRootEntity, bool cleanReference, out Dictionary <Guid, Guid> entityMapping)
        {
            if (!Hierarchy.Entities.ContainsKey(sourceRootEntity))
            {
                throw new ArgumentException(@"The source root entity must be an entity of this asset.", nameof(sourceRootEntity));
            }

            // 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.Entities[sourceRootEntity];
            var subTreeHierarchy = new EntityHierarchyData {
                Entities = { subTreeRoot }, RootEntities = { sourceRootEntity }
            };

            foreach (var subTreeEntity in EnumerateChildren(subTreeRoot, true))
            {
                subTreeHierarchy.Entities.Add(Hierarchy.Entities[subTreeEntity.Entity.Id]);
            }

            // clone the entities of the sub-tree
            var clonedHierarchy = (EntityHierarchyData)AssetCloner.Clone(subTreeHierarchy);

            clonedHierarchy.Entities[sourceRootEntity].Entity.Transform.Parent = null;

            if (cleanReference)
            {
                // set to null reference outside of the sub-tree
                EntityAnalysis.FixupEntityReferences(clonedHierarchy);
            }

            // 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.Entities)
            {
                // 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?
            EntityAnalysis.RemapEntitiesId(clonedHierarchy, entityMapping);

            return(clonedHierarchy);
        }
Example #22
0
        public void TestListWithIdsNoConflicts()
        {
            var baseAsset = new TestDiffAsset()
            {
                Name = "Red", Value = 1
            };

            baseAsset.List.Add(new DiffComponent()
            {
                Name = "Test1", Position = new Vector4(1, 0, 0, 0)
            });
            baseAsset.List.Add(new DiffComponent()
            {
                Name = "Test2", Position = new Vector4(1, 0, 0, 0)
            });
            baseAsset.List.Add(new DiffComponent()
            {
                Name = "Test3", Position = new Vector4(1, 0, 0, 0)
            });

            var newBaseAsset = (TestDiffAsset)AssetCloner.Clone(baseAsset);

            var baseItem = new AssetItem("/base", baseAsset);

            var childAsset = (TestDiffAsset)baseItem.CreateChildAsset();

            var diff = new AssetDiff(baseAsset, childAsset, newBaseAsset)
            {
                UseOverrideMode = true
            };

            var diffResult = diff.Compute();

            var diffResultStripped = diffResult.FindLeafDifferences().ToList();

            // Expecting only 2 diff from TestDiffAsset (3 properties + BuildOrder)
            Assert.AreEqual(4, diffResultStripped.Where(item => item.BaseNode.Parent?.Instance is TestDiffAsset).Count());

            // Expecting 6 diffs for DiffComponent (3 elements, 5 properties (Name + Vector4))
            Assert.AreEqual(3 * 5, diffResultStripped.Where(item => item.BaseNode.Parent?.Instance is DiffComponent || item.BaseNode.Parent?.Parent?.Instance is DiffComponent).Count());

            // All changes must be from asset2 (considered as new base), as everything is setting base
            Assert.True(diffResultStripped.All(item => item.ChangeType == Diff3ChangeType.MergeFromAsset2));

            foreach (var node in diffResultStripped.Where(item => item.BaseNode.Parent.Instance is DiffComponent))
            {
                var base1  = (DiffComponent)node.BaseNode.Parent.Instance;
                var asset1 = (DiffComponent)node.Asset1Node.Parent.Instance;
                var asset2 = (DiffComponent)node.Asset2Node.Parent.Instance;

                var baseIndex   = baseAsset.List.IndexOf(base1);
                var asset1Index = childAsset.List.IndexOf(asset1);
                var asset2Index = newBaseAsset.List.IndexOf(asset2);

                Assert.AreEqual(baseIndex, asset1Index);
                Assert.AreEqual(baseIndex, asset2Index);
            }
        }
Example #23
0
        public void TestAssetClonerContent()
        {
            var obj1 = new TestAssetClonerContent {
                Content = new TestContent()
            };
            var obj2 = AssetCloner.Clone(obj1, AssetClonerFlags.KeepReferences);

            Assert.Equal(obj1.Content, obj2.Content);
        }
Example #24
0
        protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, SpriteFontAsset asset, AssetCompilerResult result)
        {
            var colorSpace = context.GetColorSpace();

            if (asset.FontType is SignedDistanceFieldSpriteFontType)
            {
                var fontTypeSDF = asset.FontType as SignedDistanceFieldSpriteFontType;

                // copy the asset and transform the source and character set file path to absolute paths
                var assetClone     = (SpriteFontAsset)AssetCloner.Clone(asset);
                var assetDirectory = assetAbsolutePath.GetParent();
                assetClone.FontSource    = asset.FontSource;
                fontTypeSDF.CharacterSet = !string.IsNullOrEmpty(fontTypeSDF.CharacterSet) ? UPath.Combine(assetDirectory, fontTypeSDF.CharacterSet) : null;

                result.BuildSteps = new AssetBuildStep(AssetItem)
                {
                    new SignedDistanceFieldFontCommand(urlInStorage, assetClone)
                };
            }
            else
            if (asset.FontType is RuntimeRasterizedSpriteFontType)
            {
                UFile fontPathOnDisk;

                fontPathOnDisk = asset.FontSource.GetFontPath();

                var fontImportLocation = FontHelper.GetFontPath(asset.FontSource.GetFontName(), asset.FontSource.Style);

                result.BuildSteps = new AssetBuildStep(AssetItem)
                {
                    new ImportStreamCommand {
                        SourcePath = fontPathOnDisk, Location = fontImportLocation
                    },
                    new RuntimeRasterizedFontCommand(urlInStorage, asset)
                };
            }
            else
            {
                var fontTypeStatic = asset.FontType as OfflineRasterizedSpriteFontType;
                if (fontTypeStatic == null)
                {
                    throw new ArgumentException("Tried to compile a dynamic sprite font with compiler for signed distance field fonts");
                }

                // copy the asset and transform the source and character set file path to absolute paths
                var assetClone     = (SpriteFontAsset)AssetCloner.Clone(asset);
                var assetDirectory = assetAbsolutePath.GetParent();
                assetClone.FontSource       = asset.FontSource;
                fontTypeStatic.CharacterSet = !string.IsNullOrEmpty(fontTypeStatic.CharacterSet) ? UPath.Combine(assetDirectory, fontTypeStatic.CharacterSet): null;

                result.BuildSteps = new AssetBuildStep(AssetItem)
                {
                    new OfflineRasterizedFontCommand(urlInStorage, assetClone, colorSpace)
                };
            }
        }
Example #25
0
        public void TestHash()
        {
            var obj1 = new TestAssetClonerObject
            {
                Name      = "Test1",
                SubObject = new TestAssetClonerObject()
                {
                    Name = "Test2"
                },
                ObjectWithAttachedReference = new TestObjectReference()
            };

            // Create a fake reference to make sure that the attached reference will not be serialized
            var attachedReference = AttachedReferenceManager.GetOrCreateAttachedReference(obj1.ObjectWithAttachedReference);

            attachedReference.Url = "just_for_test";
            attachedReference.Id  = Guid.NewGuid();

            // Setup some proper id on objects so serialization is stable
            IdentifiableHelper.SetId(obj1, new Guid("EC86143E-896F-45C5-9A4D-627317D22955"));
            IdentifiableHelper.SetId(obj1.SubObject, new Guid("34E160CD-1D94-468E-8BFD-F82FF96013FC"));

            var obj2 = (TestAssetClonerObject)AssetCloner.Clone(obj1);

            var hash1 = AssetHash.Compute(obj1);
            var hash2 = AssetHash.Compute(obj2);

            Assert.AreEqual(hash1, hash2);

            obj1.Name = "Yes";
            var hash11 = AssetHash.Compute(obj1);

            Assert.AreNotEqual(hash11, hash2);
            obj1.Name = "Test1";

            var hash12 = AssetHash.Compute(obj1);

            Assert.AreEqual(hash12, hash2);

            // Test the same with overrides
            var objDesc    = TypeDescriptorFactory.Default.Find(typeof(TestAssetClonerObject));
            var memberDesc = objDesc.Members.First(t => t.Name == "Name");

            obj1.SetOverride(memberDesc, OverrideType.New);
            obj1.SubObject.SetOverride(memberDesc, OverrideType.Sealed);

            obj2 = (TestAssetClonerObject)AssetCloner.Clone(obj1);

            var hash1WithOverrides = AssetHash.Compute(obj1);
            var hash2WithOverrides = AssetHash.Compute(obj2);

            Assert.AreNotEqual(hash1, hash1WithOverrides);
            Assert.AreNotEqual(hash2, hash2WithOverrides);
            Assert.AreEqual(hash1WithOverrides, hash2WithOverrides);
        }
Example #26
0
        /// <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);
        }
Example #27
0
        protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, SpriteFontAsset asset, AssetCompilerResult result)
        {
            var colorSpace = context.GetColorSpace();

            if (asset.IsDynamic)
            {
                UFile fontPathOnDisk;

                if (!string.IsNullOrEmpty(asset.Source))
                {
                    var assetDirectory = assetAbsolutePath.GetParent();
                    fontPathOnDisk = UPath.Combine(assetDirectory, asset.Source);
                    if (!File.Exists(fontPathOnDisk))
                    {
                        result.Error("The font source '{0}' does not exist on the PC.", asset.FontName);
                        return;
                    }
                    // set the source filename as font name instead of the font family.
                    asset.FontName = fontPathOnDisk.GetFileName();
                }
                else
                {
                    fontPathOnDisk = GetFontPath(asset, result);
                    if (fontPathOnDisk == null)
                    {
                        result.Error("The font named '{0}' could not be located on the PC.", asset.FontName);
                        return;
                    }
                }
                var fontImportLocation = FontHelper.GetFontPath(asset.FontName, asset.Style);

                result.BuildSteps = new AssetBuildStep(AssetItem)
                {
                    new ImportStreamCommand {
                        SourcePath = fontPathOnDisk, Location = fontImportLocation
                    },
                    new DynamicFontCommand(urlInStorage, asset)
                };
            }
            else
            {
                // copy the asset and transform the source and character set file path to absolute paths
                var assetClone     = (SpriteFontAsset)AssetCloner.Clone(asset);
                var assetDirectory = assetAbsolutePath.GetParent();
                assetClone.Source       = !string.IsNullOrEmpty(asset.Source) ? UPath.Combine(assetDirectory, asset.Source): null;
                assetClone.CharacterSet = !string.IsNullOrEmpty(asset.CharacterSet) ? UPath.Combine(assetDirectory, asset.CharacterSet): null;

                result.BuildSteps = new AssetBuildStep(AssetItem)
                {
                    new StaticFontCommand(urlInStorage, assetClone, colorSpace)
                };
            }
        }
Example #28
0
 /// <summary>
 /// Merges the specified assets from <c>base</c> and <c>from2</c> into <c>from1</c>.
 /// </summary>
 /// <param name="assetBase">The asset base.</param>
 /// <param name="assetFrom1">The asset from1.</param>
 /// <param name="assetFrom2">The asset from2.</param>
 /// <param name="mergePolicy">The merge policy. See <see cref="AssetMergePolicies" /> for default policies.</param>
 /// <returns>The result of the merge.</returns>
 /// <exception cref="System.ArgumentNullException">
 /// assetFrom1
 /// or
 /// mergePolicy
 /// </exception>
 public static MergeResult Merge(Asset assetBase, Asset assetFrom1, Asset assetFrom2, MergePolicyDelegate mergePolicy)
 {
     if (assetFrom1 == null)
     {
         throw new ArgumentNullException("assetFrom1");
     }
     if (mergePolicy == null)
     {
         throw new ArgumentNullException("mergePolicy");
     }
     return(Merge(new AssetDiff((Asset)AssetCloner.Clone(assetBase), (Asset)AssetCloner.Clone(assetFrom1), (Asset)AssetCloner.Clone(assetFrom2)), mergePolicy));
 }
            private void EnsureClonedSceneAndHash()
            {
                if (!sceneCloned)
                {
                    // Hash relevant scene objects
                    if (asset.Scene != null)
                    {
                        string sceneUrl   = AttachedReferenceManager.GetUrl(asset.Scene);
                        var    sceneAsset = (SceneAsset)package.Session.FindAsset(sceneUrl)?.Asset;

                        // Clone scene asset because we update the world transformation matrices
                        clonedSceneAsset = (SceneAsset)AssetCloner.Clone(sceneAsset);

                        // Turn the entire entity hierarchy into a single list
                        sceneEntities = clonedSceneAsset.Hierarchy.Parts.Select(x => x.Entity).ToList();

                        sceneHash = 0;
                        foreach (var entity in sceneEntities)
                        {
                            StaticColliderComponent collider = entity.Get <StaticColliderComponent>();

                            // Only process enabled colliders
                            bool colliderEnabled = collider != null && ((CollisionFilterGroupFlags)collider.CollisionGroup & asset.IncludedCollisionGroups) != 0 && collider.Enabled;
                            if (colliderEnabled) // Removed or disabled
                            {
                                // Update world transform before hashing
                                entity.Transform.UpdateWorldMatrix();

                                // Load collider shape assets since the scene asset is being used, which does not have these loaded by default
                                foreach (var desc in collider.ColliderShapes)
                                {
                                    var shapeAssetDesc = desc as ColliderShapeAssetDesc;
                                    if (shapeAssetDesc?.Shape != null)
                                    {
                                        var assetReference = AttachedReferenceManager.GetAttachedReference(shapeAssetDesc.Shape);
                                        PhysicsColliderShape loadedColliderShape;
                                        if (!loadedColliderShapes.TryGetValue(assetReference.Url, out loadedColliderShape))
                                        {
                                            loadedColliderShape = contentManager.Load <PhysicsColliderShape>(assetReference.Url);
                                            loadedColliderShapes.Add(assetReference.Url, loadedColliderShape); // Store where we loaded the shapes from
                                        }
                                        shapeAssetDesc.Shape = loadedColliderShape;
                                    }
                                }

                                // Finally compute the hash for this collider
                                sceneHash += NavigationMeshBuildUtils.HashEntityCollider(collider);
                            }
                        }
                    }
                    sceneCloned = true;
                }
            }
Example #30
0
        public void TestListWithIdsChangeType()
        {
            var baseAsset = new TestDiffAsset()
            {
                Name = "Red", Value = 1
            };

            baseAsset.List.Add(new DiffComponent()
            {
                Name = "Test1", Position = new Vector4(1, 0, 0, 0)
            });
            baseAsset.List.Add(new DiffComponent()
            {
                Name = "Test2", Position = new Vector4(1, 0, 0, 0)
            });
            baseAsset.List.Add(new DiffComponent()
            {
                Name = "Test3", Position = new Vector4(1, 0, 0, 0)
            });

            // Change type of 2nd element in newBase list
            var newBaseAsset = (TestDiffAsset)AssetCloner.Clone(baseAsset);

            newBaseAsset.List[1] = new DiffComponentSub()
            {
                Value = 1
            };

            var baseItem = new AssetItem("/base", baseAsset);

            var childAsset = (TestDiffAsset)baseItem.CreateChildAsset();

            var diff = new AssetDiff(baseAsset, childAsset, newBaseAsset)
            {
                UseOverrideMode = true
            };
            var diffResult = diff.Compute();

            var diffList = diffResult.Members.First(node => ((DataVisitMember)node.Asset1Node).MemberDescriptor.Name == "List");

            // Check that we have only 3 items
            Assert.AreEqual(3, diffList.Items.Count);
            Assert.AreEqual(Diff3ChangeType.MergeFromAsset2, diffList.Items[1].ChangeType);

            var mergeResult = AssetMerge.Merge(diff, AssetMergePolicies.MergePolicyAsset2AsNewBaseOfAsset1);

            Assert.False(mergeResult.HasErrors);

            Assert.AreEqual(3, childAsset.List.Count);
            Assert.AreEqual("Test1", childAsset.List[0].Name);
            Assert.True(childAsset.List[1] is DiffComponentSub);
            Assert.AreEqual("Test3", childAsset.List[2].Name);
        }