protected override void Compile(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var asset = (SkeletonAsset)assetItem.Asset; var assetSource = GetAbsolutePath(assetItem, asset.Source); var extension = assetSource.GetFileExtension(); var buildStep = new AssetBuildStep(assetItem); var importModelCommand = ImportModelCommand.Create(extension); if (importModelCommand == null) { result.Error("No importer found for model extension '{0}. The model '{1}' can't be imported.", extension, assetSource); return; } importModelCommand.SourcePath = assetSource; importModelCommand.Location = targetUrlInStorage; importModelCommand.Mode = ImportModelCommand.ExportMode.Skeleton; importModelCommand.ScaleImport = asset.ScaleImport; importModelCommand.PivotPosition = asset.PivotPosition; importModelCommand.SkeletonNodesWithPreserveInfo = asset.NodesWithPreserveInfo; buildStep.Add(importModelCommand); result.BuildSteps = buildStep; }
/// <inheritdoc/> public AssetCompilerResult Compile(CompilerContext context, AssetItem assetItem) { if (context == null) throw new ArgumentNullException("context"); if (assetItem == null) throw new ArgumentNullException("assetItem"); assetItem = assetItem.Package.Session.DependencyManager.FindDependencySet(assetItem.Id).Item; var compilerResult = new AssetCompilerResult(); if (assetItem.Package == null) { compilerResult.Warning("Asset [{0}] is not attached to a package", assetItem); return compilerResult; } var assetCompilerContext = (AssetCompilerContext)context; // create the a package that contains only the asset and its the dependencies var dependenciesCompilePackage = assetItem.Package.Session.CreateCompilePackageFromAsset(assetItem); assetCompilerContext.Package = dependenciesCompilePackage.LocalPackages.FirstOrDefault(); var clonedAsset = dependenciesCompilePackage.FindAsset(assetItem.Id); CompileWithDependencies(assetCompilerContext, clonedAsset, assetItem, compilerResult); return compilerResult; }
/// <summary> /// Ensures that the sources of an <see cref="Asset"/> exist. /// </summary> /// <param name="result">The <see cref="AssetCompilerResult"/> in which to output log of potential errors.</param> /// <param name="assetItem">The asset to check.</param> /// <returns><c>true</c> if the source file exists, <c>false</c> otherwise.</returns> /// <exception cref="ArgumentNullException">Any of the argument is <c>null</c>.</exception> private static bool EnsureSourcesExist(AssetCompilerResult result, AssetItem assetItem) { if (result == null) throw new ArgumentNullException(nameof(result)); if (assetItem == null) throw new ArgumentNullException(nameof(assetItem)); var collector = new SourceFilesCollector(); var sourceMembers = collector.GetSourceMembers(assetItem.Asset); foreach (var member in sourceMembers) { if (string.IsNullOrEmpty(member.Value)) { result.Error($"Source is null for Asset [{assetItem}] in property [{member.Key}]"); return false; } // Get absolute path of asset source on disk var assetDirectory = assetItem.FullPath.GetParent(); var assetSource = UPath.Combine(assetDirectory, member.Value); // Ensure the file exists if (!File.Exists(assetSource)) { result.Error($"Unable to find the source file '{assetSource}' for Asset [{assetItem}]"); return false; } } return true; }
/// <inheritdoc/> public AssetCompilerResult Compile(CompilerContext context, AssetItem assetItem) { if (context == null) throw new ArgumentNullException("context"); if (assetItem == null) throw new ArgumentNullException("assetItem"); var compilerResult = new AssetCompilerResult(); if (assetItem.Package == null) { compilerResult.Warning("Asset [{0}] is not attached to a package", assetItem); return compilerResult; } var assetCompilerContext = (AssetCompilerContext)context; // create the a package that contains only the asset and its the dependencies var dependenciesCompilePackage = assetItem.Package.Session.CreateCompilePackageFromAsset(assetItem); var clonedAsset = dependenciesCompilePackage.FindAsset(assetItem.Id); CompileWithDependencies(assetCompilerContext, clonedAsset, assetItem, compilerResult); // Check unloadable items foreach (var currentAssetItem in dependenciesCompilePackage.Assets) { var unloadableItems = UnloadableObjectRemover.Run(currentAssetItem.Asset); foreach (var unloadableItem in unloadableItems) { compilerResult.Log(new AssetLogMessage(dependenciesCompilePackage, currentAssetItem.ToReference(), LogMessageType.Warning, $"Unable to load the object of type {unloadableItem.UnloadableObject.TypeName} which is located at [{unloadableItem.MemberPath}] in the asset")); } } // Find AssetBuildStep var assetBuildSteps = new Dictionary<AssetId, AssetBuildStep>(); foreach (var step in compilerResult.BuildSteps.EnumerateRecursively()) { var assetStep = step as AssetBuildStep; if (assetStep != null) { assetBuildSteps[assetStep.AssetItem.Id] = assetStep; } } // TODO: Refactor logging of CompilerApp and BuildEngine // Copy log top-level to proper asset build steps foreach (var message in compilerResult.Messages) { var assetMessage = message as AssetLogMessage; // Find asset (if nothing found, default to main asset) var assetId = assetMessage?.AssetReference.Id ?? assetItem.Id; AssetBuildStep assetBuildStep; if (assetBuildSteps.TryGetValue(assetId, out assetBuildStep)) { // Log to AssetBuildStep assetBuildStep.Logger?.Log(message); } } return compilerResult; }
public AssetCompilerResult Compile(CompilerContext context, AssetItem assetItem) { if (context == null) throw new ArgumentNullException(nameof(context)); if (assetItem == null) throw new ArgumentNullException(nameof(assetItem)); var result = new AssetCompilerResult(GetType().Name) { BuildSteps = new AssetBuildStep(assetItem) }; // Only use the path to the asset without its extension var fullPath = assetItem.FullPath; if (!fullPath.IsAbsolute) { throw new InvalidOperationException("assetItem must be an absolute path"); } // Try to compile only if we're sure that the sources exist. if (EnsureSourcesExist(result, assetItem)) { Compile((AssetCompilerContext)context, assetItem, assetItem.Location.GetDirectoryAndFileName(), result); } return result; }
protected override void Compile(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var asset = (EffectLogAsset)assetItem.Asset; var originalSourcePath = assetItem.FullPath; result.ShouldWaitForPreviousBuilds = true; result.BuildSteps = new AssetBuildStep(assetItem) { new EffectLogBuildStep(context, originalSourcePath, assetItem) }; }
/// <summary> /// Constructs an <see cref="AssetCompiledArgs"/> instance. /// </summary> /// <param name="asset">The asset that has been compiled. Cannot be null.</param> /// <param name="result">The result of the asset compilation. Cannot be null.</param> public AssetCompiledArgs(AssetItem asset, AssetCompilerResult result) { if (asset == null) throw new ArgumentNullException("asset"); if (result == null) throw new ArgumentNullException("result"); Asset = asset; Result = result; }
/// <summary> /// Compile the current package session. /// That is generate the list of build steps to execute to create the package assets. /// </summary> public AssetCompilerResult Compile(AssetCompilerContext compilerContext) { if (compilerContext == null) throw new ArgumentNullException("compilerContext"); var result = new AssetCompilerResult(); var assets = packageCompilerSource.GetAssets(result).ToList(); if (result.HasErrors) { return result; } var defaultAssetsCompiler = new DefaultAssetsCompiler(assets); defaultAssetsCompiler.AssetCompiled += OnAssetCompiled; // Add default compilers compilers.Clear(); compilers.Add(defaultAssetsCompiler); // Compile using all PackageCompiler foreach (var compiler in compilers) { var compilerResult = compiler.Compile(compilerContext); compilerResult.CopyTo(result); while (compilerResult.BuildSteps.Count > 0) { var step = compilerResult.BuildSteps[0]; compilerResult.BuildSteps.RemoveAt(0); result.BuildSteps.Add(step); } } return result; }
/// <inheritdoc/> public override string GetFontPath(AssetCompilerResult result = null) { if (!File.Exists(Source)) { result?.Error("Cannot find font file '{0}'. Make sure it exists and is referenced correctly.", Source); } return Source; }
/// <summary> /// Compile the required build steps necessary to produce the desired outputs items. /// </summary> /// <param name="context">The context source.</param> /// <param name="assetItems">The list of items to compile</param> /// <param name="compilationResult">The current compilation result, containing the build steps and the logging</param> protected void Compile(CompilerContext context, IEnumerable<AssetItem> assetItems, AssetCompilerResult compilationResult) { foreach (var assetItem in assetItems) { var itemBuildStep = CompileItem(context, compilationResult, assetItem); if (itemBuildStep != null) compilationResult.BuildSteps.Add(itemBuildStep); } }
protected override void Compile(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var url = EffectCompilerBase.DefaultSourceShaderFolder + "/" + Path.GetFileName(assetItem.FullPath); var asset = (EffectShaderAsset)assetItem.Asset; var originalSourcePath = assetItem.FullPath; result.BuildSteps = new AssetBuildStep(assetItem) { new ImportStreamCommand { SourcePath = originalSourcePath, Location = url, SaveSourcePath = true } }; var shaderLocations = (ConcurrentDictionary<string, string>)context.Properties.GetOrAdd(ShaderLocationsKey, key => new ConcurrentDictionary<string, string>()); // Store directly this into the context TODO this this temporary shaderLocations[url] = originalSourcePath; }
/// <summary> /// Compiles the package contained in the given context and add the resulting build steps in the <see cref="AssetCompilerResult"/> /// </summary> /// <param name="context">The context which contains the package to compile.</param> /// <param name="result">The <see cref="AssetCompilerResult"/> where the build steps will be added.</param> /// <returns></returns> protected static BuildStep CompilePackage(AssetCompilerContext context, AssetCompilerResult result) { // compile the fake package (create the build steps) var assetPackageCompiler = new PackageCompiler(); var dependenciesCompileResult = assetPackageCompiler.Compile(context); // Create the result build steps if not existing yet if (result.BuildSteps == null) result.BuildSteps = new ListBuildStep(); // Add the dependencies build steps to the current result result.BuildSteps.Add(dependenciesCompileResult.BuildSteps); // Copy log the dependencies result to the current result dependenciesCompileResult.CopyTo(result); return dependenciesCompileResult.BuildSteps; }
/// <inheritdoc/> public IEnumerable<AssetItem> GetAssets(AssetCompilerResult assetCompilerResult) { // Check integrity of the packages var packageAnalysis = new PackageSessionAnalysis(package.Session, new PackageAnalysisParameters()); packageAnalysis.Run(assetCompilerResult); if (assetCompilerResult.HasErrors) { return Enumerable.Empty<AssetItem>(); } // Compute list of assets to compile and their dependencies var packagesProcessed = new HashSet<Package>(); var assetsReferenced = new HashSet<AssetItem>(); CollectReferences(package, assetsReferenced, packagesProcessed); var assets = assetsReferenced.ToList(); assets.Sort((item1, item2) => item1.Asset != null && item2.Asset != null ? item1.Asset.InternalBuildOrder.CompareTo(item2.Asset.InternalBuildOrder) : 0); return assets; }
/// <summary> /// Ensures that the sources of an <see cref="Asset"/> exist. /// </summary> /// <param name="result">The <see cref="AssetCompilerResult"/> in which to output log of potential errors.</param> /// <param name="asset">The asset to check.</param> /// <param name="assetAbsolutePath">The absolute path of the asset on the disk</param> /// <returns><c>true</c> if the source file exists, <c>false</c> otherwise.</returns> /// <exception cref="ArgumentNullException">Any of the argument is <c>null</c>.</exception> protected static bool EnsureSourcesExist(AssetCompilerResult result, T asset, UFile assetAbsolutePath) { if (result == null) { throw new ArgumentNullException(nameof(result)); } if (asset == null) { throw new ArgumentNullException(nameof(asset)); } if (assetAbsolutePath == null) { throw new ArgumentNullException(nameof(assetAbsolutePath)); } var collector = new SourceFilesCollector(); var sourceMembers = collector.GetSourceMembers(asset); foreach (var member in sourceMembers) { if (string.IsNullOrEmpty(member.Value)) { result.Error($"Source is null for Asset [{asset}] in property [{member.Key}]"); return(false); } // Get absolute path of asset source on disk var assetDirectory = assetAbsolutePath.GetParent(); var assetSource = UPath.Combine(assetDirectory, member.Value); // Ensure the file exists if (!File.Exists(assetSource)) { result.Error($"Unable to find the source file '{assetSource}' for Asset [{asset}]"); return(false); } } return(true); }
public virtual AssetCompilerResult Compile(CompilerContext context, AssetItem assetItem) { if (context == null) { throw new ArgumentNullException("context"); } if (assetItem == null) { throw new ArgumentNullException("assetItem"); } Asset = (T)assetItem.Asset; AssetItem = assetItem; // TODO: This can critically fail if the asset item has been removed from its package - find a way to prevent exceptions here and in usages of AssetsSession AssetsSession = AssetItem.Package.Session; var compilerResult = new AssetCompilerResult(); CompileOverride((AssetCompilerContext)context, compilerResult); return(compilerResult); }
/// <summary> /// Compile the current package session. /// That is generate the list of build steps to execute to create the package assets. /// </summary> public AssetCompilerResult Compile(AssetCompilerContext compilerContext) { if (compilerContext == null) { throw new ArgumentNullException("compilerContext"); } var result = new AssetCompilerResult(); var assets = packageCompilerSource.GetAssets(result).ToList(); if (result.HasErrors) { return(result); } var defaultAssetsCompiler = new DefaultAssetsCompiler(assets); defaultAssetsCompiler.AssetCompiled += OnAssetCompiled; // Add default compilers compilers.Clear(); compilers.Add(defaultAssetsCompiler); // Compile using all PackageCompiler foreach (var compiler in compilers) { var compilerResult = compiler.Compile(compilerContext); compilerResult.CopyTo(result); while (compilerResult.BuildSteps.Count > 0) { var step = compilerResult.BuildSteps[0]; compilerResult.BuildSteps.RemoveAt(0); result.BuildSteps.Add(step); } } return(result); }
/// <inheritdoc/> public IEnumerable <AssetItem> GetAssets(AssetCompilerResult assetCompilerResult) { // Check integrity of the packages var packageAnalysis = new PackageSessionAnalysis(rootPackage.Session, new PackageAnalysisParameters()); packageAnalysis.Run(assetCompilerResult); if (assetCompilerResult.HasErrors) { yield break; } // Compute list of assets to compile and their dependencies var packagesProcessed = new HashSet <Package>(); var assetsReferenced = new HashSet <AssetItem>(); CollectReferences(rootPackage, assetsReferenced, packagesProcessed); foreach (var assetItem in assetsReferenced) { yield return(assetItem); } }
public sealed override AssetCompilerResult Compile(CompilerContext context, AssetItem assetItem) { // This method is overriden only because of the issue in assignment of the AssetsSession property in the base method. // In this implementation, the assignment is deferred in the try/catch block of the CompileOverride method. // TODO: Remove this override once the issue in the bas method is fixed (and seal the base method if possible) if (context == null) { throw new ArgumentNullException("context"); } if (assetItem == null) { throw new ArgumentNullException("assetItem"); } Asset = (T)assetItem.Asset; AssetItem = assetItem; var compilerResult = new AssetCompilerResult(); CompileOverride((AssetCompilerContext)context, compilerResult); return(compilerResult); }
public override string GetFontPath(AssetCompilerResult result = null) { using (var factory = new Factory()) { Font font; using (var fontCollection = factory.GetSystemFontCollection(false)) { int index; if (!fontCollection.FindFamilyName(FontName, out index)) { result?.Error("Cannot find system font '{0}'. Make sure it is installed on this machine.", FontName); return null; } using (var fontFamily = fontCollection.GetFontFamily(index)) { var weight = Style.IsBold() ? FontWeight.Bold : FontWeight.Regular; var style = Style.IsItalic() ? SharpDX.DirectWrite.FontStyle.Italic : SharpDX.DirectWrite.FontStyle.Normal; font = fontFamily.GetFirstMatchingFont(weight, FontStretch.Normal, style); if (font == null) { result?.Error("Cannot find style '{0}' for font family {1}. Make sure it is installed on this machine.", Style, FontName); return null; } } } var fontFace = new FontFace(font); // get the font path on the hard drive var file = fontFace.GetFiles().First(); var referenceKey = file.GetReferenceKey(); var originalLoader = (FontFileLoaderNative)file.Loader; var loader = originalLoader.QueryInterface<LocalFontFileLoader>(); return loader.GetFilePath(referenceKey); } }
/// <inheritdoc/> public AssetCompilerResult Compile(CompilerContext context, AssetItem assetItem) { if (context == null) { throw new ArgumentNullException("context"); } if (assetItem == null) { throw new ArgumentNullException("assetItem"); } var compilerResult = new AssetCompilerResult(); var dependencySet = assetItem.Package.Session.DependencyManager.FindDependencySet(assetItem.Id); if (dependencySet == null) { compilerResult.Warning("Could not find dependency for asset [{0}]", assetItem); return(compilerResult); } assetItem = dependencySet.Item; if (assetItem.Package == null) { compilerResult.Warning("Asset [{0}] is not attached to a package", assetItem); return(compilerResult); } var assetCompilerContext = (AssetCompilerContext)context; // create the a package that contains only the asset and its the dependencies var dependenciesCompilePackage = assetItem.Package.Session.CreateCompilePackageFromAsset(assetItem); var clonedAsset = dependenciesCompilePackage.FindAsset(assetItem.Id); CompileWithDependencies(assetCompilerContext, clonedAsset, assetItem, compilerResult); return(compilerResult); }
/// <inheritdoc/> public IEnumerable <AssetItem> GetAssets(AssetCompilerResult assetCompilerResult) { // Check integrity of the packages var packageAnalysis = new PackageSessionAnalysis(package.Session, new PackageAnalysisParameters()); packageAnalysis.Run(assetCompilerResult); if (assetCompilerResult.HasErrors) { return(Enumerable.Empty <AssetItem>()); } // Compute list of assets to compile and their dependencies var packagesProcessed = new HashSet <Package>(); var assetsReferenced = new HashSet <AssetItem>(); CollectReferences(package, assetsReferenced, packagesProcessed); var assets = assetsReferenced.ToList(); assets.Sort((item1, item2) => item1.Asset != null && item2.Asset != null ? item1.Asset.InternalBuildOrder.CompareTo(item2.Asset.InternalBuildOrder) : 0); return(assets); }
protected override void Compile(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result) { var asset = (ModelAsset)assetItem.Asset; // Get absolute path of asset source on disk var assetDirectory = assetItem.FullPath.GetParent(); var assetSource = UPath.Combine(assetDirectory, asset.Source); var gameSettingsAsset = context.GetGameSettingsAsset(); var renderingSettings = gameSettingsAsset.Get<RenderingSettings>(); var allow32BitIndex = renderingSettings.DefaultGraphicsProfile >= GraphicsProfile.Level_9_2; var allowUnsignedBlendIndices = context.GetGraphicsPlatform(assetItem.Package) != GraphicsPlatform.OpenGLES; var extension = asset.Source.GetFileExtension(); // Find skeleton asset, if any AssetItem skeleton = null; if (asset.Skeleton != null) skeleton = assetItem.Package.FindAssetFromAttachedReference(asset.Skeleton); var importModelCommand = ImportModelCommand.Create(extension); if (importModelCommand == null) { result.Error("No importer found for model extension '{0}. The model '{1}' can't be imported.", extension, assetSource); return; } importModelCommand.Mode = ImportModelCommand.ExportMode.Model; importModelCommand.SourcePath = assetSource; importModelCommand.Location = targetUrlInStorage; importModelCommand.Allow32BitIndex = allow32BitIndex; importModelCommand.AllowUnsignedBlendIndices = allowUnsignedBlendIndices; importModelCommand.Materials = asset.Materials; importModelCommand.ScaleImport = asset.ScaleImport; importModelCommand.PivotPosition = asset.PivotPosition; importModelCommand.SkeletonUrl = skeleton?.Location; result.BuildSteps = new AssetBuildStep(assetItem) { importModelCommand }; }
/// <inheritdoc/> public IEnumerable<AssetItem> GetAssets(AssetCompilerResult assetCompilerResult) { // Check integrity of the packages var packageAnalysis = new PackageSessionAnalysis(package.Session, new PackageAnalysisParameters()); packageAnalysis.Run(assetCompilerResult); if (assetCompilerResult.HasErrors) { return Enumerable.Empty<AssetItem>(); } // Get the dependencies (in reverse order so that we start depth first) // TODO: result.Error("Unable to find package [{0}]", packageDependency); < when resolving dependencies // TODO: result.Info("Compiling package [{0}]", package.FullPath); < probably doesn't make sense anymore var packages = package.GetPackagesWithRecursiveDependencies().Reverse(); // For each package, list assets and sort by build order return packages.SelectMany(x => { var packageAssets = x.Assets.ToList(); // Sort the items to build by build order packageAssets.Sort((item1, item2) => item1.Asset != null && item2.Asset != null ? item1.Asset.InternalBuildOrder.CompareTo(item2.Asset.InternalBuildOrder) : 0); return packageAssets; }).ToList(); }
/// <summary> /// Compile the current package session. /// That is generate the list of build steps to execute to create the package assets. /// </summary> public AssetCompilerResult Compile(AssetCompilerContext compilerContext) { if (compilerContext == null) throw new ArgumentNullException("compilerContext"); if (compilerContext.Package == null) { throw new ArgumentException("Expecting a non null package", "compilerContext"); } if (compilerContext.Package.Session == null) { throw new ArgumentException("Expecting a package attached to a session", "compilerContext"); } var result = new AssetCompilerResult(); // Check integrity of the packages var packageAnalysis = new PackageSessionAnalysis(compilerContext.Package.Session, new PackageAnalysisParameters()); packageAnalysis.Run(result); if (result.HasErrors) { return result; } // Add default compilers compilers.Clear(); var defaultAssetsCompiler = new DefaultAssetsCompiler(); defaultAssetsCompiler.AssetCompiled += OnAssetCompiled; compilers.Add(defaultAssetsCompiler); var packagesProcessed = new HashSet<Package>(); RecursiveCompile(result, compilerContext, packagesProcessed); return result; }
/// <summary> /// Gets the actual file path to the font file /// </summary> /// <returns>Path to the font file</returns> public abstract string GetFontPath(AssetCompilerResult result = null);
/// <summary> /// Compile the required build step necessary to produce the desired output item. /// </summary> /// <param name="context">The context.</param> /// <param name="compilationResult">The compilation result.</param> /// <param name="assetItem">The asset item.</param> protected ListBuildStep CompileItem(CompilerContext context, AssetCompilerResult compilationResult, AssetItem assetItem) { // First try to find an asset compiler for this particular asset. IAssetCompiler compiler; try { compiler = compilerRegistry.GetCompiler(assetItem.Asset.GetType()); } catch (Exception ex) { compilationResult.Error("Cannot find a compiler for asset [{0}] from path [{1}]", ex, assetItem.Id, assetItem.Location); return null; } if (compiler == null) { return null; } // Second we are compiling the asset (generating a build step) try { var resultPerAssetType = compiler.Compile(context, assetItem); // Raise the AssetCompiled event. var handler = AssetCompiled; if (handler != null) handler(this, new AssetCompiledArgs(assetItem, resultPerAssetType)); // TODO: See if this can be unified with PackageBuilder.BuildStepProcessed foreach (var message in resultPerAssetType.Messages) { var assetMessage = new AssetLogMessage(null, assetItem.ToReference(), message.Type, AssetMessageCode.CompilationMessage, assetItem.Location, message.Text) { Exception = message is LogMessage ? ((LogMessage)message).Exception : null }; // Forward log messages to compilationResult compilationResult.Log(assetMessage); // Forward log messages to build step logger resultPerAssetType.BuildSteps.Logger.Log(assetMessage); } // Make the build step fail if there was an error during compiling (only when we are compiling the build steps of an asset) if (resultPerAssetType.BuildSteps is AssetBuildStep && resultPerAssetType.BuildSteps.Logger.HasErrors) resultPerAssetType.BuildSteps.Add(new CommandBuildStep(new FailedCommand(assetItem.Location))); // Build the module string var assetAbsolutePath = assetItem.FullPath; assetAbsolutePath = Path.GetFullPath(assetAbsolutePath); var module = string.Format("{0}(1,1)", assetAbsolutePath); // Assign module string to all command build steps SetModule(resultPerAssetType.BuildSteps, module); // Add a wait command to the build steps if required by the item build if (resultPerAssetType.ShouldWaitForPreviousBuilds) compilationResult.BuildSteps.Add(new WaitBuildStep()); foreach (var buildStep in resultPerAssetType.BuildSteps) { buildStep.Priority = latestPriority++; } // Add the item result build steps the item list result build steps return resultPerAssetType.BuildSteps; } catch (Exception ex) { compilationResult.Error("Unexpected exception while compiling asset [{0}] from path [{1}]", ex, assetItem.Id, assetItem.Location); return null; } }
/// <summary> /// Compiles the asset from the specified package. /// </summary> /// <param name="context">The context to use to compile the asset.</param> /// <param name="assetItem">The asset to compile</param> /// <param name="targetUrlInStorage">The absolute URL to the asset, relative to the storage.</param> /// <param name="result">The result where the commands and logs should be output.</param> protected abstract void Prepare(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result);
/// <summary> /// Compile the current package and all child package recursively by generating a list of build steps /// </summary> private void RecursiveCompile(AssetCompilerResult result, AssetCompilerContext context, HashSet <Package> processed) { if (result == null) { throw new ArgumentNullException("result"); } if (context == null) { throw new ArgumentNullException("context"); } if (context.Package == null) { throw new ArgumentException("context.Package cannot be null", "context"); } if (processed.Contains(context.Package)) { return; } processed.Add(context.Package); var package = context.Package; var session = package.Session; // 1. first recursively process all store packages foreach (var packageDependency in package.Meta.Dependencies) { var subPackage = session.Packages.Find(packageDependency); if (subPackage != null) { // Work on an immutable copy for the whole set of assets to compile var contextCopy = (AssetCompilerContext)context.Clone(); contextCopy.Package = subPackage; RecursiveCompile(result, contextCopy, processed); } else { result.Error("Unable to find package [{0}]", packageDependency); } } // 2. recursively process all local packages foreach (var subPackageReference in package.LocalDependencies) { var subPackage = session.Packages.Find(subPackageReference.Id); if (subPackage != null) { // Work on an immutable copy for the whole set of assets to compile var contextCopy = (AssetCompilerContext)context.Clone(); contextCopy.Package = subPackage; RecursiveCompile(result, contextCopy, processed); } else { result.Error("Unable to find package [{0}]", subPackageReference); } } result.Info("Compiling package [{0}]", package.FullPath); // Compile using all PackageCompiler foreach (var compiler in compilers) { var compilerResult = compiler.Compile(context); compilerResult.CopyTo(result); while (compilerResult.BuildSteps.Count > 0) { var step = compilerResult.BuildSteps[0]; compilerResult.BuildSteps.RemoveAt(0); result.BuildSteps.Add(step); } } }
/// <summary> /// Compiles the asset from the specified package. /// </summary> /// <param name="context">The context to use to compile the asset.</param> /// <param name="assetItem">The asset to compile</param> /// <param name="targetUrlInStorage">The absolute URL to the asset, relative to the storage.</param> /// <param name="result">The result where the commands and logs should be output.</param> protected abstract void Compile(AssetCompilerContext context, AssetItem assetItem, string targetUrlInStorage, AssetCompilerResult result);
/// <summary> /// Compiles the given asset with its dependencies. /// </summary> /// <param name="context">The asset compiler context.</param> /// <param name="assetItem">The asset to compile with its dependencies.</param> /// <param name="originalItem"></param> /// <param name="compilationResult">The result of the compilation.</param> protected virtual void CompileWithDependencies(AssetCompilerContext context, AssetItem assetItem, AssetItem originalItem, AssetCompilerResult compilationResult) { CompilePackage(context, assetItem.Package, compilationResult); }
protected sealed override AssetCompilerResult CompileOverride(AssetCompilerContext context, AssetCompilerResult compilerResult) { var thumbnailCompilerContext = (ThumbnailCompilerContext)context; // Build the path of the thumbnail in the storage var assetStorageUrl = AssetItem.Location.GetDirectoryAndFileName(); var thumbnailStorageUrl = assetStorageUrl.Insert(0, "__THUMBNAIL__"); try { // TODO: fix failures here (see TODOs in Compile and base.Compile) AssetsSession = AssetItem.Package.Session; // Only use the path to the asset without its extension Compile(thumbnailCompilerContext, thumbnailStorageUrl, AssetItem.FullPath, compilerResult); } catch (Exception) { // If an exception occurs, ensure that the build of thumbnail will fail. compilerResult.BuildSteps = null; } if (compilerResult.BuildSteps == null || compilerResult.HasErrors) { // if a problem occurs while compiling, we don't want to enqueue null because it would mean // that there is no thumbnail to build, which is incorrect. So we return a special build step // that will always fail. If we don't, some asset ids will never be removed from the in progress // list and thus never be updated again. compilerResult.BuildSteps = new ListBuildStep { new ThumbnailFailureBuildStep() }; } var currentAsset = AssetItem; // copy the current asset item and embrace it in the callback compilerResult.BuildSteps.StepProcessed += (_, buildStepArgs) => OnThumbnailStepProcessed(thumbnailCompilerContext, currentAsset, thumbnailStorageUrl, buildStepArgs); return(compilerResult); }
/// <summary> /// Compile the current package and all child package recursively by generating a list of build steps /// </summary> private void RecursiveCompile(AssetCompilerResult result, AssetCompilerContext context, HashSet<Package> processed) { if (result == null) throw new ArgumentNullException("result"); if (context == null) throw new ArgumentNullException("context"); if (context.Package == null) throw new ArgumentException("context.Package cannot be null", "context"); if (processed.Contains(context.Package)) { return; } processed.Add(context.Package); var package = context.Package; var session = package.Session; // 1. first recursively process all store packages foreach (var packageDependency in package.Meta.Dependencies) { var subPackage = session.Packages.Find(packageDependency); if (subPackage != null) { // Work on an immutable copy for the whole set of assets to compile var contextCopy = (AssetCompilerContext)context.Clone(); contextCopy.Package = subPackage; RecursiveCompile(result, contextCopy, processed); } else { result.Error("Unable to find package [{0}]", packageDependency); } } // 2. recursively process all local packages foreach (var subPackageReference in package.LocalDependencies) { var subPackage = session.Packages.Find(subPackageReference.Id); if (subPackage != null) { // Work on an immutable copy for the whole set of assets to compile var contextCopy = (AssetCompilerContext)context.Clone(); contextCopy.Package = subPackage; RecursiveCompile(result, contextCopy, processed); } else { result.Error("Unable to find package [{0}]", subPackageReference); } } result.Info("Compiling package [{0}]", package.FullPath); // Compile using all PackageCompiler foreach (var compiler in compilers) { var compilerResult = compiler.Compile(context); compilerResult.CopyTo(result); while (compilerResult.BuildSteps.Count > 0) { var step = compilerResult.BuildSteps[0]; compilerResult.BuildSteps.RemoveAt(0); result.BuildSteps.Add(step); } } }
/// <summary> /// Compiles the asset from the specified package. /// </summary> /// <param name="context"></param> /// <param name="urlInStorage">The absolute URL to the asset, relative to the storage.</param> /// <param name="assetAbsolutePath">Absolute path of the asset on the disk</param> /// <param name="asset">The asset.</param> /// <param name="result">The result where the commands and logs should be output.</param> protected abstract void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, T asset, AssetCompilerResult result);
/// <summary> /// Compile the required build step necessary to produce the desired output item. /// </summary> /// <param name="context">The context.</param> /// <param name="compilationResult">The compilation result.</param> /// <param name="assetItem">The asset item.</param> protected ListBuildStep CompileItem(CompilerContext context, AssetCompilerResult compilationResult, AssetItem assetItem) { // First try to find an asset compiler for this particular asset. IAssetCompiler compiler; try { compiler = compilerRegistry.GetCompiler(assetItem.Asset.GetType()); } catch (Exception ex) { compilationResult.Error($"Cannot find a compiler for asset [{assetItem.Id}] from path [{assetItem.Location}]", ex); return(null); } if (compiler == null) { return(null); } // Second we are compiling the asset (generating a build step) try { var resultPerAssetType = compiler.Compile(context, assetItem); // Raise the AssetCompiled event. AssetCompiled?.Invoke(this, new AssetCompiledArgs(assetItem, resultPerAssetType)); // TODO: See if this can be unified with PackageBuilder.BuildStepProcessed var assetFullPath = assetItem.FullPath.ToWindowsPath(); foreach (var message in resultPerAssetType.Messages) { var assetMessage = AssetLogMessage.From(null, assetItem.ToReference(), message, assetFullPath); // Forward log messages to compilationResult compilationResult.Log(assetMessage); // Forward log messages to build step logger resultPerAssetType.BuildSteps.Logger.Log(assetMessage); } // Make the build step fail if there was an error during compiling (only when we are compiling the build steps of an asset) if (resultPerAssetType.BuildSteps is AssetBuildStep && resultPerAssetType.BuildSteps.Logger.HasErrors) { resultPerAssetType.BuildSteps.Add(new CommandBuildStep(new FailedCommand(assetItem.Location))); } // TODO: Big review of the log infrastructure of CompilerApp & BuildEngine! // Assign module string to all command build steps SetAssetLogger(resultPerAssetType.BuildSteps, assetItem.Package, assetItem.ToReference(), assetItem.FullPath.ToWindowsPath()); // Add a wait command to the build steps if required by the item build if (resultPerAssetType.ShouldWaitForPreviousBuilds) { compilationResult.BuildSteps.Add(new WaitBuildStep()); } foreach (var buildStep in resultPerAssetType.BuildSteps) { buildStep.Priority = latestPriority++; } // Add the item result build steps the item list result build steps return(resultPerAssetType.BuildSteps); } catch (Exception ex) { compilationResult.Error($"Unexpected exception while compiling asset [{assetItem.Id}] from path [{assetItem.Location}]", ex); return(null); } }
public CompileDefaultSceneEffectCommand(AssetCompilerContext context, Package package, AssetCompilerResult compilerResult) { this.context = context; this.package = package; this.compilerResult = compilerResult; }
protected sealed override AssetCompilerResult CompileOverride(AssetCompilerContext context, AssetCompilerResult compilerResult) { var thumbnailCompilerContext = (ThumbnailCompilerContext)context; // Build the path of the thumbnail in the storage var assetStorageUrl = AssetItem.Location.GetDirectoryAndFileName(); var thumbnailStorageUrl = assetStorageUrl.Insert(0, "__THUMBNAIL__"); // Check if this asset produced any error // (dependent assets errors are generally ignored as long as thumbnail could be generated, // but we will add a thumbnail overlay to indicate the state is not good) var currentAssetHasErrors = false; try { // TODO: fix failures here (see TODOs in Compile and base.Compile) AssetsSession = AssetItem.Package.Session; // Only use the path to the asset without its extension Compile(thumbnailCompilerContext, thumbnailStorageUrl, AssetItem.FullPath, compilerResult); } catch (Exception) { // If an exception occurs, ensure that the build of thumbnail will fail. compilerResult.Error(string.Format("An exception occurred while compiling the asset [{0}]", AssetItem.Location)); } foreach (var logMessage in compilerResult.Messages) { // Ignore anything less than error if (!logMessage.IsAtLeast(LogMessageType.Error)) { continue; } // Check if there is any non-asset log message // (they are probably just emitted by current compiler, so they concern current asset) // TODO: Maybe we should wrap every message in AssetLogMessage before copying them in compilerResult? var assetLogMessage = logMessage as AssetLogMessage; if (assetLogMessage == null) { currentAssetHasErrors = true; break; } // If it was an asset log message, check it concerns current asset if (assetLogMessage.AssetReference != null && assetLogMessage.AssetReference.Location == AssetItem.Location) { currentAssetHasErrors = true; break; } } if (currentAssetHasErrors) { // if a problem occurs while compiling, we add a special build step that will always fail. compilerResult.BuildSteps.Add(new ThumbnailFailureBuildStep(compilerResult.Messages)); } var currentAsset = AssetItem; // copy the current asset item and embrace it in the callback compilerResult.BuildSteps.StepProcessed += (_, buildStepArgs) => OnThumbnailStepProcessed(thumbnailCompilerContext, currentAsset, thumbnailStorageUrl, buildStepArgs); return(compilerResult); }
/// <summary> /// Compile the required build step necessary to produce the desired output item. /// </summary> /// <param name="context">The context.</param> /// <param name="compilationResult">The compilation result.</param> /// <param name="assetItem">The asset item.</param> protected ListBuildStep CompileItem(CompilerContext context, AssetCompilerResult compilationResult, AssetItem assetItem) { // First try to find an asset compiler for this particular asset. IAssetCompiler compiler; try { compiler = compilerRegistry.GetCompiler(assetItem.Asset.GetType()); } catch (Exception ex) { compilationResult.Error("Cannot find a compiler for asset [{0}] from path [{1}]", ex, assetItem.Id, assetItem.Location); return null; } if (compiler == null) { return null; } // Second we are compiling the asset (generating a build step) try { var resultPerAssetType = compiler.Compile(context, assetItem); // Raise the AssetCompiled event. AssetCompiled?.Invoke(this, new AssetCompiledArgs(assetItem, resultPerAssetType)); // TODO: See if this can be unified with PackageBuilder.BuildStepProcessed var assetFullPath = assetItem.FullPath.ToWindowsPath(); foreach (var message in resultPerAssetType.Messages) { var assetMessage = AssetLogMessage.From(null, assetItem.ToReference(), message, assetFullPath); // Forward log messages to compilationResult compilationResult.Log(assetMessage); // Forward log messages to build step logger resultPerAssetType.BuildSteps.Logger.Log(assetMessage); } // Make the build step fail if there was an error during compiling (only when we are compiling the build steps of an asset) if (resultPerAssetType.BuildSteps is AssetBuildStep && resultPerAssetType.BuildSteps.Logger.HasErrors) resultPerAssetType.BuildSteps.Add(new CommandBuildStep(new FailedCommand(assetItem.Location))); // TODO: Big review of the log infrastructure of CompilerApp & BuildEngine! // Assign module string to all command build steps SetAssetLogger(resultPerAssetType.BuildSteps, assetItem.Package, assetItem.ToReference(), assetItem.FullPath.ToWindowsPath()); // Add a wait command to the build steps if required by the item build if (resultPerAssetType.ShouldWaitForPreviousBuilds) compilationResult.BuildSteps.Add(new WaitBuildStep()); foreach (var buildStep in resultPerAssetType.BuildSteps) { buildStep.Priority = latestPriority++; } // Add the item result build steps the item list result build steps return resultPerAssetType.BuildSteps; } catch (Exception ex) { compilationResult.Error("Unexpected exception while compiling asset [{0}] from path [{1}]", ex, assetItem.Id, assetItem.Location); return null; } }
/// <summary> /// Compile the required build step necessary to produce the desired output item. /// </summary> /// <param name="context">The context.</param> /// <param name="compilationResult">The compilation result.</param> /// <param name="assetItem">The asset item.</param> protected BuildStep CompileItem(CompilerContext context, AssetCompilerResult compilationResult, AssetItem assetItem) { // First try to find an asset compiler for this particular asset. IAssetCompiler compiler; try { compiler = compilerRegistry.GetCompiler(assetItem.Asset.GetType()); } catch (Exception ex) { compilationResult.Error("Cannot find a compiler for asset [{0}] from path [{1}]", ex, assetItem.Id, assetItem.Location); return(null); } if (compiler == null) { return(null); } // Second we are compiling the asset (generating a build step) try { var resultPerAssetType = compiler.Compile(context, assetItem); // Raise the AssetCompiled event. var handler = AssetCompiled; if (handler != null) { handler(this, new AssetCompiledArgs(assetItem, resultPerAssetType)); } resultPerAssetType.CopyTo(compilationResult); if (resultPerAssetType.BuildSteps == null) { return(null); } // Build the module string var assetAbsolutePath = assetItem.FullPath; assetAbsolutePath = Path.GetFullPath(assetAbsolutePath); var module = string.Format("{0}(1,1)", assetAbsolutePath); // Assign module string to all command build steps SetModule(resultPerAssetType.BuildSteps, module); // Add a wait command to the build steps if required by the item build if (resultPerAssetType.ShouldWaitForPreviousBuilds) { compilationResult.BuildSteps.Add(new WaitBuildStep()); } foreach (var buildStep in resultPerAssetType.BuildSteps) { buildStep.Priority = latestPriority++; } // Add the item result build steps the item list result build steps return(resultPerAssetType.BuildSteps); } catch (Exception ex) { compilationResult.Error("Unexpected exception while compiling asset [{0}] from path [{1}]", ex, assetItem.Id, assetItem.Location); return(null); } }
public AssetCompilerResult Compile(AssetCompilerContext context) { var result = new AssetCompilerResult(); var package = context.Package; // Sort the items to build by build order var assets = package.Assets.ToList(); assets.Sort((item1, item2) => item1.Asset != null && item2.Asset != null ? item1.Asset.InternalBuildOrder.CompareTo(item2.Asset.InternalBuildOrder) : 0); // generate the build steps required to build the assets via base class Compile(context, assets, result); return result; }
public AssetCompilerResult Compile(AssetCompilerContext context) { var result = new AssetCompilerResult(); // generate the build steps required to build the assets via base class Compile(context, assets, result); return result; }
protected abstract AssetCompilerResult CompileOverride(AssetCompilerContext context, AssetCompilerResult compilationResult);
/// <inheritdoc/> public AssetCompilerResult Compile(CompilerContext context, AssetItem assetItem) { if (context == null) { throw new ArgumentNullException("context"); } if (assetItem == null) { throw new ArgumentNullException("assetItem"); } var compilerResult = new AssetCompilerResult(); if (assetItem.Package == null) { compilerResult.Warning("Asset [{0}] is not attached to a package", assetItem); return(compilerResult); } var assetCompilerContext = (AssetCompilerContext)context; // create the a package that contains only the asset and its the dependencies var dependenciesCompilePackage = assetItem.Package.Session.CreateCompilePackageFromAsset(assetItem); var clonedAsset = dependenciesCompilePackage.FindAsset(assetItem.Id); CompileWithDependencies(assetCompilerContext, clonedAsset, assetItem, compilerResult); // Check unloadable items foreach (var currentAssetItem in dependenciesCompilePackage.Assets) { var unloadableItems = UnloadableObjectRemover.Run(currentAssetItem.Asset); foreach (var unloadableItem in unloadableItems) { compilerResult.Log(new AssetLogMessage(dependenciesCompilePackage, currentAssetItem.ToReference(), LogMessageType.Warning, $"Unable to load the object of type {unloadableItem.UnloadableObject.TypeName} which is located at [{unloadableItem.MemberPath}] in the asset")); } } // Find AssetBuildStep var assetBuildSteps = new Dictionary <AssetId, AssetBuildStep>(); foreach (var step in compilerResult.BuildSteps.EnumerateRecursively()) { var assetStep = step as AssetBuildStep; if (assetStep != null) { assetBuildSteps[assetStep.AssetItem.Id] = assetStep; } } // TODO: Refactor logging of CompilerApp and BuildEngine // Copy log top-level to proper asset build steps foreach (var message in compilerResult.Messages) { var assetMessage = message as AssetLogMessage; // Find asset (if nothing found, default to main asset) var assetId = assetMessage?.AssetReference.Id ?? assetItem.Id; AssetBuildStep assetBuildStep; if (assetBuildSteps.TryGetValue(assetId, out assetBuildStep)) { // Log to AssetBuildStep assetBuildStep.Logger?.Log(message); } } return(compilerResult); }
/// <summary> /// Generate the build step corresponding to raw imports of the current package file. /// </summary> /// <param name="context">The compilation context</param> /// <param name="result">The compilation current result</param> private void GenerateRawImportBuildSteps(AssetCompilerContext context, AssetCompilerResult result) { if (context.Package.RootDirectory == null) return; foreach (var profile in context.Package.Profiles) { foreach (var sourceFolder in profile.AssetFolders) { var baseDirectory = Path.GetFullPath(context.Package.RootDirectory); // Use sub directory baseDirectory = Path.Combine(baseDirectory, sourceFolder.Path); if (!Directory.Exists(baseDirectory)) { continue; } var baseUDirectory = new UDirectory(baseDirectory); var hashSet = new HashSet<string>(); // Imports explicit foreach (var rawImport in sourceFolder.RawImports) { var sourceDirectory = baseUDirectory; if (!string.IsNullOrEmpty(rawImport.SourceDirectory)) sourceDirectory = UPath.Combine(sourceDirectory, rawImport.SourceDirectory); if (!Directory.Exists(sourceDirectory)) { result.Error("Unable to find raw import directory [{0}]", sourceDirectory); continue; } var files = Directory.EnumerateFiles(sourceDirectory, "*.*", SearchOption.AllDirectories).ToList(); var importRegexes = rawImport.Patterns.Select(x => new Regex(Selectors.PathSelector.TransformToRegex(x))).ToArray(); foreach (var file in files) { var pathToFileRelativeToProject = new UFile(file).MakeRelative(sourceDirectory); var outputPath = pathToFileRelativeToProject; if (!string.IsNullOrEmpty(rawImport.TargetLocation)) outputPath = UPath.Combine(rawImport.TargetLocation, outputPath); foreach (var importRegex in importRegexes) { if (importRegex.Match(pathToFileRelativeToProject).Success && hashSet.Add(outputPath)) { result.BuildSteps.Add(new ImportStreamCommand { SourcePath = file, Location = outputPath, }); break; } } } } } } }
/// <summary> /// Add to the current compilation result the compilation steps required to compile the <see cref="AssetItem"/> dependencies. /// </summary> /// <param name="context">A compiler context.</param> /// <param name="result">The current result of the compilation</param> protected void AddDependenciesBuildStepsToResult(AssetCompilerContext context, AssetCompilerResult result) { // create the fake package used to compile the dependences var dependenciesCompilePackage = AssetsSession.CreateCompilePackageFromAsset(AssetItem); // compile the fake package (create the build steps) var assetPackageCompiler = new PackageCompiler(); context.Package = dependenciesCompilePackage.LocalPackages.FirstOrDefault(); var dependenciesCompileResult = assetPackageCompiler.Compile(context); // Create the result build steps if not existing yet if (result.BuildSteps == null) { result.BuildSteps = new ListBuildStep(); } // Add the dependencies build steps to the current result result.BuildSteps.Add(dependenciesCompileResult.BuildSteps); // Copy log the dependencies result to the current result dependenciesCompileResult.CopyTo(result); }
/// <summary> /// Compile the required build step necessary to produce the desired output item. /// </summary> /// <param name="context">The context.</param> /// <param name="compilationResult">The compilation result.</param> /// <param name="assetItem">The asset item.</param> protected ListBuildStep CompileItem(CompilerContext context, AssetCompilerResult compilationResult, AssetItem assetItem) { // First try to find an asset compiler for this particular asset. IAssetCompiler compiler; try { compiler = compilerRegistry.GetCompiler(assetItem.Asset.GetType()); } catch (Exception ex) { compilationResult.Error("Cannot find a compiler for asset [{0}] from path [{1}]", ex, assetItem.Id, assetItem.Location); return(null); } if (compiler == null) { return(null); } // Second we are compiling the asset (generating a build step) try { var resultPerAssetType = compiler.Compile(context, assetItem); // Raise the AssetCompiled event. var handler = AssetCompiled; if (handler != null) { handler(this, new AssetCompiledArgs(assetItem, resultPerAssetType)); } // TODO: See if this can be unified with PackageBuilder.BuildStepProcessed foreach (var message in resultPerAssetType.Messages) { var assetMessage = new AssetLogMessage(null, assetItem.ToReference(), message.Type, AssetMessageCode.CompilationMessage, assetItem.Location, message.Text) { Exception = message is LogMessage ? ((LogMessage)message).Exception : null }; // Forward log messages to compilationResult compilationResult.Log(assetMessage); // Forward log messages to build step logger resultPerAssetType.BuildSteps.Logger.Log(assetMessage); } // Make the build step fail if there was an error during compiling (only when we are compiling the build steps of an asset) if (resultPerAssetType.BuildSteps is AssetBuildStep && resultPerAssetType.BuildSteps.Logger.HasErrors) { resultPerAssetType.BuildSteps.Add(new CommandBuildStep(new FailedCommand(assetItem.Location))); } // Build the module string var assetAbsolutePath = assetItem.FullPath; assetAbsolutePath = Path.GetFullPath(assetAbsolutePath); var module = string.Format("{0}(1,1)", assetAbsolutePath); // Assign module string to all command build steps SetModule(resultPerAssetType.BuildSteps, module); // Add a wait command to the build steps if required by the item build if (resultPerAssetType.ShouldWaitForPreviousBuilds) { compilationResult.BuildSteps.Add(new WaitBuildStep()); } foreach (var buildStep in resultPerAssetType.BuildSteps) { buildStep.Priority = latestPriority++; } // Add the item result build steps the item list result build steps return(resultPerAssetType.BuildSteps); } catch (Exception ex) { compilationResult.Error("Unexpected exception while compiling asset [{0}] from path [{1}]", ex, assetItem.Id, assetItem.Location); return(null); } }
private void Prepare(AssetCompilerResult finalResult, AssetCompilerContext context, AssetItem assetItem, [NotNull] Type compilationContext, HashSet <BuildAssetNode> visitedItems, Dictionary <AssetId, BuildStep> compiledItems, BuildStep parentBuildStep = null, BuildDependencyType dependencyType = BuildDependencyType.Runtime) { if (compilationContext == null) { throw new ArgumentNullException(nameof(compilationContext)); } var assetNode = BuildDependencyManager.FindOrCreateNode(assetItem, compilationContext); compiledItems.TryGetValue(assetNode.AssetItem.Id, out var assetBuildSteps); // Prevent re-entrancy in the same node if (visitedItems.Add(assetNode)) { assetNode.Analyze(context); // Invoke the compiler to prepare the build step for this asset if the dependency needs to compile it (Runtime or CompileContent) if ((dependencyType & ~BuildDependencyType.CompileAsset) != 0 && assetBuildSteps == null) { var mainCompiler = BuildDependencyManager.AssetCompilerRegistry.GetCompiler(assetItem.Asset.GetType(), assetNode.CompilationContext); if (mainCompiler == null) { return; } var compilerResult = mainCompiler.Prepare(context, assetItem); if ((dependencyType & BuildDependencyType.Runtime) == BuildDependencyType.Runtime && compilerResult.HasErrors) //allow Runtime dependencies to fail { //totally skip this asset but do not propagate errors! return; } assetBuildSteps = compilerResult.BuildSteps; compiledItems.Add(assetNode.AssetItem.Id, assetBuildSteps); // Copy the log to the final result (note: this does not copy or forward the build steps) compilerResult.CopyTo(finalResult); if (compilerResult.HasErrors) { finalResult.Error($"Failed to prepare asset {assetItem.Location}"); return; } // Add the resulting build steps to the final finalResult.BuildSteps.Add(assetBuildSteps); AssetCompiled?.Invoke(this, new AssetCompiledArgs(assetItem, compilerResult)); } // Go through the dependencies of the node and prepare them as well foreach (var reference in assetNode.References) { var target = reference.Target; Prepare(finalResult, context, target.AssetItem, target.CompilationContext, visitedItems, compiledItems, assetBuildSteps, reference.DependencyType); if (finalResult.HasErrors) { return; } } // If we didn't prepare any build step for this asset let's exit here. if (assetBuildSteps == null) { return; } } // Link the created build steps to their parent step. if (parentBuildStep != null && assetBuildSteps != null && (dependencyType & BuildDependencyType.CompileContent) == BuildDependencyType.CompileContent) //only if content is required Content.Load { BuildStep.LinkBuildSteps(assetBuildSteps, parentBuildStep); } }
/// <summary> /// Generate the build step corresponding to raw imports of the current package file. /// </summary> /// <param name="context">The compilation context</param> /// <param name="result">The compilation current result</param> private void GenerateRawImportBuildSteps(AssetCompilerContext context, AssetCompilerResult result) { if (context.Package.RootDirectory == null) { return; } foreach (var profile in context.Package.Profiles) { foreach (var sourceFolder in profile.AssetFolders) { var baseDirectory = Path.GetFullPath(context.Package.RootDirectory); // Use sub directory baseDirectory = Path.Combine(baseDirectory, sourceFolder.Path); if (!Directory.Exists(baseDirectory)) { continue; } var baseUDirectory = new UDirectory(baseDirectory); var hashSet = new HashSet <string>(); // Imports explicit foreach (var rawImport in sourceFolder.RawImports) { var sourceDirectory = baseUDirectory; if (!string.IsNullOrEmpty(rawImport.SourceDirectory)) { sourceDirectory = UPath.Combine(sourceDirectory, rawImport.SourceDirectory); } if (!Directory.Exists(sourceDirectory)) { result.Error("Unable to find raw import directory [{0}]", sourceDirectory); continue; } var files = Directory.EnumerateFiles(sourceDirectory, "*.*", SearchOption.AllDirectories).ToList(); var importRegexes = rawImport.Patterns.Select(x => new Regex(Selectors.PathSelector.TransformToRegex(x))).ToArray(); foreach (var file in files) { var pathToFileRelativeToProject = new UFile(file).MakeRelative(sourceDirectory); var outputPath = pathToFileRelativeToProject; if (!string.IsNullOrEmpty(rawImport.TargetLocation)) { outputPath = UPath.Combine(rawImport.TargetLocation, outputPath); } foreach (var importRegex in importRegexes) { if (importRegex.Match(pathToFileRelativeToProject).Success&& hashSet.Add(outputPath)) { result.BuildSteps.Add(new ImportStreamCommand { SourcePath = file, Location = outputPath, }); break; } } } } } } }
/// <summary> /// Compiles the given asset with its dependencies. /// </summary> /// <param name="context">The asset compiler context.</param> /// <param name="assetItem">The asset to compile with its dependencies.</param> /// <param name="originalItem"></param> /// <param name="compilationResult">The result of the compilation.</param> protected virtual void CompileWithDependencies(AssetCompilerContext context, AssetItem assetItem, AssetItem originalItem, AssetCompilerResult compilationResult) { CompilePackage(context, compilationResult); }
/// <summary> /// Compile the current package and all child package recursively by generating a list of build steps /// </summary> private void RecursiveCompile(AssetCompilerResult result, AssetCompilerContext context, HashSet <Package> processed) { if (result == null) { throw new ArgumentNullException("result"); } if (context == null) { throw new ArgumentNullException("context"); } if (context.Package == null) { throw new ArgumentException("context.Package cannot be null", "context"); } if (processed.Contains(context.Package)) { return; } processed.Add(context.Package); var package = context.Package; GenerateRawImportBuildSteps(context, result); // 1. first recursively process all store packages foreach (var packageDependency in package.Meta.Dependencies) { var subPackage = session.Packages.Find(packageDependency); if (subPackage != null) { // Work on an immutable copy for the whole set of assets to compile var contextCopy = (AssetCompilerContext)context.Clone(); contextCopy.Package = subPackage; RecursiveCompile(result, contextCopy, processed); } else { result.Error("Unable to find package [{0}]", packageDependency); } } // 2. recursively process all local packages foreach (var subPackageReference in package.LocalDependencies) { var subPackage = session.Packages.Find(subPackageReference.Id); if (subPackage != null) { // Work on an immutable copy for the whole set of assets to compile var contextCopy = (AssetCompilerContext)context.Clone(); contextCopy.Package = subPackage; RecursiveCompile(result, contextCopy, processed); } else { result.Error("Unable to find package [{0}]", subPackageReference); } } result.Info("Compiling package [{0}]", package.FullPath); // Sort the items to build by build order var assets = package.Assets.ToList(); assets.Sort((item1, item2) => item1.Asset != null && item2.Asset != null ? item1.Asset.BuildOrder.CompareTo(item2.Asset.BuildOrder) : 0); // generate the build steps required to build the assets via base class Compile(context, assets, result); }
/// <summary> /// Compiles the asset from the specified package. /// </summary> /// <param name="context">The thumbnail compile context</param> /// <param name="thumbnailStorageUrl">The absolute URL to the asset's thumbnail, relative to the storage.</param> /// <param name="assetAbsolutePath">Absolute path of the asset on the disk</param> /// <param name="result">The result where the commands and logs should be output.</param> protected abstract void Compile(ThumbnailCompilerContext context, string thumbnailStorageUrl, UFile assetAbsolutePath, AssetCompilerResult result);
/// <summary> /// Compiles the package contained in the given context and add the resulting build steps in the <see cref="AssetCompilerResult"/> /// </summary> /// <param name="context">The context which contains the package to compile.</param> /// <param name="result">The <see cref="AssetCompilerResult"/> where the build steps will be added.</param> /// <returns></returns> protected static BuildStep CompilePackage(AssetCompilerContext context, Package package, AssetCompilerResult result) { // compile the fake package (create the build steps) var assetPackageCompiler = new PackageCompiler(new PackageAssetEnumerator(package)); var dependenciesCompileResult = assetPackageCompiler.Compile(context); // Create the result build steps if not existing yet if (result.BuildSteps == null) { result.BuildSteps = new ListBuildStep(); } // Add the dependencies build steps to the current result result.BuildSteps.Add(dependenciesCompileResult.BuildSteps); // Copy log the dependencies result to the current result dependenciesCompileResult.CopyTo(result); return(dependenciesCompileResult.BuildSteps); }
/// <summary> /// Compile the required build steps necessary to produce the desired outputs items. /// </summary> /// <param name="context">The context source.</param> /// <param name="assetItems">The list of items to compile</param> /// <param name="compilationResult">The current compilation result, containing the build steps and the logging</param> protected void Prepare(AssetCompilerContext context, IEnumerable <AssetItem> assetItems, AssetCompilerResult compilationResult) { foreach (var assetItem in assetItems) { var itemBuildStep = CompileItem(context, compilationResult, assetItem); if (itemBuildStep != null) { compilationResult.BuildSteps.Add(itemBuildStep); } } }